2016年07月27日

ぼら猫パズルシステム解説その2 クリア判定の方法と不具合顛末記


この解説は連日更新していこうと思っていたところ、ウディコンの掲示板にて不具合の報告をいただいてずっと格闘していました。
今夜やっと修正ができたので、それについて書きます。

でもまずその前にそもそもこのパズルはどういう仕組みで動いているかですよね。
前回の記事で書いた通り、描画関係はデフォルトシステムの流用で楽にできました。
そしてキー入力関係も既存のものの流用で簡単にできました。
(これについては後日記事を分けて書こうと思います。)
一番問題だったのはクリア判定です。

プレイヤーの操作によってマス目の並びがお片付け成功状態になった時に、それをどう判定するか。
これはとても難しかったです。
でもこれができたなら一つのゲームができるという確信があったので、ちょっと自分の技術力から見ると背伸びでしたが挑戦しました。
作りたいものがはっきり見えていて、それに向けて試行錯誤している時って創作者にとって至福の時間ですね。大変なんだけど。

実際の制作は作ってもうまく動かない、やり直しても動かない、の繰り返しでした。
作り直すたびに発想を変え別の方法を試すのですが、3つ目の方法を試している時、方法とか以前の初歩的な失敗があったことに気づきました。
イベントの位置を把握するために入力していたX座標とY座標とが逆になっていたのでした。あれまぁ。
そりゃあ、どおりで何度作り直しても上手くいかないわけです。
そこを修正した途端、3つ目の方法がうまく機能し始めました。
なので1つ目や2つ目のやり方でもできてたのかもしれないです。
でももう消しちゃったし、3つ目の方法でできているので検証する必要もなく、今となってはどうしていたかも忘れてしまいました。
なので実際に採用した方法を説明します。

まず可変データベースに、各マスに関する数値を記録する場所を5×5の25用意しました。
マスの色は各マップイベントのセルフ変数に記憶させているので、この数値とは別です。
この数値のことは仮に感染値と名付けました。

そしてマスの入れかえ直後だけ動くコモンイベントを5つ用意しました。
5つのコモンは5つの色に対応します。
それらは各色に対して「端から順に見てその色が最初に出てきたとき、それとつながっている同じ色のますだけ感染値を入力する」という働きをするのです。
その結果、マスの入れかえ直後に全ての感染値を初期化しておけば、各色一つ目のかたまりのみ数値が入力されることになります。
ところでこのパズルの目指す状態は同じ色のますが全部かたまることです。
つまり一つ目のかたまりが全てとなって、二つ目のかたまりなんか存在しない、そんな状態を目指すのです。
なので5色全てが一つ目のかたまりだけになる、つまり未感染のますが存在しない、そういう状態になった時にクリアーしたと判定することにしました。

そして同じ色のかたまりを認識すること、これがまた非常に難しかったです。
これなんかは、以前tohさん主催のウディタリバーシに挑戦したからこそできたと思います。
あの経験がなかったらぼくには到底作れないシステムでした。
人との縁は不思議なものですね。出会いってありがたいです。

色のかたまりの認識を完全に制御することはぼくにはできませんでした。
今回採った方法は確率論的なものに頼っています。
イメージとしては、最初に出てきたその色のますを、菌に感染させる。
そして菌に自由な方向に発育を試させながら十分な時間を置き、それで感染している部分だけを隣接したかたまりであるとみなす。
そういう方法にしました。

各色について、最初に見つかったマスに置かれた「菌」は1100回自由な方向に移動を試みます。移動先が別の色なら移動はできません。
この1100という回数が大きくても少なくても不具合が起きました。
回数が少ないとかたまりの判定が不正確になります。
範囲が細長い場合には開始地点から反対の端まで感染が届かないまま判定終了することがありました。
逆に回数を多くすると処理が重くなります。
処理落ちを防ぐために、システム変数を使って1フレーム当たりのナンチャラが50万に近づいたらウェイトを入れるようにはしました。
それでも動きは遅くなるので、それではまずいので。
遅くならず、不正確にもならない回数が1100回だったというわけです。

それらの機能を実装できて、一応クリア判定ができるようになったわけです。
ただ、ウディコン開始後に報告をいただいた誤判定は、実は公開前から何度も確認はしていました。

そして何度も修正を加え「ついに修正に成功した!」と、何度も何度も思いました。
この不具合は再現頻度が高くないので、確認が大変だったんですよね。
確認のプレイをして、50回クリアしても出るか出ないかだったりする。
なので、修正をしたらとりあえず見つからなければ直ったと思いこむのですが、忘れたころに不具合が再確認され「え〜」となることがしばしばでした。



ScreenShot_2016_0721_21_01_44.png
あってはならない、禁断の画像。同じ色が二ケ所に分かれているのに、大成功!の文字が・・・。


さっき書いたXY座標のミスと同じで、最終的に見つかった不具合は致命的なものだったので、それ以前にチョコチョコ修正していたことに意味があったのかなかったのかはよくわかりません。
ただその過程を通して、ぼくがウディタの仕様について考え抜くことはできました。
最初は並列コモンをいくつも適当に置いておいて「いつでも同時に動いてるだろ」と思っていたのですが・・・。
並列でも1フレーム内ではコモンは番号順に処理されるのだろうから、並び順がすごく大事なんじゃないかとか思って並べ替えてみたり。
並列コモン内の処理が完了するまでにフレームの切り替えが必要なんじゃないかとか疑心暗鬼になってあちこちに1フレームウェイトをはさんでみたり。
コモン呼び出しをやめて予約にしてみたり。
とにかく原因が分からないからいろいろ試しまくりました。
そして最終的にわかったことは、感染させるコモンが不完全だったのです。
(隣接ますに移動を試みた際にそのマスが範囲外だった時、記憶させている隣接ますのイベント番号を初期化し忘れていたのでした)

これに気づくまでには、このゲームシステムを作ったのと同じくらいの労力をかけました。
なので2作作った気分です。
反省点としては、可視化することの重要性ですね。
データベースの中に何が入っているかをちゃんと常時表示確認していれば、不具合自体はたまにしか起きなくても内部数値はしょっちゅうおかしなことになっているということにゲーム公開前に気づけたと思います。


ScreenShot_2016_0727_00_45_34.png
忘れちゃいけない、可視化。

それとこれは難しいけれど、やっぱり先入観念を捨てるのが大事ですね。
ぼくの場合は並列とかフレームとかの仕様などをいまいち理解しきれていないという意識があるために、謎の不具合に出会ってそこばかり注目していました。
適切な場所を落ちついてよーく見れば30分で「ここがおかしい」と気づけるはずの失敗でした。
いい勉強になりました。
せっかくプレイしてもらって不具合にあわれた方、申し訳ありませんでした。

次回はキー入力について少しだけ書いて、ぼら猫パズルのシステム解説を終わる予定です。

posted by じゃ。 at 00:56| Comment(0) | 雑文 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント: