Glenelg開発メモ/横殴り判定。
Glenelgの機能についてのメモ。
自分のための覚書でもあり、利用者のための豆知識でもあり、他AI開発者のための参考情報でもあり。
掲示板でも突っ込まれたところなので、現時点でのGlenelgの「横殴り判定」のアルゴリズムについてメモします。
Glenelgでは、自律動作による攻撃対象選定・攻撃においては、基本的に常時横殴り判定を行っています。
アクティブ索敵時はもちろん、とりあえずの目標を決めた後にそれに向かって移動している最中、および実際の戦闘中など、とにかくいつでも「横殴りしている」と判断した瞬間に攻撃を中止します。
で、その「横殴りになっている」というのは、以下のような内容を確認しています。
- その敵が誰をタゲっているかを、GetV()関数で調べる。
その結果、その敵が「ホム」「オーナーケミ」「友人」のいずれかをタゲっている、もしくは誰もタゲっていないなら、その敵を『攻撃してよい可能性のある敵』とする。
上記以外の敵(言い換えると「第三者」をタゲっている敵)は、『攻撃してはいけない敵』と判断する。 - 近くにいる「ケミ本人でも友人でもない、第三者プレイヤーキャラ」全てについて、そのキャラがどの敵をタゲっているかをGetV()関数で調べる。
その結果、そのキャラがタゲっている敵がいれば、それを『攻撃してはいけない敵』と判断する。
上記の組み合わせで、少しでも横殴りの可能性があれば攻撃を取りやめています。
表として書くと、以下のような感じ。「×」になっている部分は「横殴りになる」と考えて積極的攻撃をしないようにしています。
その敵が攻撃していない | その敵が味方を殴っている | その敵が第三者を殴っている | |
誰もその敵を殴っていない | ○ フリーの敵 | ○ 味方が一方的にやられている | × 第三者が一方的にやられている |
味方(だけ)がその敵を殴っている | ○ 草類 | ○ 普通の交戦中 | × 味方が横殴りしてる |
第三者がその敵を殴っている | × 第三者草刈 | × 第三者がこっちを横殴り | × 第三者が普通に交戦中 |
ただしこのアルゴリズムには、ROクライアントの(GetV関数の)仕様上、穴が存在します。
誰が誰をタゲっているかを知る手段には原則的にGetV()しか手段がないのですが、誰かが(人間の目から見ればあきらかに)誰かをタゲっているにもかかわらず、GetV()では「誰もタゲっていない」ように見えるような状況がいくつかあるのです。
以下にいくつか例を列挙すると・・・
- アクティブ敵が(PCを発見して)PCに向かって移動している場合。
イメージとしては、「近くにいる騎士に向かって歩いている、まだ接敵していないスケワカ」のようなもの。
人間の目では「その敵(スケワカ)がそのPC(騎士)をタゲっている」ように見えますが、GetV()では「その敵は誰もタゲっていない」ように見えます。 - プロボックなど「遠距離から、即反撃をされないようなタゲ取り」をした場合。
この場合も上述に近く、敵は「プロボックを行った」キャラに向かって移動を始めますが、GetV()では「その敵は誰もタゲっていない」ように見えます。 - いわゆる「火壁で隔離」している敵も、これに類似します。
敵は火壁の向こうにいる魔法使いに向かって歩き&はじかれているので、人間からみると「その魔法使いのタゲ」と判断できますが、ホムからはそうは見えません:ただ単に「フリーの敵が狭い範囲を往復移動している」ように見えています。 - 1キャラクターが複数の敵を引っ張っている場合。
GetV()で取れる「そのキャラがタゲっている相手」は、最後に攻撃を仕掛けた相手1体分だけです。
例えばよくあるのが、「騎士が敵Aにプロボック、続けて敵Bをプロボック、接敵されないうちにトレイン移動」というようなことをした場合。
ホムから見ると「騎士は敵Bだけをタゲっている。敵Aはフリー(騎士は敵Aのタゲを取っていない)」ように見えてしまいます。 - ストームガストのような「地面指定の範囲魔法」の影響範囲を知ることもできません。
そのため、詠唱中・効果発動中のそういったスキルの攻撃範囲にいる敵は(その敵が実際に誰かを殴っていないかぎり)「フリー」として判断してしまいます。
このアルゴリズム、PC全てが普通に足を止めて戦闘をしている場合、ほぼ完璧に横殴りを阻止できます。
が、いわゆるトレインが絡むと上記した「GetV()がうまく効かない」ケースが置きやすくなり、結果横殴り判定に失敗してしまうことがあります。
Glenelgではこの問題に対する本質的な対処手段は、2006.Jul.16時点では何も入っていません。
一応「アクティブ索敵範囲を3セル程度」にすることで、間接的な対処にしています:トレインする人も普通は気をつかってすれ違うような動作は避ける傾向があるので、至近距離にこなければ横殴りにならない、という方針。
他のAIなどでは、「視界内に第三者がいたら、一切アクティブ攻撃をしない」ような仕組みを持っているものもあるようです。
これはある意味完全な「横殴り回避」策ではあるのですが、個人的にはこれはあまりに譲りすぎと考えたので、今のところ採用を見送っています。
・・・ある程度要求があるようなら、オプションとして採用を検討します。
いろいろ検討をした結果、
Ver0.38からオプションとして採用しました。
追記†
上述のアルゴからわかると思いますが、Glenelgでは「プレイヤーキャラの職業」については何も判断をしていません。
そのため、新しい職業が導入された直後でも、それに対する横殴りはしないはずです。