プラットフォーム

ひとつのランタイム、ひとつのプロトコルで、 ゲームをプログラム可能な環境に

W3 Runtime はオリジナルのゲームに注入され、ゲームスレッド上でワールド全体を収集し、コマンドを実行し、結果を返します。あなたの AI は「何をするか」を伝えるだけ。バージョン付きの共有メモリプロトコルを通じてランタイムと対話します。

レイヤー構成

下の層は上の層の存在を知らない

インターフェース層には「攻めるべきか」のロジックは 1 行もありません。ブレイン同士は互いに import せず、SDK だけに依存します。これがアリーナを成立させる前提です。プラットフォームに必要なのは「インターフェース層 + レフェリー」だけで、誰のブレインでも差し込めます。

あなたの Agent / Bot
どんなモデルでも、どんな言語でも
Claude CodeCursorChatGPTQwen ローカルモデルPython Botリファレンス AI
意思決定
import openwar3 · または WebSocket / JSON ゲートウェイ · MCP
OpenWar3 SDK
Python · openwar3
Game / Botスナップショット w3worldファストレーン w3fastcombat 戦闘計算pathing 経路探索w3claim 調停canvas キャンバスjass チャネルschemes スキーム
インターフェース
50 ms ごとにワールドをプッシュ · コマンドは約 1 フレームで反映 · すべてにレシート
W3P プロトコル v2
共有メモリ · ゼロコピー · バージョン付き
War3WorldWar3EventsWar3MapWar3TreesWar3Fast コマンドレーンWar3Canvas キャンバス
プロトコル
ゲームスレッドでバッチ実行 · 1 件 4~8 µs · 1 回の処理予算 4 ms
W3 Runtime
ゲームスレッド上で動作
ワールドステート発行イベントストリームセマンティックコマンド実行クエリ権限と視点自前描画キャンバスJASS 呼び出しバージョン対応ヘルスチェックとサーキットブレーカー
ランタイム
War3.exe 1.27 · オリジナルのゲーム。ディスク上のファイルは一切変更しません
リアルタイム情報層

マップ全体を、50 ms ごとに

情報はランタイムがゲームスレッド上で一度に収集して共有メモリにプッシュし、クライアントはそれを直接読みます。ゲームスレッドにキューイングする必要はもうありません。1 回の収集は中央値 0.5 〜 0.9 ms(ユニット 100 〜 120 体)で、各段階の所要時間は常にワールドブロックのヘッダーに記録されています。

プレイヤー ×16

ゴールド、木材、人口と上限、累計採集量、種族

ユニット ×1024

種類、所有者、座標、HP・マナ、現在のオーダーと目標、実際に攻撃している相手、レベル・経験値・スキルポイント、各プレイヤーからの可視性

ユニット詳細 ×256

スキル 12 個(レベル、残りクールダウン)、バフ 8 個、インベントリ 6 枠。ヒーロー優先

生産表 ×128

訓練 / 研究 / 建設 / アップグレード:キュー、総時間、経過時間、詰まっているかどうか

地面のアイテム ×256

種類、位置、耐久度。拾われたり使われたりするとイベントを発行

樹木 ×4096

破壊可能オブジェクトの位置と HP。2 秒ごとに更新

マップ

1 マス 128 の通行可能 / 建設可能グリッド、プレイ可能領域、スタート地点。ゲーム開始後数秒で計算完了

時間

エンジンのゲーム時計、ゲーム内時刻(昼夜)、ゲーム速度、ゲーム中かどうか

イベントストリーム 8192 件のリングバッファ。各イベントに連番があり、読み取りが遅れて上書きされたときは SDK が検出できます
unit.appearedunit.diedunit.removedunit.damagedorder.changedowner.changedhero.levelupitem.appeareditem.removedspell.castselection.changedmessageplayer.leftgame.startedgame.ended damage · エンジンレベルの 1 回ごとkilled · エンジンレベルの 1 回ごと production.done · 相手のものも含む
セマンティックコマンド

どの経路を通るかはランタイムが決める

採集、撤退、スペル使用……同じ「ユニットに何かをさせる」でも、エンジン内での経路はそれぞれ異なります。そうした知見はすべてランタイムに組み込まれています。あなたは何をするかを伝えるだけで、ランタイムが検証済みのレシピで実行し、同じフレームで命令前後のオーダーを読み戻してレシートとして返します。

  • 1 回で 1 バッチを送信し、同じフレームで実行
  • すべてにレシート:ステータスコード + エンジンの理由コード + 実行時間
  • Shift キュー、ウェイポイント、連続建設
  • クエリ:テクノロジー数、実行可否、可視性、金鉱の残量、コンピューター対戦相手の攻撃目標
レシートと理由コード
moveattack_moveattackstopholdpatrolattack_groundgatherrepairbuildbuild_nearbuild_queuetraincancellearncastrallyrevivepick_upuse_itemdrop_itemgive_itemsell_itembuypathcall_to_armspausebatch
低レイテンシ

