AI製作開始

Last-modified: 2014-08-01 (金) 22:44:05

AI作成の前準備で説明したとおり、直接「command」のあるステートの記述を編集して、AIを作成していく
triggerの設定は、技特性とstatenoのチェックで把握した各技の特性に合わせて記述していけば良い

 

triggerの仕組みや内容などを詳しく知りたいときは、GoogleやYahoo!で検索してみると良いだろう
また和訳KFM内の記述を読めば把握できるtriggerも多いし、このwikiのAIサンプル記述も参考になるはず

 

また元からある条件はなるべく遵守すること、でないと技の性能が変わってしまい改変となる
ただ元の条件に含まれているならば、記述そのものを変更しても問題は無いのだが
このwikiに置いては、可能な限り元々の記述を残しながら作成していく

 

<注意点・1>
AI用の記述に書き換えるのは、AI作成の前準備で作成した配布用ファイルの方だけ
元ファイルの方を書き換えると操作出来なくなるので、そこは気をつけた方が良い
<注意点・1>


 

例文1:三烈カンフー突き手

<注意点・2>

triggerall下位トリガーへの共通条件、これが満たされていないとその技は起動しない
trigger1基本トリガー、これが無いとエラーが出る(実はtriggerallが無くてもエラーは出ない)
trigger2以降、3、4、5、と増やしていけるが、間の番号が空いたり、順番が入れ変わっていたりすると
それ以降のtriggerは読み込まれなくなるので、注意して記述していく必要がある

<注意点・2>

 
編集前

[State -1, 三烈カンフー突き手];ゲージレベル1
type = ChangeState
value = 3000
triggerall = command = "TripleKFPalm"
triggerall = power >= 1000
trigger1 = statetype = S
trigger1 = ctrl
trigger2 = statetype != A
trigger2 = hitdefattr = SC, NA, SA, HA
trigger2 = stateno != [3000,3050)
trigger2 = movecontact
trigger3 = (StateNo = 1300) && (Time = [12,38]) ;ちょっとこ丸が追加

 
編集後

;非ロック式の高火力乱舞技、初段にのみ無敵あり、全段当てるなら距離100以内
[State -1, 三烈カンフー突き手];ゲージレベル1
type = ChangeState
value = 3000
triggerall = power >= 1000
triggerall = roundstate = 2
triggerall = p2statetype != L
triggerall = statetype != A
triggerall = p2bodydist X = [-10,100]
trigger1 = ctrl
trigger1 = p2statetype != A
trigger1 = p2movetype = A
trigger1 = p2bodydist X <= 80
trigger1 = random <= 200
trigger2 = hitdefattr = SC, NA, SA, HA
trigger2 = stateno != [3000,3050)
trigger2 = movehit
trigger2 = stateno = 1010
trigger2 = random <= 700
;trigger3 = (StateNo = 1300) && (Time = [12,38])


書き換えた部分は赤で表記しているので、順番に内容を説明する

 
triggerall
power >= 1000パワーゲージが1000点以上、つまり1本以上溜まっているとき
roundstate = 2試合前以降、試合後以前、要するに試合中のとき
p2statetype != L「statetype = L」はダウン中という意味、転じて「相手がダウン中でないとき」
statetype != A「statetype = A」は空中にいるという意味、転じて「地上にいるとき」
p2bodydist X = [-10,100]「p2bodydist X」は横方向の距離、それが「-10以上で100以下のとき」
 

「roundstate」は1が試合前、2が試合中、3が試合後を表す
フライングと死体蹴りを避けるため、各トリガーに必ず設定しておくこと

 

距離が100以下の時に、と言うのはメモに書き残してあるからすぐに理解できるだろうが
何故-10以上からなのかと思う人も居るかもしれない。その理由はMUGENの各キャラクターの差異にある
と言うのもMUGENのキャラクターの中には、当たり判定とぶつかり判定が一致していない物もあったりするのだ
そういうキャラクターが相手だと密着できなかったり、逆にめり込んでしまったりという事がある
つまり-10からと記述するのは、その「めり込んでしまったとき」でも固まらず技を出せるようにするため

 

