ドキュメント ガイド
デバッグとパフォーマンス
ティックが遅い、コマンドが効かない、ゲームが動かない。現象から原因を絞り込み、付属の実機検証スクリプトで確認します。
レシートを見る
各コマンドのレシートが一次情報です。
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 ゲーム秒経たないと蘇生できません。