遅いのはプロセス間通信ではない

共有メモリの読み書きはナノ秒単位で、スナップショット 1 つの読み取りは約 0.05 ms です。旧チャネルが遅かったのは、リクエストごとにマシン全体で共有する 1 つのロックを奪い合い、さらにゲームが次にメッセージを取り出すのを待っていたからです(1 フレームに 1 回、16 〜 33 ms)。リファレンスブレインの実時間の 93% がこの待ちに費やされていました。

旧 · コントロールチャネル20 〜 40 ms / 回
  1. マシン全体で共有するミューテックスを奪い合う
  2. ゲームスレッドにメッセージを 1 つ投げる
  3. ゲームが次にメッセージを取り出すのを待つ(1 フレームに 1 回)
  4. 完了イベントを待ってロックを解放

6 プロセスで同時に使うと、スループットは約 88 回/秒で頭打ちになります。

新 · ファストレーン約 1 フレーム、バッチ処理
  1. 各クライアントが専用のレーンを持つ:書き手 1、読み手 1、ロックなし
  2. 実行ポイントはゲームスレッドのイベントディスパッチ内(毎秒数百回)。送信がないときのコストは整数比較数回だけ
  3. 1 回で 16 件を送信し、同じディスパッチ内ですべて実行。1 回の処理には 4 ms の時間予算
  4. 各コマンドに期限付き:一時停止から再開したあと、期限切れのコマンドは実行されない

各コマンドのレシートには実行時間が含まれ、レーンのヘッダーには最も遅かったコマンドと直近の処理時間が記録されます。どこが遅いのかが一目でわかります。

区分チャネルレイテンシ利用者ステータス
0 プッシュ型スナップショット + イベントストリーム 1 回の読み取り約 0.4 ms。50 ms ごとに更新(16 ms まで調整可能) すべての Bot 実機検証済み
1 ファストレーン 約 1 フレーム。6 プロセス並行で中央値 0.06 ms、スループット約 3000 回/秒 SDK のデフォルト 実機検証済み
2 コントロールチャネル 20 〜 40 ms フォールバック、一部の UI 系操作 実機検証済み
3 ゲートウェイ(WebSocket / JSON) 区分 1 + 約 1 ms あらゆる言語、ブラウザのページ、LLM(MCP)、別のマシン 実機検証済み

実測(1.27 テストインスタンス、2026-09-23 / 24)

コマンドスループット
以前 88
3,000 回/秒
6 プロセス並行
並行時の待ち時間の中央値
以前 67 ms
0.06 ms
旧コントロールチャネル → ファストレーン
16 件のコマンド
以前 121 ms
13 ms
1 件ずつ送信 → 1 バッチで送信
8 件の移動
以前 68~99 ms
6.5~10 ms
with g.batch()
ワールドステートの 1 回の収集
以前 11.8 ms
0.58 ms
ゲームスレッド上。読み取り可能と確認済みのメモリ領域を再利用
序盤の 1 コマンド
以前 4~10 ms
4~8 µs
サンプラーで同期ログを特定し、非同期化
リファレンスブレインの 1 ラウンド
以前 0.15~0.56 s
0.02~0.07 s
39 分の試合全体でタスクエラー 0
リファレンスブレインの最も遅い 1 ラウンド
以前 1.3~3.2 s
0.24~0.42 s
試合全体で 2 秒以上かかったラウンドはなし

エンジニアリングノート:序盤の 3 分間、各コマンドが 1000 倍遅かった

各コマンドに実行時間を付けてみたところ、序盤の数分間は同じバッチ内の 2 件目以降のコマンドが 1 件あたり 4 〜 10 ms かかり、ゲーム時間が約 180 秒に達すると突然数マイクロ秒まで下がることがわかりました。ランタイム組み込みのゲームスレッドサンプラーで 1700 サンプルを取ると、93% がランタイム自身のログ関数の中にありました。1 行書くたびにログファイルを同期的に開いて閉じており、しかも序盤はエンジンのオーダーごとに 1 行記録していたのです。デバッグログをデフォルトで無効にし、ログを非同期書き込みに変えたところ、開始 14 秒時点のコマンドも 4 〜 8 µs で済むようになりました。

私たちが信じるのは測った数値であって、推測ではありません。

権限と視点

すべてのレーンにロールがある

所有権チェックと視界フィルタリングはランタイムで行います。エンジンの実行層自体はユニットの所有権をチェックしないため、ここで補うしかありません。2 つの AI を対戦させるには、同じゲームで player レーンを 2 本開きます。

ロール見えるものできること
player 自軍のすべて + 視界内の敵と中立(フェアモード) 自軍のユニットだけを指揮できる
プレイヤー、あなたの Bot
observer マップ全体 命令は出せない。クエリ、カメラ操作、HUD の読み取りは可能
ディレクター、実況、振り返り
複数バージョン対応 · P4

推測しない、落ちない

