原作者:@therealbytes @_yonada
翻訳:@hiCaptainZ
元文書のリンク:https://world.mirror.xyz/fL3IMnsOPMqQ_Td1pPEd_kYYNdWu0NW7aBDb_CwfarA
仮想世界の創造者として、私たちの目標は、ユーザーが楽しく深く関与できる環境を作り出すことです。これには、複雑で予期しない振る舞いが現れるデジタル物理学を設計し、既存のインフラストラクチャがこれらの振る舞いをサポートできるようにするバランスを見つける必要があります。そのためには、デジタル物理学の 3 つの主要な次元、時間、その法則の形式、およびそれらの法則が適用される範囲を考慮する必要があります。
時間#
私たちは仮想世界内の時間の経過を、世界の法則が自身に対して適用されることとしています。各離散的な適用は、この世界の時間の流れの中の「瞬間」です。時間の設計方法の一つは、外部の時間と連続して進行するようにすることです。ブロックチェーンベースの仮想世界では、各ブロックは過去の一定数の瞬間に対応し、そのブロックに含まれるトランザクションに関係なくです。これは同期時間または「チック」現象と呼ばれます。このアプローチにより、ユーザーは自分の行動の結果をリアルタイムで見ることができるため、世界はユーザーにとってより興味深くなります。さらに、これにより世界内の時間がより長くなり、世界が継続的に更新されるため、興味深い行動が生まれやすくなります。
しかし、このアプローチには欠点もあります。より大きな時間範囲は通常、より多くの計算リソースを必要とし、すぐにチェーンまたはサーバーの能力を超える可能性があります。このシステムを通常のブロックチェーン上で実装することも困難かもしれません。なぜなら、チェーン上の変化はすべて、外部のユーザーによって開始されるトランザクションによってのみ起こる必要があるからです。
この困難さは、いくつかの簡単な例を想像すると明らかになります。例えば、チェーン上のゲームには非プレイヤーキャラクター(NPC)が存在するとします。メインネットの Ethereum では、更新機能を定義し、ゲームマップ上の各 NPC の位置を設定し、外部のアカウントが定期的にそれを呼び出して位置を更新することができます。しかし、これは信頼性が低いかもしれません。なぜなら、外部のアカウントがガス料金の競売で競り落とされる可能性があるため、アップデートを呼び出すべきブロックで外部のアカウントが呼び出されないことが保証できないからです。このような手動のチックの方法により、ゲーム内の時間構造がドリフトする可能性があります(元の CryptoKitties の giveBirth () 機能を例に挙げると、ガス料金の増加に伴い、Axiom Zen は実際に giveBirth 機能の呼び出しを増やすために報酬を増やさなければならなかった。これにより、ユーザーが Kitty を繁殖させた後の 256 ブロックで新しい NFT の出生トランザクションが呼び出されることが保証されました)。この外部アカウントを使用する方法を「手動チック」と呼びます。
カスタムロールアップを使用すると、外部アカウントを使用せずにチック機能をチェーン上に追加し、同期時間の進行をプロトコルが保証します。この方法を「自動チック」と呼びます。自動チックは、「チックコントラクト」と呼ばれるコントラクトを書くことで実現できます。このコントラクトはプロトコル自体によって呼び出されるため、外部アカウントによって呼び出されるのではありません。
例えば、@therealbytes は OP Stack ベースのコンセプト検証チックチェーンを開発しました。このチェーンは自動チックの Conway's Game of Life の実装を実行しています(このビデオデモはこちらでご覧いただけます)。Bytes は、変更されたシステムトランザクションを使用して、チックスタイルのセルオートマトンシミュレーションコントラクトを自動的に呼び出します。彼はチェーン自体の限界をテストするために、ゲームを 2 つの方法で実装しました。1 つはチェーン上で実行される Solidity スマートコントラクトとして、もう 1 つはチェーン自体のプリコンパイルとしてです。Solidity の実装では、ブロックごとに 2 回の更新が行われる 70x70 のグリッドで CPU が限界に達しました(1 ブロック / 秒、約 10k のセル / 秒)。一方、カスタムプリコンパイルエンジンを使用したチェーンは、同じ速度の 256x256 グリッドで CPU の約 6%(約 130k のセル / 秒)を使用して同じ速度に到達しました。
最後の段落の最後の文で、キーワードは「限界に達する」ということです。チックチェーンは、追加の複雑さのレイヤーを追加します:1 つのブロックが追加されるたびに、シミュレーションゲームのトランザクションはより多くの状態に触れる必要があります。最終的には、ロールアップノードは元の計算(CPU、ディスク IO など)に制約されます。ここでの唯一の解決策は、より高い容量のノードを使用することです。
「同期時間」の代替案は「非同期時間」です。このアプローチでは、世界内の時間の経過は外部の時間の進行に関係なく進む必要はありません。代わりに、時間は通常、特定のイベント(通常はユーザーの行動)が発生したときにのみ前進します。これは、タイマーを使用しない伝統的なボードゲームに似た範疇に属します。非同期時間をチェーン上で実現することは比較的容易ですが、それはチェーンがサポートするモデルであるためです。ただし、これにより、世界をより面白くする可能性のあるいくつかの機能(自動移動する NPC など)が犠牲になることもあります。
@notdavidhuang と cha0sg0d によるコンセプト検証ゲームの初期バージョンである WildWood は、この犠牲を明らかにしました。このゲームでは、2 人のプレイヤーが攻撃的な NPC の攻撃から彼らの拠点を守る必要があります。初期バージョンでは、NPC の移動はプレイヤー自身の移動時にのみトリガーされる非現実的な非同期時間の実装でした。チックを追加した後も、NPC は移動しましたが、別の問題が残りました。チェーンは 1 秒ごとにチックし、したがってプレイヤーが 1 秒に複数回移動する場合、ゲームはオプティミスティックロールアップの更新を使用してプレイヤーの位置をブロードキャストする必要があります。しかし、チームメイトは自動的にクライアントでそれを見ることはありませんので、プレイヤーの位置の更新には遅延が生じます。この問題を克服するために、チームは MUD のリレーサービスを利用しました。これは、ローカルクライアントをチェーン全体にブロードキャストするためのピアツーピアネットワークです。見てください、非同期時間から同期時間への変換が実現されました。
閉じた形式と開かれた形式の法則#
世界のビルダーは、仮想世界が開かれた形式の表現を従うのか、閉じた形式の表現を従うのかを決定する必要があります。閉じた形式の表現は、固定された数の操作を持っています。一方、開かれた形式(または再帰的な)の表現は、与えられた変数の成長に応じて操作の数が増えます。開かれた形式の表現では、既知の状態に世界の法則を反復的に適用することで、世界の未来の状態を計算することができます。複雑で生き生きとした環境、例えば「ドワーフフォートレス」は通常、このカテゴリに属します。一方、閉じた形式の表現では、過去の状態とそれらの間に経過した時間から、任意の未来の状態を計算することができます(未来のユーザーの行動が状態を変化させない場合を仮定します)、例えば「エイジオブエンパイア II」の資源採掘速度です。
開かれた形式は、仮想世界をより興味深くすることができます。なぜなら、現実世界と同様に、それらは予測不可能だからです。世界の将来の状態を予測するには、ますます多くの時間と計算リソースが必要になります(チェーン上で実装された Conway's Game of Life は良い例です:未来の任意の状態を計算することはできません、ゲームを時間に沿って実行する必要があります)。さらに、単純なマイクロな相互作用から予期しないマクロな振る舞いが生じることがあります。閉じた形式で管理される世界では、これらの発生する振る舞いは通常、外部で発生し、ユーザーの行動(彼ら自身が開かれた形式のように)を介してのみ発生しますが、世界の物理自体では発生しません。
開かれた形式と閉じた形式の間のトレードオフは、時間と同様のバランスを取ることに関連しています。閉じた形式は世界の潜在的な興味を減らすかもしれませんが、計算効率を向上させます。閉じた形式は同期または非同期時間と共に使用できます。ブロックチェーン上で実装する場合、同期時間では開かれた形式に対して明らかな利点があります。なぜなら、任意の時間のコストが一定であるため、世界はユーザーがトランザクションを送信するときにのみチェーン上の状態を更新するように設計されているからですが、それは前回の更新からの経過時間に設定されています。
時間と形態の範囲#
現在のチェーン上のダイナミックな標準的な方法である「遅延更新」を考えてみましょう。遅延更新では、プレイヤーはアクションの開始と終了を開始しますが、その間の時間は直接計算されるのではなく、シミュレートされます。たとえば、プレイヤーが最初のブロックでリンゴの木を植え、10 番目のブロックでリンゴを収穫するとします。遅延更新ロジックを書くことで、プレイヤーは 1 つの時間単位ごとにリンゴを収穫できるようにすることができます。合計 9 個のリンゴです。閉じた形式の関数(ブロックごとに 1 つのリンゴ)の更新ロジックに対しては、これは完全に可能ですが、農業ロジックがプレイヤーのアクション間の入力に基づいて変化する場合、この方法は機能しません。たとえば、第 5 ブロックで豪雨がリンゴの成長速度を増加させ、第 7 ブロックでバッタの災害が作物をほぼ破壊した場合、第 10 ブロックでプレイヤーがどれだけのリンゴを収穫できるかを効果的に計算することはできません(新しい状態に追いつくためには、すべての発生したイベントを実際に適用するための十分な計算能力が必要です)。それにもかかわらず、遅延更新は、特定の生物(成長速度が固定された植物など)の安価な計算に非常に便利ですが、ダイナミックな世界の完全なツールボックスにはまだ不十分です。
現実世界では、時間はどこにでもあり、一度きりの流れですが、仮想世界では必ずしもそうではありません。
まず、仮想世界は明らかに有限である可能性があります。興味深い可能性は通常、サイズの増加とともに増加します - 200 億の銀河から成る世界で起こることは、2 つの原子から成る世界よりも多いです - しかし、計算コストも増加します。これらの 2 つの関係は、前述の 2 つのトレードオフと密接に関連しています:時間の経過と物理的な形態です。
次に、時間は仮想世界のすべての場所で進む必要はありません。世界は時間の経過が異なる離散的な領域に分割されることができ、世界の計算負荷を減らすことができます。たとえば、ユーザーの活動がある地域では、より複雑で高価な物理的なルールを使用し、活動がない地域ではより単純な物理的なルールを使用することができます。このアプローチの欠点は 2 つあります:世界が一貫性を欠き、完全性がないように見えること、これにより世界のルールの設計空間が制限され、ユーザーが混乱することを避けるために世界ビルダーにプレッシャーをかけます。また、それは因果関係が世界内部で伝播することを制限します。ある領域の行動が遠くの領域に影響を与えない場合、それらの間の空間は時間に凍結されます。物理的なルールの適用領域のサイズは重要な設計上の考慮要素であり、世界が必要とするリソースとそれが達成できる興味深さのレベルに影響を与えます。
興味深く魅力的な仮想世界を作るためには、計算効率と興味深さを慎重にバランスさせる必要があります。これには、どのタイプの時間を使用するか(同期または非同期)を決定し、支配する物理法則の形態を評価することが含まれます。物理法則の適用領域のサイズも重要な決定です。これらの選択を慎重に行うことで、世界ビルダーは世界の計算負荷を管理しながら興味深さを維持するだけでなく、他の開発者に対しても非常に豊かなイノベーションの基盤を提供することができます。