またtrigger1の「statetype = S」は「(地上で)立ち状態のとき」という意味なのだが
それを「statetype != A」にまとめてしまっている。本当なら、しゃがみ中の場合は立ちに移行するよう
それ専用の記述を書く必要があるのだが、非常に複雑な記述になる上、やっても大して差が無かったりするため
MUGENのAIの場合「statetype = S」「statetype = C」を、「statetype != A」に略するというのは
半ば黙認されている状態である。このwikiでも、その辺の記述は略していく予定なのでご了承願いたい

 
trigger1
ctrlコントロール可能、つまりキー操作が可能な時
p2statetype != A「statetype != A」の相手版、つまり「相手が地上にいるとき」
p2movetype = A「movetype = A」は攻撃態勢のとき、転じて「相手が攻撃態勢のとき」
p2bodydist X <= 80相手との横方向の距離が、80「以下」のとき
random <= 200randomは0~999までの乱数を出すトリガー、各randam毎に違う乱数が出る
この場合はその乱数が200以下のとき、つまり低めの確率でという意味
 

相手が地上にいて攻撃態勢のとき、つまり無敵を生かしてカウンターで使うことを考えた記述
ゲージを消費するというリスクがあり、確実に成功するとは限らない(相手の技にも無敵がある可能性)
なので低めの確率で挑戦する、成功すれば大ダメージが期待できるし、追い込まれていた時は切り返しにもなる

 

triggerallで既に使用する距離を指定しているのに、また距離を指定しているのに加え
その距離を100から80まで縮めている理由だが、これはカウンターが当たる可能性を上げたいのに加えて
相手の飛び道具や設置に反応して出してしまうのを防ぐためでもある。MUGENキャラの攻撃範囲は
一般の格闘ゲームを参考に「最もリーチのある通常攻撃なら、おおよそ80~90前後」となっていることが多く
それに対してAIの方も、飛び道具や設置といった隙の大きい行動等は、潰されないようにその範囲外から
行うように設定してあることが多い。距離が100のままだと、まれにその範囲の端に引っかかってしまい
飛び道具や設置で技が潰されてしまう事がある。だから逆に使用する距離を80まで縮めて設定すれば
「相手の出す行動が通常攻撃になる」確率が上がり、カウンターが成功する確率も上がるという考えである

 

と言うのも「三烈カンフー突き手」に設定されている、無敵に関する記述の内容が

 

[State 3000, 相手の特定の攻撃属性無効]
type = NotHitBy
trigger1 = AnimElem = 2
value = , NA, SA, AT
time = 11

 

当たり判定表示<注意点・4>を参考にすると、「通常打撃」「必殺打撃」「全ての投げ技」に対して
無敵とされており、飛び道具に対しての無敵が無いため、飛び道具に反応して出されると困るというわけだ

 

ちなみに「p2bodydist X = [-10,100]」と「p2bodydist X <= 80」が重なっているので
この場合だと、実際に技を振る範囲は「p2bodydist X = [-10,80]」ということになる
ただ技の終わりまで完全無敵だったり、相手をロックして乱舞する技なら、こういう小細工は無用だと思う

 
trigger2
hitdefattr = SC, NA, SA, HA「hitdefattr」は攻撃の属性を判定する、「SC」は立ちかしゃがみ
「NA」は通常打撃、「SA」は必殺打撃、「HA」は超必殺打撃を表す
つまりこの場合は「地上で何がしかの打撃技を出しているとき」
stateno != [3000,3050)ステート番号が「3000以上~3050未満『以外』のとき」という意味
和訳KFMの場合、この範囲に入らないのは「三烈カンフー突き手」のみ
つまり同じ技を何度も連続キャンセルして出すことは出来ない
movehit攻撃が相手に触れて、なおかつガードされなかった(ヒットした)とき
stateno = 1010ステート番号が1010のとき、これに該当する技は「強カンフー突き手」
random <= 700乱数が700以下のとき、つまりかなりの高確率という意味
 

「三烈カンフー突き手」は「三烈カンフー突き手」自身以外の地上打撃技からなら、どれでもキャンセルして
繋げることが出来るという記述。ただ立ち弱パンチのように、相手の怯む時間が短い技だと、相手の復帰と
ガードが間に合ってしまったり。カンフーブローのように、相手を大きくノックバック(向こうへ押し出す)
させる技だと、届かなくて空振ってしまったりということがある。なので確実に当たって繋がる技を選ぶ
「強カンフー突き手」は大きく踏みこむ技なので確実に当たり、通常攻撃をキャンセルして出せるので
「通常攻撃→強カンフー突き手→三烈カンフー突き手」のコンボが成立するため、最適と言えるだろう

 

