Posts
KFM 2.18a リリース
バグの深刻度が比較的高めだったので緊急リリースすることにした。
事の発端
KFM をプレイしていると、たまにキャラクターの動作がおかしくなることがあり、検証を行ったところスーパーアーマー状態が発生していることが分かった。
上昇する必殺技を出した後に地上スレスレで攻撃を食らうと、座標上は地上なので地上食らいにはなるが、下降ベクトルが残ったままなので着地が発生してしまい、食らいモーションをキャンセルしてニュートラルに戻っていた。
KFA で検証
KFA でも同じ現象が発生するのか確認するため、着地が地面スレスレになる RYOU の大青龍拳で検証したところ、地上食らいになっただけで動作に問題は見られなかった。ただ、落下動作をスローモーションで確認してみると何かがおかしい。
つまり、RYOU は地上スレスレの状態で攻撃を食らっているのではなく、次のフレームで着地した後、普通に地上で攻撃を食らっていた。下降ベクトルは着地するとクリアされるので、KFM のような問題は発生しない。
検証は「落下地点に高さ 1 ドットの飛び道具を設置する」という方法で行ったが、高さを 2 ドットにすると空中食らいになったので、着地寸前のモーションが浮いているのは間違いないと思われる。
KFA の座標精度
KFA で RYOU の大青龍拳を出すと滞空時間が KFX より 1F 長くなり、増えたフレームは地上スレスレの状態だったので「KFA は地上スレスレを着地として扱わない」という仕様だと思い込んでしまった。
仕様を誤認する要因の一つとなったのが、座標とベクトルの切りの良さで、大青龍拳は上昇ベクトルが 144、重力が 16 なので、理論上は地面にめり込まず地面ぴったりの位置での着地となる。以下は垂直方向の座標とベクトルをシミュレーションしたもの。
| ベクトル | 適用後座標 |
|---|---|
| 0 | 0 |
| 144 | 144 |
| 128 | 272 |
| 112 | 384 |
| 96 | 480 |
| 80 | 560 |
| 64 | 624 |
| 48 | 672 |
| 32 | 704 |
| 16 | 720 |
| 0 | 720 |
| -16 | 704 |
| -32 | 672 |
| -48 | 624 |
| -64 | 560 |
| -80 | 480 |
| -96 | 384 |
| -112 | 272 |
| -128 | 144 |
| -144 | 0 |
座標にズレがあるとなると、最初に疑われるのが浮動小数点数による誤差で、先程のベクトルと重力は浮動小数点数で正確に表現することができない値となっている。Java で採用されている IEEE 754 だと以下のような値に変換される。
| motion.lst 上の値 | 浮動小数点数 |
|---|---|
| 144 | 14.399999618530273 |
| 16 | 1.5999999046325684 |
浮動小数点数でシミュレーションを行うと、最終座標は 0.0000090599060059 となり微妙に浮いている状態と言えるので、一応辻褄は合う。そこで、上昇ベクトルが 150、重力が 15 という正確に表現可能な値 (2^-n) を使って再度検証を行うことにした。
微妙に浮くことなく着地となったので、原因は浮動小数点数による誤差で確定かと思われたが、KFA は固定小数点数で保持していると聞いた覚えがある。そこで Ya-Ta さんに誤差について確認したところ「よくわからん」という答えだったので、原因は分からずじまい。
KFM での対策
KFM 2.12 で着地の挙動を変更したが、
- 地面スレスレで着地しないのは誤差によるもので着地するケースもある。
- 着地させないとスーパーアーマー状態になってしまう。
という理由により変更を取り消すことにした。