誰が何を持つのか
上から順に見ると、各部分の担当が分かります。接続方法が変わっても、ゲームの複製が別の場所に作られるわけではありません。
scene、UI部品、ゲーム内の値、入力状態そのものを持ちます。
ゲームの更新ごとに、公開を許可されたUI・ゲーム世界の情報だけを集めます。
現在の状態一覧と変更番号を保持し、操作要求をqueueへ入れ、ゲーム側の完了結果を対応付けます。
stdio MCP serverからWebSocketのgame bridgeへ接続します。
page toolから同じbrowser tab内のengine portへ接続します。
local bindingまたはgame bridgeを直接使い、2つのMCP接続部分は経由しません。
ゲームの更新ごとに「現在の状態一覧」を作る
engine adapterは、UIの公開処理が完了するごとに、同じ時点の情報でそろえたSemantic UI Treeを公開します。World Object Treeは、明示的に公開したゲーム世界のobjectを表す別の観測専用一覧で、公開処理も別です。Gua Runtimeは完成したsnapshotをそれぞれ一括で入れ替えますが、button、door、enemy、scoreそのものの所有者にはなりません。
| 情報 | 平易な意味 | 何が分かるか |
|---|---|---|
frameSequence | 1つのTreeについて、このsessionで何回のhost frameが完了したかを表す番号。 | そのTreeの意味情報が同じままでも、より新しい公開結果を観測したことが分かります。 |
revision | 1つのTreeについて、公開中の意味情報が何回変化したかを表す番号。 | UIの変化はUI側、Worldの変化は別のWorld側revisionを増やします。 |
sessionEpoch | resetで区切られた、現在のsessionを識別する番号。 | UIとWorldがこの値を共有するため、古いsessionや異なるsessionの情報を取り違えずに済みます。 |
操作の完了と、その後の画面変化は別
- 利用者が操作を送る
たとえば、意味情報でbuttonをclickする、game actionを押す、といった要求です。
- Gua Runtimeが要求をqueueへ入れる
要求には安定した
requestIdが付きます。queueへ受理された時点では、まだ成功ではありません。 - engine adapterが要求を取り出す
現在の対象、権限、状態を必要に応じて再確認し、engine上の操作を実行します。
- ゲーム側が同じIDで完了を通知する
成功または失敗の結果に同じrequest IDを付けることで、その操作をゲーム側が処理したと分かります。
- 期待する状態になるまで別に待つ
clickでmenuが開くはずでも、操作完了だけではmenu表示まで証明できません。新しいsnapshotを読み、menuが表示されたことを確認します。
条件待機は新しい状態を確認し続ける
状態待機は、対応している条件が成立するか、時間切れになるまで新しいsnapshotを取得します。呼び出し元の取消を伝播するtransportでは、それより早く終了できます。wait_for_nodeが待つのは指定IDの存在、wait_for_world_objectが待つのはWorld selectorへの一致です。Worldの近傍selectorでは、pollのたびに1つの新しい投影済みsnapshot内で基準と候補を解決し直し、過去frameの位置やmatchを現在のobjectと組み合わせません。テストclientはWaitForStateAsyncなどで、より詳しい条件を新しいsnapshotへ適用できます。PCの速さではなく、期待する条件そのものを成功基準にできます。
成功したWorld queryは、そのWorld snapshotのsessionEpoch、frameSequence、revisionを返します。検証結果を記録するときはmatchと一緒に保持すると、どの投影済みsnapshotを評価した結果かを識別できます。
「Loading nodeが出現するまで待つ」。対応する条件が成立した時点ですぐ終わります。表示状態も必要なら、IDの存在だけで表示中と決めず、新しいsnapshot上の状態を確認します。
「2秒待つ」。clientのsleepやRecordingのdelayは時間を進めるだけで、期待する状態の成立は証明しません。
経過時間そのものを試す場合だけ固定時間を使います。通常の同期では、適切なtimeoutを付けた状態待機を優先します。
保持中のゲーム入力は接続ごとに所有する
Wキーの押しっぱなしなど、状態を持つゲーム入力は、それを開始したWebSocket接続、local input session、Inspector接続、browser page bridgeごとに分けて管理します。leaseは保持できる時間の上限です。明示的な解除、lease切れ、切断、reset、session終了、tool登録解除、engine終了時には、その所有者の入力だけをneutralへ戻し、別の接続が保持している入力には影響させません。
MCPとWebMCPの共通部分・異なる部分
| 観点 | gui-mcp | gua-webmcp |
|---|---|---|
| 共通するGuaの動作 | hostが認可した意味情報のsnapshotと操作、request IDに対応するゲーム側完了、条件待機、所有者ごとの入力cleanup。 | |
| 観測・操作profile | native hostが固定したprofileを使います。既定はDebugです。Player向けhostではPlayerを明示設定し、policyも構成します。 | 常にhostのPlayer投影とPlayer action認可を使います。page toolからDebugを要求できません。 |
| 接続部分が動く場所 | 別processのstdio MCP server。 | exportされたゲームのbrowser page内。 |
| Runtimeまでの経路 | WebSocket game bridge。 | 同じtab内のengine-owned JavaScript port。 |
| 入力の所有者 | WebSocket接続ごとに1つ。 | 登録したpage bridgeごとに1つ。 |
Guaが保持しないもの
Guaは、AIとの会話、plan、思考過程、考え途中の状態を保持しません。保持するのは、公開snapshot、要求・完了の管理情報、接続が所有する入力状態など、範囲を限定したprotocol上の状態だけです。toolが待機している間にAIが別の処理を進められるかは、AI clientと実行環境の仕組みによって決まり、Guaの機能ではありません。