「movecontact」はヒット・ガード問わず『当たったら』という意味、それを「movehit」に変えてある
「movehit」は『当たって、なおかつガードされなかったとき』という意味なので、俗に言う「ヒット確認」の
コンボなどに使うが、今回は単純に「ゲージ消費というリスクのある大技なので、確実に成果を上げたい」
という考えでこのように設定している。なので強すぎると思うなら、元の「movecontact」に戻すと良いだろう

 

ちなみに『当たったがガードされたとき』は「moveguarded」と記述する、使う機会はあまり多くないけど
(さらに余談だがシールドやブロッキングはガードではないので、実は「movehit」で反応してしまったりする
 とは言えそれらの特殊ガードを成功されたら、即座に反撃されているはずなので気付かないだろうが)

 

乱数の要素は、本来ならコンボには無くても良いのだが、このwikiではコンボにも入れておくことにする
と言うのもこのwikiで教えるAIは、さほど複雑な動きをしない簡易な物であるため、どうしてもその動きは
ワンパターンになりがちである。なのであえてコンボにも乱数を入れる、すると他にも可能なコンボルートが
ある場合、ランダムでそちらを使ったりもするようになる。もちろん総ダメージ量が落ちることもあるだろうが
その意外な動きが役立つ場面もあるだろうし、何より見ていて飽きないというのは大切なことだ

 

ただコンボに乱数を使う場合、あまり確率を下げ過ぎると、今度はコンボが全く繋がらなくなってしまう
おおよその目安だが「random <= 500(~700くらい)」の中~高確率で設定すれば大丈夫だろう
(「三烈カンフー突き手」の場合は、なるべく優先して使いたいので「random <= 700」と高めに設定した)

 
trigger3
StateNo = 1300ステート番号が1300のとき、これに該当する技は「板投げ」
&&いわゆるand、ようするに「○○で、△△の場合」
()カッコ、数学と同様、括った範囲は先に答えを処理する(今回の場合無意味なのは秘密)
Time = [12,38]そのステートの経過時間、この場合だと普通ならまだ技後の硬直中のはず
 

「stateno = 1300」に該当する技は「板投げ(飛び道具)」、例えばこの飛び道具を牽制で出し
反応して避け移動で近づいてきた相手に対して、キャンセルの「三烈カンフー突き手」で迎撃する
といった使い方が出来るかもしれない。ただこのwikiで説明するには少々記述が複雑なのと
何より筆者の力不足ゆえ、今回はコメントアウトして「使わない」ということにさせてもらう

 

AIの作成に慣れてきたら、コメントアウトを解除し、この部分の記述に挑戦してみても良いかもしれない

 

例文2:立ち強パンチ

編集前

[State -1, 立ち強パンチ]
type = ChangeState
value = 210
triggerall = command = "y"
triggerall = command != "holddown"
trigger1 = statetype = S
trigger1 = ctrl
trigger2 = (stateno = 200) && time > 5
trigger3 = (stateno = 230) && time > 6

 
編集後

;発生は早いがリーチは短い、打点は高いが対空には使えない、距離は63まで届く
[State -1, 立ち強パンチ]
type = ChangeState
value = 210
triggerall = roundstate = 2
triggerall = p2statetype != L
triggerall = p2bodydist X = [-10,60]
triggerall = p2statetype = S
trigger1 = statetype != A
trigger1 = ctrl
trigger1 = p2movetype != A
trigger1 = random <= 200
trigger2 = (stateno = 200) && time > 5
trigger2 = movecontact
trigger2 = random <= 500
trigger3 = (stateno = 230) && time > 6
trigger3 = movecontact
trigger3 = random <= 500


 
triggerall
roundstate = 2「三烈カンフー突き手」と同様、試合中のとき
p2statetype != L「三烈カンフー突き手」と同様、相手がダウン中でないとき
p2bodydist X = [-10,60]「三烈カンフー突き手」とほぼ同様、リーチに合わせて距離を縮めた
p2statetype = S相手が地上で、立ち状態のとき
 