1.24 〜 1.28 は同じエンジン構造なので、「1 つのランタイム + 複数の profile」が適しています。1.29 以降と Reforged は別のエンジンのため、自動互換は約束しません。

  1. 識別 Game.dll のバージョンリソースとファイルハッシュを読み、profile を選ぶ
  2. シンボル表 レシピは数値ではなくシンボル名を参照。各シンボルに呼び出し規約と引数の形が付く
  3. シグネチャによるフォールバック 未知のバージョンでは関数先頭のバイトパターンでスキャンし、一意に一致した場合のみ使用
  4. 起動時セルフチェック 各シンボルを副作用のない方法で検証し、通らなかった機能は使用不可としてマーク
  5. 機能一覧 SDK は使用不可の機能を読み取ると、呼び出し時にわかりやすいエラーを投げる。黙って 0 を返したりしない
高可用性

1 つの Bot のバグで、ゲーム全体を落としてはならない

これが、各 AI が独立したプロセスで動く理由でもあります。プロセス内では null ポインタ 1 つでゲーム全体がクラッシュしますが、独立したプロセスならクラッシュしてもその陣営が止まるだけです。

仕組み方法ステータス
ゲームを巻き込まない すべてのゲーム呼び出しを例外保護。1 回の処理に 4 ms の時間予算(高精度タイマー) 実装済み
クライアント同士が干渉しない クライアントごとに 1 本のレーンと個別の割り当て。1 つが固まっても他を妨げない 実装済み
期限切れは実行しない 各コマンドに期限を付け、期限切れはマークするだけで実行しない。一時停止から再開しても再生しない 実装済み
可観測性 各コマンドの実行時間。各収集の段階別所要時間はワールドブロックのヘッダーに記録 実装済み
切断時の再接続 SDK はゲームやプロセスの切り替えに追従して自動再接続 一部
機能のサーキットブレーカー ある機能が N 回連続で故障 → 使用不可としてマークしてイベントを発行、他の機能は通常どおり 計画
拡張層

ゲームの中で、自分だけのものをつくる

セマンティックコマンドは AI にプレイヤーと同じ操作をさせます。拡張層は、プレイヤーが見るもの・体験するものを変えます。クリックできる自分の UI を描き、マップ作者が使える関数をすべて呼び出せます。2 つの経路は「マルチプレイで安全かどうか」で分かれています。

キャンバス マルチプレイで安全
0.27 〜 0.34 ms 1 フレームあたりのコスト(要素 9 個、約 63 フレーム/秒)
  • テキストボックス、パネル、プログレスバー、画像、地形に沿った円、矢印付きのルート
  • ユニット、ワールド座標、画面位置に追従。CJK フォント、角丸、半透明、任意の色
  • ランタイムが自前で描画。ゲームオブジェクトを作らず、ゲームの状態も変えない
  • Python なら 1 行で 1 要素。HTTP 経由や、共有メモリへの直接書き込みも可能
  • ボタンや選択カードはクリックでき、ホバーでハイライト。マウスカーソルの下に描かれ、そのクリックはゲームには届かない
キャンバスのドキュメント
JASS チャネル シングルプレイ · ローカルツール
1291 個の JASS 関数を名前で直接呼び出し
  • ユニット生成、属性変更、エフェクト、パネル、ダイアログ、サウンド、カメラ、霧、天候……
  • Farsight コンソール、コマンドライン、HTTP、Python で、同じスクリプトの書き方
  • よく使う効果は 1 行で 1 つ:フローティングテキスト、ライン、範囲円、ポートレート会話、全画面フィルター
  • マルチプレイでは読み取り専用の関数だけを許可し、同期ずれを防ぐ
JASS チャネルのドキュメント
キャンバスJASS の描画関数
描くのは ランタイムが自前で描画 ゲーム自身
マルチプレイ 安全:自分の画面にだけ描く シングルプレイのみ
スタイル 自由:フォント、角丸、半透明、画像 ゲーム標準のスタイル
追従対象 ユニット / ワールド座標 / 画面位置 関数による
1 回のコスト 1 フレーム 0.2 〜 0.35 ms 1 回の呼び出し約 13 ms
1291 個の関数を用途別に
画面エフェクト 80 UI パネル 146 カメラ 44 サウンド・音楽 50 霧と視界 25 ユニット 161 アイテム 63 ヒーロー 32 プレイヤー / 同盟 / 資源 71 トリガー / タイマー 62 地形 / 天候 45 ゲーム進行 57

プレイヤーの操作は、そのままイベントストリームへ

ランタイムがプレイヤーの操作を直接報告します:描いたボタンのどれをクリックしたか、どのホットキーを押したか、地面のどこをクリックしたか、誰を選択したか、どのスキルを使ったか、チャット欄に何を打ったか。ゲーム自身のトリガーイベント(リージョンへの進入、ダイアログのボタン、矢印キー)は、空のトリガーでも受け取れます:イベントだけを登録し、条件もアクションも書かず、その実行回数を数えます。