Papyrus による世界の創造 - Skyrim MOD 制作

迷路の自動生成 - 実用的な Papyrus サンプル群

最終更新: 2015-04-02 (木) 21:36:11 (151d)

MOD 本体

fileRandDungsMazeExample.zip

  • RandomMazeExample.esp
  • Scripts
    • RandDungsMaze.pex
    • RandDungsMazeActivator.pex
    • RandDungsMazeFloor.pex
    • Source
      • RandDungsMaze.psc
      • RandDungsMazeActivator.psc
      • RandDungsMazeFloor.psc

インストール方法

解凍して Data フォルダにコピーもしくは NMM での導入も可能です。

アンインストール方法

アンインストールは、導入したファイルを全て削除すれば完了です。Data フォルダを「Example」で検索すれば該当ファイルが全て検索できるので簡単です。

NMM で導入した場合は、NMM が全部やってくれます。

概要

CenterOnCell - coc(セル移動) コンソールコマンドにて部屋に行きます。

coc mazeexample

以下のメッセージボックスが出るので、迷路が生成されるまで数秒ほど待ちます。

Wait a few seconds.
creating the random maze ...

迷路の生成が終わるまで、入口の扉には鍵が掛かっており、迷路の中に入ることはできませんので、扉の前で待ってください。

迷路の生成が終わると、次のメッセージボックスが出ます。

OK. Open the door. Let's Go!

扉の鍵が開くので、入って出口を目指しましょう。

|automaze.jpg

待っている間に ToggleFlyCamera - tfc(カメラ操作モード切り替え) コンソールコマンドで扉の向こう側を見ると、出口だけが用意された状態であることがわかります。

tfc

また、迷路作成途中の模様も見れます。

ポイント

3つのソースの役割

今回のサンプルには3つの Papyrus スクリプトがありますが、役割がそれぞれ異なります。

スクリプト名役割
RandDungsMaze純粋な迷路作成ロジック部分であり、Skyrim には一切関係がない独立プログラム。迷路作成のアルゴリズムには「壁のばし法」を使っている*1
RandDungsMazeFloor迷路の作成~フィールドへのオブジェクトの設置を行う部分である。再入室時には迷路を作りなおすため、迷路を破棄するロジックも含んでいる。
RandDungsMazeActivator全体の制御を行うプログラムであり、イベント制御・メッセージ出力および RandDungsMazeFloor へ迷路の作成指示を行い、終わったら扉を開ける制御を行なっている部分である。また、再入室の場合には迷路の作り直しの指示もここで行なっている。

迷路作成ロジック部分について

迷路の作成結果を見るために毎回ゲームを起動しなければならないのは大変であるため、一度、別の言語(今回は Ruby を使用)で迷路作成ロジックの部分を作りました。

その上で Papyrus スクリプトに落とし込んだのが RandDungsMaze の部分になります。

Ruby から Papyrus スクリプトへの書き換えには、簡単なトランスレータを作り、繰り返し Ruby から Papyrus スクリプトへの変換ができるようにし、作業効率を上げています。

トランスレータの部分に関しては、今後、必要があれば公開を考えています。

迷路をフィールドに配置するにあたって Nordic/BgHalls キットを使用

Nordic を採用したのは、Creation Kit の入門にて使われており、わかりやすかったからですが、SmHalls だと通路が狭くできあがった迷路がわかりづらかったため、BgHalls を採用しました。

1つの部品の大きさは 512x512 の正方形で、組み合わせにより任意の通路を作成できます。

全てを自動生成するのではなく、入口と出口、それに必要なマーカーは事前に設置しておきます。マーカーはフィールドを配置するための位置取りに使いました。以下の図が事前の設計図です。

design.png

そして、スクリプトは迷路全体を捜査し、

  • どの部品を使うか?
  • どの方向に設置するか?

を判断して設置&回転を実行します。

限界について

2つの限界があります。

  • サイズ
  • 生成速度

1つ目のサイズですが、Papyrus スクリプトは配列のサイズに 128 の上限があります。正方形にして 11 × 11 の 121 マスの迷路が精一杯です。11 という数字は、壁と空間との両方を表しているので、実質的な迷路として通れる空間のサイズは 5 × 5 でしかありません。

配列をつなげて大きくするロジックを間に挟むことで、多少の改善はできます。

2つ目の生成速度ですが、Ruby での生成は一瞬ですが、Papyrus スクリプトだと数秒を要するという対比になりました。アルゴリズムの改善に予知はあるのですが、それでも生成速度は一番のネックかもしれません。