DQ3 Extenedのススメ

先日質問を受けて不思議に思ったのが「なぜDQ3の改造にDQ3 Extended(最新版はv1.444)ではなくオリジナル版を使うのか」ということです。DQ3 Extendedという素晴らしいパッチの存在が十分周知されていないのではということで、「なぜDQ3 Extendedを使うべきなのか」を使用者の観点からつらつら書いていこうと思います。

DQ3 Extended

DQ3 Extendedとは、86氏作の「オリジナルROMを4MBから6MBに拡張し、各種データ領域に余裕をもたせることで改造作業を容易にする」ことを目的としたベースパッチです。データの移動に伴い、それらを参照しているSRもあわせて変更されているので、単純にサイズを広げて空き領域にデータを移動させたものではありません。また、DQ3 Extendedは拡張系のパッチに見られる「ゲーム性を変えるような変更」は隠し要素としても一切含んでおらず、パッチを当ててプレイしてもオリジナルと何も変わりません。

はっきり言ってDQ3の改造をするにあたってあえてオリジナル版を使用するメリットはありません。自分の中では「各種データ量に余裕をもたせることを目的とした極めてプレーンな(作成者のエゴを含まない)パッチ」という位置づけです。「他人の手の入ったパッチをベースにしたくない」という人も嫌悪感なく使えると思います。

強いてデメリットを上げるなら

  1. ROMサイズが2MB増える。それに応じてパッチのファイルサイズも増える
  2. 盗賊のアイテム使用バグ(勇者と同じになっている)が修正されてしまっている?

くらいです。1はこのご時世2MBくらい増えたところで何が悪いのという感じですし、今時ExHiROMに対応していないエミュというのも考えにくいのであえてオリジナルを選択して絶対的に優位になるケースは思いつきません。

2についてはもしオリジナルと同じようにしたいのであれば、単に盗賊のアイテム使用可能フラグを勇者に合わせればいいだけの話です。

というわけで、以下は使用することによるメリットです。ステマというわけではありませんが、当方作成のSFCGENEditor使用を前提とした時の話です(特に文字列編集まわり)。

  1. ROMサイズが2MB増える。使用できる領域が大幅に増える
  2. アイテム、モンスター、戦闘行動他各種固定長データに追加分を簡単に定義できる
  3. 文字列の編集が簡単になる

1はデメリットの裏返しですが、「たかが」2MBと侮るなかれ。オリジナルのDQ3でもオープニングからエンディングまでのプログラム部分は合計しても1MB程度なのでプログラムの変更をするには十分な領域と言えます。2とも関係しますが「何かを追加したいときにサイズの制約で削る箇所を考えなくていい」というのは精神衛生上非常によろしいことだと思います。

2も改造作業の入り口とも言えるアイテム、モンスター等の追加作業が簡単にできます。アイテムは27レコード、モンスターは96レコード、戦闘行動は110レコード空きがあるので、当面は何を削るか悩む必要はありません。また、モンスターの色やフィールドなどで共通で使用され、残り領域が88レコードしかなかったパレットアクセスもver1.4以降はモンスターパレットを別領域にジャンプさせることにより十分な領域(88+256=344)が確保されました。旧ブログのときにエントリ中で「残り数が少ない」と愚痴っていたら86氏に対応してもらったのを覚えています。

3は2の一部と言えなくもないですが、文字列の扱いは本体が可変長ということもあり少し特殊です。固定文字列、戦闘メッセージ、移動中メッセージは素早くアクセスできるように別途インデックスが存在します。8個(固定文字列は16個)おきに各データの先頭からのオフセットが1レコード3バイトの配列になっているので、まずはIDを8(or16)で割って商からオフセットの開始位置を取得し、オフセットから目的の文字列の開始位置を先頭から区切り文字を検索するして特定するという処理になっています。これによってレコードIDにかかわらず最大で検索する数が0~7(もしくは0~15)に限定できます。

例:固定文字列ID:$47「ひのきのぼう」の開始位置の取得

  1. 16で割った商をインデックスのID、余をインデックスから検索するレコード数とする(この場合は商は4、余は7)
  2. 固定文字列インデックス($190000-)の4レコード目の値($00006D)をオフセットとして取得し、固定文字列開始位置($190300)に足して($19036D)、$40レコード目の固定文字列の開始位置を取得する
  3. 2で取得した開始位置から文字列のデコードを行い、1の余(7)に相当する開始位置($19041E)を区切り文字($AC, $AEなど)が見つかったらカウントアップすることで特定する
  4. 3で取得した開始位置からデコードを行う。取得できた文字列は「26 24 12 24 DC 0E (AC)」(ACは区切り文字)

※アドレスはDQ3 Extendedで移動後のもの

戦闘メッセージについてもインデックスが16個おきではなく8個おきになるだけで同じ方法でアクセスしています。オリジナルでは、これらのデータの前後は別のデータで埋められているのでオリジナルに対して変更を加えようとすると

  • 総データ量を超える変更はできない(文字数を削るか維持するのみ)
  • 新たに文字列を定義することはできない

という制約に縛られることになります。SFCGENEditorのDQ36プラグインではこういった制限がある状態で編集可能にするのもアホらしいということで、表示のみ対応としています。さらに、レコード中の文字数を変更する場合、「変更した文字列ID以降のインデックスの開始位置を(増)減した分だけシフトする」作業が必要になります。上の例の「ひのきのぼう」を「ぼう」に変更した場合(文字数4減)、固定文字列インデックスの5レコード目以降のオフセット値を全てマイナス4する処理が必要になります。手作業でやってできなくはないですが、非常に手間がかかります(自分は1回手作業でやってみてギブアップしました)。SFCGENEditorのDQ36プラグインはこの処理を自動で行う実装をしているため、文字列の編集が極めて直感的に行なえます。別にステマというわけではないですが、自分が作業をするにあたって「これは手作業でやるのは無理」と判断した産物に過ぎません。一番この機能を使ってるのは自分だと思いますww。

