Contents — 7 sections

RicochetTanksのNPCには、普通の直線射撃をさせたくなかった。

ゲームの核が一回反射だから、NPCも壁を使って撃つ必要がある。

そこでNPCは、

どの壁へ当てれば一回反射で相手へ届くか

を探す。

問題は、候補の壁面が106面あったこと。

全部を1frameで調べる設計にはしなかった。

1frame最大16面

探索は分割した。

1frameに最大16面。

全106面なら、

約7frame

で一周する。

重い処理を一度に押し込まず、複数frameへ散らす。

VRChat / Udon上で使う前提なので、1frameへ集めすぎないことを優先した。

探しているのは一回反射の経路

NPCが見るのは、

  1. 自分から壁面へ届く
  2. その面で反射する
  3. 反射後に相手へ届く
  4. 途中で別の壁へ当たらない
  5. 自分へ返ってこない

という経路。

保存Sceneの検査では、

  • 160組で返した撃ち筋がすべて一回反射で命中
  • 自滅0
  • 道順3192本が壁へ衝突しない
  • 無作為60配置で自分へ返る撃ち筋を返さない

ことをEditor検査で確認した。

ただしこれは自動検査。

実VRChat上の処理時間を測った結果ではない。

難易度は「賢さ」より人間っぽい誤差で作った

NPCは3段階。

EASY

  • 反応: 1.2秒
  • 角度ずれ: ±5°
  • 発射間隔: 4秒
  • 射程: 22m

NORMAL

  • 反応: 0.7秒
  • 角度ずれ: ±2.5°
  • 発射間隔: 2.5秒
  • 射程: 30m

HARD

  • 反応: 0.35秒
  • 角度ずれ: ±0.8°
  • 発射間隔: 1.5秒
  • 射程: 45m

難易度を変えるために別の戦術AIを作ったわけではない。

同じ射線探索を使いながら、

反応・精度・頻度

を変えた。

完璧に撃つNPCは練習相手にならない

一回反射の正解が見つかったら毎回正確に撃つ。

それだとHardというより、ただのSolverになる。

だから角度誤差を入れた。

EASYでは±5°。

HARDでも±0.8°。

完全な数学解を、そのままPlayerへぶつけない。

練習モードは本番M1と分けた

このNPCモードはローカル練習用。

M0 / M1の評価結果には数えない。

理由は、

NPCと戦えても、人間対戦が面白い証拠にはならないから。

「敵がいないと操作感が分からない」という問題を解くための練習相手。

それ以上の意味は持たせない。

実VRChat性能は未計測

106面を約7frameに分けた。

設計としては負荷分散している。

でも、

実VRChatで何msかかったかはまだ測っていない。

Editor検査で正しい経路を返すことは見た。

人間が遊んで、この強さが適切かも未確認。

だから「高速なAIが完成した」という記事ではない。

いまの結論

NPCに跳弾をさせるとき、最初に必要だったのは高度なAIではなかった。

候補面を分割して、正しい反射経路を探す仕組み。

その上へ、

  • 反応時間
  • 精度
  • 発射間隔

という人間っぽい制限を載せた。

PicoTowaでは、こういう「賢く見える前の地味な計算部分」も残していく。

Signal / 観測記録

この記録への観測を送る

反証、再現失敗、追加で試してほしいこと。届いた SIGNAL は非公開で保存し、次の実験候補として扱います。