読者です 読者をやめる 読者になる 読者になる

ミニゲームのステージを自動生成した時の難易度調整はどうする?

最近はよくて10分遊んでもらえれば上出来みたいなミニゲーム作っているが、それでも数回は繰り返し遊んでもらえるくらいのリプレイアビリティは欲しい。でも面倒な作り込みはしたくない。

と考えた結果、ステージは無限に自動生成、1ステージは10秒くらい、残機無し即死だけどリトライし放題、クリアステージ数はブラウザに保存してコンティニュー可、という作りにしている。ステージをどこまで進められるか、というくらいのリプレイアビリティは得られるといいな、というもくろみ。

自動生成されるステージは面が進むたびに少しずつ難しくならないとハリが無い。かといって単に線形に難しくなっていくとメリハリが無い。それなりの波がありながらも確実に難しくなっていくステージをどうやったら作れるかなあということを考えていて、今のところ下のグラフを使っている。

difficulty graph

横軸はrandom()の0〜1の出目で、縦軸が難度(0が簡単で1が難しい)。ステージ開始前にrandom()を振ってその出目に対応する難度をそのステージの難度として採用する。

このグラフの難度は

Math.pow(random(), 100 / (stage + 1))

で求まっていて、ステージ数が少ないうちは難度の低い下方向に張り付き、ステージ数が進むと上へ膨らむようになっている。なので、先のステージになると、より高い難度が設定されやすくなる、けどたまにrandom()の機嫌によってはそのステージ数にしてはやたら簡単だったり難しくなったりする。

あとステージ全体の難しさが一つの難度で決まるのも楽しくないので、

  • 敵の数
  • 敵が弾を撃つ頻度
  • 弾のスピード

とかのいくつかのパラメタに対してそれぞれrandom()を振って上の式を当てはめた難度を設定する。そうするとあるステージでは敵の数はやたら多いけど弾はあまり撃たないとか、敵は一人しかいないんだけどやたら速い弾をやたら撃つ、とかいうバリエーションが得られる。

後半面になると全てのパラメタが難度1に張り付きがちになるので、全般的に難しい面が連続するようになる。でも難度自体は1が上限なので、単に線形に難度を上げていくよりはリミッタがかかる。

ていう具合にすると、まあ納得できる形で理不尽に難しくなっていくので、そこそこ気に入ってます。最終的には全てのパラメタが難度1に張り付いてカンストするので、無限に難しくなるのは実現できないし、その1に張り付いた難度設定をどの程度にすればいいの、ってところの調整が難しいのが難点。難易度曲線を考えるのは好きなので、またいろいろ考えたい。