また、移動中メッセージの文字列はハフマン圧縮を解凍し、全て1文字2バイトの可変長配列として保存されています。非圧縮のデータ形式は1文字2バイトになった点を除けば戦闘メッセージと同じになります。当然ハフマン解凍を行うSRはスキップするなどの変更が行われていますが、表面上はオリジナルと何も変わりません(多分)。これにより移動中メッセージの容量がオリジナル分で131KB→320KBと増えることになりますが、空き容量を含めても512KBとROM全体の6MBからすると1/12を占めるに留まります。ハフマン圧縮された文字列のデコードは極めて難解で自分もs-endo氏のサイトで公開されていたデコード用のCのソースコードをそのままパクってC#で書き換えただけなので、いまいち原理を理解していないのですが、「使用頻度の高い文字に短いIDを割り当てることで全体のサイズをビット単位で極小化している」ということなのではと思います。あまり良く覚えていませんが、移動中メッセージの区切りはバイト単位ではなく、バイトの中のビット単位で行われていたような気がします。

このように格納されたデータに対して、圧縮状態を保ったまま変更できるようにするのはかなり複雑な処理が必要です。真面目にやれば「移動中メッセージ全体で使用されている文字の使用率を計算し、一番高いものから少ないビットを割り当てていき、移動中メッセージ全体およびハフマン木を同時に更新する」という処理が必要なのではと思います。一度実装すれば楽なのかもしれませんが、実装が面倒くさそうなのと、メッセージを少しでも変えるたびにこの処理を行う必要があるのでちょこっと文字を変えると毎回再計算するのに時間がかかり、直感的な作業ができなくなる可能性があります。自分も当初は「非圧縮の文字列を格納するなんて領域がもったいない」と思っていましたが、実際に空き領域を眺めていると他にまだ余裕があるため、こだわる必要なしという結論に到達しました。いよいよサイズが厳しくなったら考えますが。したがって現状提供しているDQ36プラグインでは移動中メッセージについては「オリジナルではデコードのみ、拡張版のみ編集可能」という状態になっています。自分もDQ6 Extendedを作ったときは非圧縮のデータをROM中に配置し、デコード用SRを書き換えるというのが結構手間でした。圧縮を解凍したバイナリデータが間違っていたためにテストプレイ中に間違いに気づいて再度バイナリデータを埋め込み直したこともありました。

最後になりましたが、作者の86氏には改めてこの場でお礼申し上げます。

コメント

  1. さそりばち より:

    > 先日質問を受けて不思議に思ったのが「なぜDQ3の改造にDQ3 Extended(最新版はv1.444)ではなくオリジナル版を使うのか」ということです。
    > オリジナルを選択して絶対的に優位になるケースは思いつきません。

    単純に知らなかったというだけ。
    知っていたならば誰でもそちらを選ぶのは明白。
    まだ知らない人が多いかも知れないので、この記事はとても良い記事ですね。

    >「各種データ量に余裕をもたせることを目的とした極めてプレーンな(作成者のエゴを含まない)パッチ」

    という事を最初から知っていればダウンロードし適応していました。
    (これから改造を始めようとする方々や昔の自分に教えてやりたいです)

    個人的な話になりますが、この事がわかった時点ではすで通常版で
    (BNE2などを使い)複雑な改造をした後だったので、
    いまさらExtened適応で最初から改造しなおしともなると
    ただの苦行にしか感じず、あえてExtenedは使わずに
    さらに新しく改造を始めたという経緯です。

    ちょうど今日、満足出来るレベルにまで改造をし終えて
    今後数年間はドラクエ3をプレイしないだろうという段階に入りましたが、
    1ヶ月ほど前に「ROMを複数利用する」
    という手段を思いついたおかげでExtenedを利用せず
    拡張と同じ楽しみを擬似的に味わう事が出来たので不満はありません。
    (例:後半は使わないメラを潰してメラガイヤーにするなど様々な工夫をしました。)

    あなたのようにプログラムの変更に熟知している人なら
    造作もなく出来る事でも、初心者ならばどうがんばっても実現出来なかったり、
    出来たとしてもそこに至るまで無駄に手間隙がかかりすぎて
    得られた楽しみよりストレスの方が何倍も大きくなるというケースも多い。
    ROMを複数利用しつつ少し工夫をくわえるだけで、
    複雑な改造をストレスなく、またプログラムの勉強も必要最小限で済むので
    Extenedはほぼ不要となったわけです。

    >文字列の編集が簡単になる

    通常メッセージ変更については確かにこれだけは実現出来ませんでしたが、
    変えたい箇所はほんの4~5箇所程度だったので
    以前言ったとおりさっさと諦め、それ以外のやりたい改造は
    なにもかもすべて実現させる事が出来ました。
    それもこれもあなたが作って下さったSFCGENEditorのおかげです。

    良いツールを作って下さって本当にありがとうございました。
    改造に夢中になっている時間はとても楽しく過ごす事が出来ました。
    とても感謝しています。

    管理者より返信:

    手段はどうあれ「自分のやりたいこと」ができたのであればそれでいいと思います。

タイトルとURLをコピーしました