スポンサーサイト

--.--.--.--:--

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

バグが起きない爆ラン記述方法(2/4)

2014.08.30.23:54

続きです。

今回はバグが発生しやすい記述方法と回避方法をお話しします。


そもそもどういうバグが起きるのか、。最初にその話しをします。

私が爆ランⅢ1.6で確認した現象です。
強制的に1つのパターンが出現するように確率を変えて、水の量を調査していました。水の割合自体も変更して、増やしたり減らしたりしていたのですが、それが正しく反映されていないという現象が起きていました。設定した数値よりあきらかに少なかったり、または、出現してはいけない時にでてきているのでバグと判断しました。

また私が作り直した方でも、出現割合0%になっているにもかかわらず出現してしまったことがありました。(それが後に回避方法発見へとつながりましたが)


つまり、バグとはどういうものかというと
正しくスクリプトが反映されない」(バグなんてそれしかないですが)
というものです。


これら2つの例の実際のランダムマップの記述を見ると、一見正しく書いてあると思えるスクリプトでも「ランダムマップスクリプトの記述には、独自の書き方が必要」と言うことがわかります。




それではバグの説明はこんなところで終わりにして本題に入ります。




爆ランの性質として「random(一部略)」「#define」「if(一部略)の3つのスクリプトを多用します。

「random(一部略)でどれを選ぶか選択し
「#define」で定義し
「if(一部略)で定義したものを引き出す

単体でも利用可能なものはありますが、これら3つが深くかかわりランダム要素のあるランダムマップを形成しています。

バグの発生は、これら3つのスクリプトの歯車がうまく噛み合わなかった時に起きます。


噛み合わなかった時に生じるのが「if(一部略)」によるデータ引き出しの失敗です。
(次から例をだして説明しますが、この事を頭の片隅に入れておいてください。)



では実際どういう時にデータの引き出しが失敗するか、ここから説明していきたいと思います。
注意!ここからはバグが起きやすいと思われる例をだして説明しますが、先に言ったようにバグは噛み合わなかった時に発生します。今からだす例では噛み合ってしまって、それらの記述では問題ない場合があります。その点ご了承ください。また、説明がとにかくややっこしくなるので頑張って想像してください。説明うまくできずすみません。

<例1:何回も同じ名前で定義しない&データの引き出し先を明確にする>
20140830_03.png


こちらの画像は、配布したバグ改善版を作る際の試作段階のものです。(改善前のもの)

どういったものか解説すると
・< PLAYER_SETUP >で、コメント部分(緑色の文字)のマップのベース地形タイプを選択で「SEA_TYPE」が100%で選択され、同時に「FOREST_LEVEL_MIN」も100%で選択されるようになっている
・< TERRAIN_GENERATION >で、もし選ばれたのが「FOREST_LEVEL_MIN」だった場合(今回の場合)「land_percent が 1(%)」になる


つまり、この画像の通り処理をすると
「1%分を木として他の(指定した)地形から置き換える」
という風になることになります。


「1%分を木として他の(指定した)地形から置き換える」ですが、
こちらを実際< TERRAIN_GENERATION >でデータを引き出そうとする時に

if FOREST_LEVEL_MIN
 ○○(処理)
endif


のような処理で引き出すと思います。

今回のケースの場合、100%の確率で「SEA_LEVEL_MAX」を選び、同じく100%の確率で「FOREST_LEVEL_MIN」を選んでいます。
しかし、この記述の場合どのような問題が生じるか。


「FOREST_LEVEL_MIN」は
「SEA_LEVEL_MAX」だけでなく、「SEA_LEVEL_2」と「SEA_LEVEL_MIN」にも存在しています。(全部で3つ)


先ほどの記述方法だと「FOREST_LEVEL_MINだったら」ということになりますが、どの時の「FOREST_LEVEL_MIN」かをきちんと指定してあげないと残り2箇所のいずれかを選んでしまうこともあります。


ちょっとわかりにくいかもしれないですが例えて言うなら、
親戚の苗字が全員一緒で仮に田中さんだとすると、
『本来、東京の田中さんを呼ぼうとしてたのに、誤って千葉の田中さんを呼んでしまった』
ということになります。
もしかしたら千葉だけでなく、埼玉や北海道の田中さんも呼ばれてしまうかもしれません。
さらには海外のMr.TANAKAも呼ばれるかもしれません。


もうちょっと田中さんを例に話しますが、
先ほどの記述が「田中さんを呼んでくれ」だとすると、今度作るものは
「日本の東京の田中さんを呼んでくれ」という記述に作りかえなければいけません。


一旦田中さんは置いといて、正しく反映されるように記述を作りかえるとこうなります。

20140830_04.png

大事なのが1~2行目、それと3・15・27行目の記述です。
見る人が見れば、住所のように感じるかもしれません。



< PLAYER_SETUP >でランダム発生させる時、大まかな内容に名前をつけていきました。

最初のランダムで「STANDARD_MAP」か「EXTRA_MAP」か。
次のランダムで「SEA_TYPE」か「LAND_TYPE」か。
その次のランダムで「SEA_LEVEL_MAX」か「SEA_LEVEL_2」か「SEA_LEVEL_MIN」か。
そして同じところにある「FOREST_LEVEL_MAX」などです。

これらは大まかな内容を知らせる為だけでなく、きちんとどれを指定してあげるか判別するための住所のような役割を同時に担っていたのです。(行きたい場所へ道がわかるように記す)

実際< TERRAIN_GENERATION >でどのパターンか引き出して使う時に正しく使うためには
「どこにあるものか、きちんと明確にしてあげる必要がある」というのを覚えておいてください。




もうひとつ、これはうろ覚えで申し訳ないのですが、何かの拍子に同じ名前で定義したものが引き出されるかもしれないので「同じ名前で定義するのはやめよう」と思い、配布した改善版ではなるべく使わないような記述に変えたと思います。

3ヶ月も経っているので記憶が曖昧ですが、できるだけ「#define」による定義は1回に済ませた方がいいかもしれません。




<例2:ランダム処理で済むところは、できるだけはランダム処理を行う。>

バグの一番の原因はifによるデータの引き出しと言いました。
それと同じ名前による定義を複数回行うのもよくないと言いました。

ifや#defineはたしかに便利なのですが、多用するとそれだけバグになるかも知れない機会を増やすことにもつながります。
できるだけデータを引き出す機会を減らし、その場でランダムによる数値決めなどをした方がバグになる機会を減らすことになります。

注意点
・該当部分にランダムの記述を増やすので、記述がさまざまな場所へちらばり手直しの手間は増えます
・文の量も多くなるので、ファイルの容量も多くなります


ifや#defineを使わないで済むところはなるべくランダムの処理で置き換えましょう。



~今回のまとめ~
「if(一部略)が一番バグが起きやすい。
「#define」は住所として使える。また同じ名前での定義はなるべく減らす。
「random(一部略)で済むところは極力、これに置き換える。



次回
「バグが起きない爆ラン記述方法(3/4)」に続く。



スポンサーサイト

comment

Secret

プロフィール

スキタイ人の青年

管理人:スキタイ人の青年

最新記事
最新コメント
カテゴリ
月別アーカイブ
リンク
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。