こんにちは。今回は現在細々とやっているDQ7 TASでの移動最適化のお話をしようかなと思います。
前知識
DQ7 TASで使っている「Bizhawk」というエミュレータには「Lua Script」を動かす機能がついています。
要するにプログラミング言語のLuaを動かせるというお話です。さらにエミュレータの操作や値の取得、キー入力といった関数が用意されています。
(http://tasvideos.org/Bizhawk/LuaFunctions.html)より引用
これで何が出来るかと言うと、例えばステートセーブ(好きな場面でセーブできる機能)を併用して、思ったダメージが出なかったらやり直すであったりとか、メッセージ送りを自動化する、主人公が死んだらやり直す、画面上にHPなどの値を表示させるなど、BOTのようなことからビジュアル面でもLuaは活躍します。
今やっていること 「移動最適化」
そして私が今やっていることは「移動の最適化」です。マップでの最適な移動ルートの探索をLuaを使って自動化しようという魂胆です。DQ7はそのボリュームから移動にかかる時間が多く、ここを最速にできればタイムがぐっと縮まるはずです。
現在の進捗
方針としては、今のところは総当り(すべてのコマンド入力を順番に試す)で最適化を行っています。
メモリアドレスより得られているゲーム内の値は、主人公の座標、マップアドレス(これを使うと目的地へ移動したかが分かる)です。
手順としては
1.最適化したい場面でプログラムスタート
2.人力操作(コントローラー操作)でマップ移動
3.人力操作を記録。各フレームでのゴール地点までの距離を記録
4.総当りで最適な移動を探索(人力操作と比較して遅ければ、打ち切って次の総当りに移動)
5.最適な移動が見つかる(更新される)たびに外部ファイルにフレームごとの入力を出力
6.出力ファイルを見ながらTASに反映させる
といった手順で行っています。使っている値は主人公の座標、フレーム数からの現在の移動時間です。
2の人力操作でかかった時間と常にゴールまでの距離をフレームごとに記録し、4の総当りでは途中で人力操作より遅くなった・またはゴールまでの距離が人力より遠い時点で現在の入力の組み合わせを打ち切り(枝刈り)、次の入力を試すようにして高速化を図っています。
問題点
総当りパターンが多すぎる
DQ7ではカメラの角度によって移動速度が変わるという特徴があり、1フレームに対するコマンドの組み合わせは上下左右斜めの8コマンド×R1,2,L1,2,カメラ移動しないの5コマンドの計40コマンドの組み合わせがあります。更に10秒間(600フレーム)の移動で総当りするとなると、40×600=24000通りとなり膨大な数となってしまいます。ちょっとの距離でもかなり時間がかかり大変です。
計算資源(PCスペック)が貧弱
これは私の個人的な開発環境になってしまいますが、私のPCスペックが低すぎて、この最適化の総当りの遅さに拍車をかけています。早く新しいPC欲しいなぁ……。
エンカウントのあるマップは?
現在のプログラムではエンカウントのないマップでしか対応していません。なのでエンカウントする直前までの最適化を行ってからエンカウントの調整を行うという細切れの最適化になるかもしれません。それかチートコードで強制的にエンカウントなしにしてから最適化を行う→TASに反映させるとか。
カメラ角度
DQ7ではカメラの角度が変更できるため、8方向にしか移動ができなくてもカメラの角度を変えてやれば実質360°の移動が可能になります。そのため総当り数が大きくなっています。
解決案
1.移動コマンドの重み付け
総当たりなので最初はあらぬ方向へ進みます。ですが、キャラクターの座標を取得できているのでどっちの方向へ進むのが適切なのかという情報を得ることはできます。なのでこれを用いてもう少し最適化を高速化したいです。
2.新しいPCを買う
お金がないよぉ
3.諦める
総当りなんて時間かかるん当たり前なんやから一晩放置しとけばええやんけ!!
以上、現在の状況でした。お読み頂きありがとうございます。
2019.07.30 20:24 2019.07.30 22:35