DQ6 AI処理の解析2

多少間があいてしまいましたが、徐々に通常モードに復帰します。今回はまだリハビリ中ということで軽めに。

  • SR: $025BA3 AI行動決定
025BA3 LDX $2555 X=$2555
025BA6 STX $258B $258B=X
025BA9 JSL $C2C197 SR: $02C197 行動主体がAI行動決定の必要があるか(ないc=on)
025BAD BCS #$5B if(c==on) goto $025C0A
025BAF PEA #$2515 Push #$2515
025BB2 PEA #$0080 Push #$0080
025BB5 PEA #$7E00 Push #$7E00 まねまね発動中
025BB8 JSL $C92965 SR: $092965
025BBC BNE #$4C if(z==off) goto $025C0A
025BBE PEA #$2516 Push #$2516
025BC1 PEA #$0001 Push #$0001
025BC4 PEA #$7E00 Push #$7E00 腕輪発動中
025BC7 JSL $C92965 SR: $092965
025BCB BNE #$3D if(z==off) goto $025C0A
025BCD JSL $C2590F SR: $02590F AI対象外戦闘行動か(該当c=on)
025BD1 BCS #$A3 if(c==on) goto $025B76
025BD3 JSL $C2EFA7 SR: $02EFA7 引数:1#$204F 引数:2#$01FF
025BDB AND #$00FF A&=#$00FF
025BDE CMP #$0001 A==#$0001? 主人公ならAI対象外
025BE1 BEQ #$27 if(z==on) goto $025C0A
025BE3 JSL $C43488 SR: $043488 引数:1#$FF 作戦取得
025BE8 CMP #$0005 A==#$0005? めいれいさせろならスキップ
025BEB BEQ #$1D if(z==on) goto $025C0A
025BED JSL $C2EFA7 SR: $02EFA7 引数:1#$2054 引数:2#$000F
025BF5 CMP #$0000 A==#$0000? 受け身中ならスキップ
025BF8 BNE #$10 if(z==off) goto $025C0A
025BFA JSL $C2CF63 SR: $02CF63 AI行動決定コア
025BFE LDA $258D A=$258D
025C01 STA $255F $255F=A
025C04 LDA $2591 A=$2591
025C07 STA $2557 $2557=A
025C0A RTS return

このSRがAI行動決定の一番トップのSRです。この中で全てAIに関する行動が決まります。条件に応じてAI行動決定コアSRを飛ばすようになっているだけで、特筆する点はありません。

  • SR: $02CF63 AI行動決定コア
02CF63 PHP Push P Flag
02CF64 REP #$30 m=off(A/M:16b) x=off(X/Y:16b)
02CF66 PHA Push A
02CF67 PHX Push X
02CF68 PHY Push Y
02CF69 PHB Push DB
02CF6A PEA #$7E7E Push #$7E7E
02CF6D PLB Pull DB
02CF6E PLB Pull DB
02CF6F JSR $CF86 SR: $02CF86 AI行動決定用RAM領域初期化
02CF72 JSR $CF9B SR: $02CF9B AI判断用情報をメモリにセット
02CF75 JSR $D01B SR: $02D01B 各キャラクター用AI判断用情報セット
02CF78 JSR $D15E SR: $02D15E モンスター特別種族情報セット
02CF7B JSR $D191 SR: $02D191 AI行動決定
02CF7E PLB Pull DB
02CF7F REP #$30 m=off(A/M:16b) x=off(X/Y:16b)
02CF81 PLY Pull Y
02CF82 PLX Pull X
02CF83 PLA Pull A
02CF84 PLP Pull P Flag
02CF85 RTL return

ここもまだ大きなSRの段階なのでこのSR自体も「まあそんなもん」という感じでしかありません。次回からよく使われるRAMの意味を説明してから更に掘り進んでいきます。

例のAI実装についてはほぼ終わったので、まずは学習機能をOFFにしておかしな行動を取らないかの確認をするべく0からテストプレイをしています(ちんたらやっているのでまだダーマ近辺)。やはりというべきか、ポツポツと期待した通りの動作をしていないのを見つけてデバッグをしながら進めているので進行度合いはかなり遅いです。自動SS採取機能付きのSnes9Xでプレイしているので、再現に手間がかからないのがいいです。現状気になる点として「行動決定までに一瞬間があるキャラクターがいる」という点です。行動可能な戦闘行動についてすべてシミュレーションをする必要がある以上、レベルが上がるほど(行動の選択肢が増えれば増えるほど)トータルの計算量が増え、人間が違和感を感じるレベルまでの遅延が発生する可能性はどうしても防げないのですが、選択肢の少ない序盤にもかかわらず違和感を感じるキャラクターが出てきてしまったのでこれからデバッグをするところです。明らかにバグっていて処理が遅いというのであればバグを直せばいいだけなのですが、問題は「正しい処理をしているが、プログラムの書き方が悪くて遅い」場合の対処法です。理想を言えば「とある箇所でブレークポイントを張り、その次に止まったところまでのサイクル数のカウント及びどのSRでサイクル数を食っているかを表示するプロファイラーのような機能」があれば少なくとも遅い箇所を特定することはできます。実際その箇所の処理を早くできるかどうかは別として、時間のかかっている場所を特定できなければ適切な対処もできないということで、一番近いところにいそうなGeiger’s Snes9x Debuggerにその機能がないかざっくり見てみたのですが、なさそうです。ソースも公開されていなそうなので機能追加するというわけにもいかなそうなので、プレーンなSnes9Xに機能を付けるとしたら結構面倒くさそうです。

コメント

  1. akito より:

    AI行動の計算に入る前に「○○はかんがえている」のようなメッセージを表示すれば遅延によるプレイヤーのストレスを軽減できるかもしれません。
    根本的な解決ではありませんが・・・。

    管理者より返信:

    そのうちモノを出すので見てもらえばわかりますが、そこまで遅くはないんですよね…。DQ3はDQ6に比べて特技がないぶん選択肢はかなり少ないですが、現状魔法使いと僧侶の呪文を全て覚えたときのみ若干の引っ掛かりを感じるレベルです。

    対処法としてはAIなしの場合も若干のウェイトを入れるというのも考えられなくはないですが、AIの遅さをごまかすためにほかも遅くするというのはどうにもすっきりしないのでとりあえず最初の段階では何も対処はしないままリリースすると思います。現在初回クリアまでテストプレイしましたが、初回クリアまでは特に引っ掛かりを感じることはありませんでした。