Seaside Laboratory

Article

コマンドバッファを利用した連続入力

リバーサルやガードキャンセルフラグを利用しての連続入力を理解している人を対象に説明をします。

仕組み

格闘ゲームには烈火拳や葵花といった連続入力技が存在します。これを再現するには入力ステップごとに違うキャンセルフラグを立てる必要があるため、フラグを大量消費してしまうのが欠点です。しかし、視点をかえてみると・・・。

葵花 1 段目 = 24p

葵花 2 段目 = 24p24p

葵花 3 段目 = 24p24p24p

と考えることができます。この説明を見ただけでピンと来る人もいるのでは?

具体的な内容

今回はフラグにリバーサルフラグを利用します。

葵花 1 段目の終わり際をリバーサル可能にしておきます。葵花 2 段目の終わり際もリバーサル可能にしておきます。葵花 3 段目はこれ以上の入力がないので、キャンセル不可能にしておきます。

そしてコマンドリストの方は、このように、設定をします。

100      24p   00001  011   1000  -1  ;葵花1
101    2424p   00001  011   1010  -1  ;葵花2
102  242424p   00001  011   1020  -1  ;葵花3

1 段目のコマンドバッファの状態は 24p なので、1000 番の技が発動。

2 段目のコマンドバッファの状態は、1 段目のコマンドと 2 段目のコマンドを足したものになるので 24p24p になり、1010 番の技が発動。

2 段目のコマンドバッファの状態は、1 段目のコマンドと 2 段目のコマンドと 3 段目のコマンドを足したものになるので 24p24p24p になり、1020 番の技が発動。

つまり、1 段目で 24p を入力して 2 段目の 24p を入力するというコマンド上 2 段目のコマンドには、1 段目のコマンドが含まれるという原理を利用して連続入力を行います。連続入力というのは、何段目なのか判別する手段が必要になるのですが、フラグを用いた時はフラグが識別子であり、今回のものはコマンドの違いが識別子になったわけです。

不具合対処

連続入力での問題点に「特定コマンドいれれば 2 段目以降が出せちゃうでしょ?」というのがあります。こういうときは、同じコマンドのダミー技を入れておくのがセオリーなので、とりあえずリストに追加します。

100      24p   00001  011   1000  -1  ;葵花1
101    2424p   00001  011   1010  -1  ;葵花2
102  242424p   00001  011   1020  -1  ;葵花3
103    2424p   00000  011    250  -1  ;弱パンチ(葵花2暴発防止)
104  242424p   00000  011    250  -1  ;弱パンチ(葵花3暴発防止)

となりますが、242424p コマンドは 2424p コマンドを含むので、省略することができます。

100      24p   00001  011   1000  -1  ;葵花1
101    2424p   00001  011   1010  -1  ;葵花2
102  242424p   00001  011   1020  -1  ;葵花3
103    2424p   00000  011    250  -1  ;弱パンチ(葵花2&3暴発防止)

フラグとコマンド優先法則により、特定コマンドをいれても弱パンチが発動し 2 段目以降の技が出ることはなくなりました。一見、これで良いように見えますが、まだ問題はあります。例えば、しゃがんだあとに敵の飛び道具を立ちガードし、葵花で反撃しようとしても通常技が出てしまいます。なぜならしゃがみから立ちガードへ以降した際に入力される 24 というコマンドと葵花コマンドが連結し 2424p というコマンドになってしまうからです。通常技が暴発するとプレイし辛いので以下のように書き換えます。

101    2424p   00001  011   1010  -1  ;葵花2
102  242424p   00001  011   1020  -1  ;葵花3
103      24p   00001  011   1000  -1  ;葵花1

さきほど書いたコマンドの 1 段目を下に持ってきただけです。103 行の 24p コマンドが 2424p と 242424p コマンドに含まれるので、暴発防止コマンドは不必要になりました。でも、今度は追加入力しても初段しか出なくなってしまいます。原因は、リバーサル状態をリバーサルキャンセルしているので一番下の初段が優先発動するためです。これを防止するには以下のように書き換えます。

101    2424p   00001  011   1010  -1  ;葵花2
102  242424p   00001  011   1020  -1  ;葵花3
103      24p   00100  011   1000  -1  ;葵花1

103 行のフラグをリバーサルから、必殺技キャンセルへ変更しただけです。これによって暴発は起こらなくなります。しかも、初段は必殺技キャンセルできたほうが調度いいですね。

欠点

コマンドバッファに前回の入力が残っているのを利用しているために、あまりモーションが長いとコマンドバッファの中身が流れてしまって使い物にならなくなります。何段まで連続入力が可能になるのかも、モーションの長さと、コマンドの長さ次第です。詳しくは「コマンドバッファの仕組による問題」を参照してください。

もう一つの欠点は 1 段目の入力をした後、キャンセルに間に合うように 3 段目のコマンド入力してキャンセルをすると、2 段目をスキップして 3 段目が出てしまいます。実用上あまり問題にはなりませんが、こういうことが起きうることを頭の隅にでも入れておいたほうがいいのかもしれません。

コマンドバッファの仕組による問題

コマンドバッファとは、キーの入力を溜めこんでおく場所です。格闘ゲームにはコマンド技というものが存在するので、数フレーム前までの入力を参照してコマンドが発動可能か調べる必要があります。コマンドバッファはある一定の大きさがあり、時間が流れるとともに一番古い入力情報から破棄されていきます。ステップ数の多い技をだらだらと入力すると技が発動しないというのは、入力が遅いためコマンドの一部がバッファから破棄されてしまうのが原因です。 (実は他の要因もあるのですが説明を省きます)

例えば、コマンドバッファの入力数が 0 ~ 9 までの 10 ステップ記録可能だとします。

状態 9 8 7 6 5 4 3 2 1 0
初期状態 - - - - - - - - - -
1 段目入力 - - - - - - - 2 4 p
2 段目入力 - - - - 2 4 p 2 4 p
3 段目入力 - 2 4 p 2 4 p 2 4 p
4 段目入力 p 2 4 p 2 4 p 2 4 p

始めの方にあった 24 コマンドがコマンドバッファに入りきらなくなり、破棄されてしまうので、3 段目の入力と 4 段目の入力の区別がつかなくなります。同じフラグを使っているので、区別がつかないと 3 段目の次に再度 3 段目でキャンセルがかかってしまうという問題が起こります。

このロジックが理解できれば、なぜ長いモーションはマズイのかも理解できるようになります。モーションが長いということは、次の追加入力までの間が長いということになります。時間とともにコマンドは破棄されていくので、追加入力までの間にもコマンドが破棄されています。そのため、モーションが長いものほど追加入力ステップ数が少なくなります。

コマンドリストのコマンド長による問題

経験上からわかっている人もいると思いますが、KFX のパラメータのサイズや行数には最大サイズが決まっています。例えば、モーションの行数は 1299 行が限界です。これは、プログラム側が固定サイズの記憶領域を確保した後にリストのデータを読みこんでいるからです。

コマンドを記述する部分にも限界文字数が存在します。今回のテクニックのように段階が増えるとコマンドが長くなるので、いずれは限界文字数を超過してしまうでしょう。そのため、連続入力回数も限界文字数の範囲でやる必要があるということです。

ちなみに KFX はチェックがあまいので指定サイズを超えてもソフトに警告されるということは起きません。しかし、指定サイズを超えたデータは記憶領域に入りきらずに他の記憶領域を破壊します。KFX が落ちる原因になるのでほどほどにしましょう。