ドキュメント ガイド

デバッグとパフォーマンス

ティックが遅い、コマンドが効かない、ゲームが動かない。現象から原因を絞り込み、付属の実機検証スクリプトで確認します。

レシートを見る

各コマンドのレシートが一次情報です。

r = g.cast(hero, "blizzard", x=tx, y=ty)
if not r:
    print(r.reason, r.verdict)     # rejected(…)と理由コード
print(r.exec_us, r.engine_us)      # このコマンドがゲームスレッドで実行された時間(µs)/ そのうちエンジンの命令関数自体にかかった時間

通常、1 つのコマンドがゲームスレッドで使う時間は数マイクロ秒から数百マイクロ秒です。バッチブロックの終了後、g.last_receipts にそのバッチの各コマンドのレシートが入っています。

ゲーム内で見る

g.say(unit, "撤退")          # ユニットの頭上にチャット吹き出しを表示(ゲームには影響しない)
g.message("クリーピング開始")    # 左下のメッセージ欄に 1 行表示(ローカルでのみ見える)

print の内容は Bot を実行しているターミナルに表示されます。ティックごとの主要な判断を出力し、頭上の吹き出しと組み合わせると、コードを読むよりずっと早く状況を把握できます。

ティックが遅い

まず次のケースに当てはまらないか確認してください。

原因対処
コマンドを 1 件ずつ送り、毎回 1 フレーム待っているwith g.batch(): で包めば、数十件でも待つのは 1 回だけ
g.visible() / g.can_do() を 1 件ずつ呼んでいる(毎回ファストレーン経由で 1 フレーム待つ)可視性はスナップショットの u.visible_to() を使い、実行可否は g.can_do_many([...]) でまとめて問い合わせる
on_tick の中で sleep や待機をしているゲーム時間を記録し、次のティックで判定する
重い処理(経路探索、全マップ走査)を毎ティック再計算している結果をキャッシュし、数ティックおきに再計算する。g.grid() には 2 秒のキャッシュがあり、g.stats() のテクノロジーレベルは 5 秒ごとにキャッシュされる

ゲームが動かない / Bot がゲーム開始を待ち続ける

現象主な原因
ずっと「ゲーム開始待ち」のままインスタンス番号が違う。またはゲームウィンドウが最小化されている。最小化中はゲームのシミュレーションが止まっている(時計が進まない)
ゲームは動いているのに、Bot の命令に反応がない他人のユニットに命令している(レシートが not_owner)。または Bot が observer として接続している(forbidden)
コマンドが held になるこのユニットがより優先度の高い層(リファレンスブレインのリフレックス層、コンソールからの手動命令)に確保されていて、送信されなかった
一時停止中もコマンドを出せる正常です。一時停止中はエンジンの時計が止まりますが、イベントディスパッチは動き続け、コマンドも通常どおり実行されます

接続して状態を見る

python -m openwar3 status --inst 5

接続状態を出力します。ゲームの pid、ワールドの発行周期と 1 回の収集時間、ファストレーンのカウンター、ゲーム中かどうか、ユニット数、ゲーム時計。

実機検証スクリプト

テストインスタンスを 1 つ起動し、SDK の各機能があなたのマシンで正常に動くか 1 項目ずつ確認します。

python tools/sdk_live_check.py --inst 20                 # すべて
python tools/sdk_live_check.py --inst 20 --only prod     # 1 セクションだけ確認

セクション:バッチ、時間、生産、キュー付き命令、戦闘ステータス、経路探索、フェアモード。各セクションは実際の対戦でコマンドを出して効果を読み戻し、合格数を出力します。

オフラインテストはゲームを起動しなくても実行できます。

python tools/run_tests.py

「バグに見える」よくあるケース

  • 建設のレシートは受理されたのに、いつまでも建設が始まらない:森の中の地点でもエンジンはその場で受理し、ワーカーが到着してから失敗します。build_near を使えば、建設を追跡し、失敗した地点をしばらくブラックリストに入れてくれます。
  • スキルのレシートは受理されたのに、発動しない:中断されたか、マナ不足です。使用後の次のティックで g.cooldown() がクールダウンに入ったか確認してください。
  • 攻撃命令は受理されたのに、兵が別の相手を攻撃する:特定の目標を攻撃するには g.attack(兵, 敵)(右クリックのセマンティクス)を使います。生の攻撃オーダーは目標に対してオーダーを切り替えるだけで目標を記録しないため、近くの別の相手を攻撃しに行きます。
  • ワーカーの数が合わない:金鉱に入ったワーカーはスナップショットにいません。
  • 死んだヒーローを訓練できない:ヒーローは唯一なので g.revive(祭壇) が必要です。蘇生には人口が必要で、死亡後約 3 ゲーム秒経たないと蘇生できません。