「三烈カンフー突き手」のときとほぼ同じなので、特筆すべきところはほとんど無い
ただ「距離は63まで届く」としながら「p2bodydist X = [-10,60]」と僅かに縮めてあるのは
前述した『MUGENキャラ毎に当たり判定も変わる』ことから、確実に当てることを考えて
ただ神経質になる必要は無い、端数が出たらキリの良い数字に丸めておこうか程度で良いと思う
また打点が高いのでしゃがみ状態の相手には当たりにくい、なので立ち状態の相手にのみ使うように

 
trigger1
statetype != A「三烈カンフー突き手」ではtriggerallだったが、今回はここ
ctrl「三烈カンフー突き手」と同様、コントロール可能なとき
p2movetype != A「p2movetype = A」の否定、つまり「相手が攻撃態勢ではないとき」
random <= 200「三烈カンフー突き手」と同様、低い確率で
 

「三烈カンフー突き手」ではtrigger1にstatetype = S、trigger2にstatetype != Aが記述されていたので
triggerallにstatetype != Aとまとめて記述したが、「立ち強パンチ」ではtrigger1にstatetype = Sだけ
記述されているので、trigger1にのみ(前述した通り「statetype != Aに略して」)記述しておく

 

「p2movetype = A」と「p2movetype != A」の説明を見れば分かるだろうが、「!」は否定の意味
ただしトリガーごとに、何処に「!」を入れれば否定になるのかは異なるので、注意して記述しよう
詳しいことはGoogleやYahoo!で検索するなり、このwikiのAIサンプルを読むなりすれば大体理解できるはず

 
trigger2
(stateno = 200) && time > 5「stateno = 200」に該当する技は「立ち弱パンチ」
「time」はそのステートの経過時間、この場合はまだ技の途中
movecontactヒット・ガード問わず攻撃が当たったらという意味
random <= 500「三烈カンフー突き手」と同様、コンボにもランダム性を
 

「立ち弱パンチ」からキャンセルして出せる、という記述なのだが「time > 5」とそのステートの
経過時間しか指定されていない。しかもかなり早めにキャンセルできるので、この場合だと「立ち弱パンチ」が
相手に当たる前にキャンセルして「立ち強パンチ」を出してしまいかねない。それではほとんど意味が無い

 

なので「movecontact」を追加する、「三烈カンフー突き手」のときはゲージ消費というリスクがあったので
「movehit」を用いたが、今回は通常攻撃なので神経質になる必要は無い。こうすれば「立ち弱パンチ」が
当たってから、キャンセルして「立ち強パンチ」を出すので、確実にコンボを繋げるだろう

 

「random <= 500」は「三烈カンフー突き手」のコンボの時にも書いた、コンボルートのランダム性のため

 
trigger3
(stateno = 230) && time > 6「stateno = 230」に該当する技は「立ち弱キック」
それに伴い「time」の必要経過時間が増えた
movecontacttrigger2と同様
random <= 500trigger2と同様
 

trigger3の内容はtrigger2とほぼ一緒、キャンセル元が「立ち弱キック」になって、それに伴い「time > 6」と
キャンセル可能になるまでに必要な経過時間が増えた。とは言えやっていることはほとんど一緒なので
trigger2を参考に記述していこう、と言うかほとんど丸写し状態なのだがこれで問題ない

 

よく使われるトリガー

ここは「よく使われるトリガー」のリストを作成する予定地、現在はまだ作成途中
随時増やしていく予定なので、それまではこのwikiのAIサンプルなどを読むなりして欲しい
また、もっと読みやすく編集してくれる方、追加を手伝ってくれる方は随時募集中です(切実)

 
 

「&&」 いわゆるand、ようするに『○○かつ、△△の場合』
「||」 こちらはor。ようするに『○○もしくは、△△の場合』
「()」 カッコ、数学と同様、括った範囲は先に答えを処理する
「[○○,△△]」 『○○から、△△までの範囲』、つまり[○○以上,△△以下]
「!」 『~以外』、トリガーの種類ごとに付けるべき位置が違い、間違うとエラーが出るので注意
「>」 不等号、『~未満(同数は含まない)』または『~より大きい(同数は含まない)』
「<」 上記に同じ
「=」 イコール、一致した場合、『>=』や『>』などと、適時使い分けること
「<=」 不等号その2、こちらは『以下~(同数も含む)』または『~以上(同数も含む)』
「>=」 上記に同じ

 

「movecontact」 ヒット・ガード問わず『攻撃が当たった』とき
「movehit」 当たって、なおかつ『ガードされなかった』とき
「moveguarded」 攻撃は当たったが『ガードされた』とき

 

「statetype = A」 空中状態
「statetype = S」 立ち状態
「statetype = C」 しゃがみ状態
「statetype = L」 ダウン状態

 

「movetype = A」 攻撃態勢
「movetype = H」 食らい中
「movetype = I」 それ以外の、どちらでもない状態

 

statetypeやmovetypeは頭に「p2」を付けることで、相手の状態を取得できる
p2statetype』や『p2movetype』は、このwikiのAIサンプルでよく目にするだろう

 

「stateno」 『現在の』ステートナンバーを取得する、コンボ条件としてよく見られる
「prevstateno」 『直前の』ステートナンバーを取得する、ほぼ目押しコンボ専用のトリガー

 

食らい中は「p2stateno = [5000,5999]」、ガードは「p2stateno = [120,155]」、より厳密にコンボしたいなら

 

「p2bodydist X」 相手との横方向の距離
「p2bodydist Y」 相手との縦方向の距離

 

ちなみに『p2bodydist Y』は、相手が自分より高い位置にいるとマイナスの数値を
相手が自分より低い位置にいるとプラスの数値を返す、間違えやすいところなので注意しよう

 

「InGuardDist」 ガード可能範囲(後ろキーを押したときガード体制を取る範囲)
「random」 0~999までの乱数を出す、抽選は各randam毎に行われる
「BackEdgeBodyDist」 自身の後方の画面端との距離を取得、追い詰められているか否かを判断できる
「FrontEdgeBodyDist」 こちらはその逆、自身の前方の画面端との距離を取得、あまり使わない

 

「life」 ライフの『現在値』を取得する、ドラクエで言うHP(ヒットポイント)
「lifemax」 ライフの『最大値』を取得する
「power」 パワーゲージの『現在値』を取得する、ドラクエで言うMP(マジックポイント)
「powermax」 パワーゲージの『最大値』を取得する

 

「life」は「p2life」で相手の値も取得できるが、防御力も関係するので『追い込んでいるか』の確認は難しい

 

「hitdefattr」 出している攻撃の属性を取得する

 

hitdefattrで取得できる属性は、「S(立ち)」「C(しゃがみ)」「A(空中)」というstatetypeと
「NA(通常打撃)」「SA(必殺打撃)」「HA(超必殺打撃)」「NT(通常投げ)」「ST(必殺投げ)」
「HT(超必殺投げ)」「NP(通常飛び道具)」「SP(必殺飛び道具)」「HP(超必殺飛び道具)」
といった、攻撃の種類を組み合わせて記述する(どう記述するかはAIサンプルを参照すること)

 

「NumProj」 出している『飛び道具』の数などを取得する
「NumHelper」 出している『ヘルパー』の数などを取得する

 

「enemynear」 『近い方の敵の』という意味、『p2』の使えないトリガーに使う

 

多くのトリガーは「p2」を付けると相手の値を取得できるが、一部のトリガーではそれが出来ない
例を挙げると「p2NumProj」「p2hitdefattr」などというトリガーは存在しない。なのでそれらの値を相手から
取得したいという時は、『enemynear,NumProj』や『enemynear,hitdefattr』といった形で記述する
どのトリガーがどちらの記述形式に当たるかは、検索したり、このwikiのAIサンプルを参考にしたりして欲しい

 

「Facing」 キャラクターの向いている向きを取得する、これ単体では役に立たないが……

 

「EnemyNear,Facing = Facing」ならば、相手と自分は同じ方向を向いている、つまりタッグ戦において相手が
こちらに背を向けていることがわかる。「EnemyNear,Facing != Facing」ならば、相手と自分は違う方向を
向いている、つまり向き合っているので、当て身などを使うのに適した状態だと分かる、というふうに使う