Skip to content

Instantly share code, notes, and snippets.

@cma2819
Last active November 17, 2019 16:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cma2819/34c9b00f12573316f9b6becc2c0ae948 to your computer and use it in GitHub Desktop.
Save cma2819/34c9b00f12573316f9b6becc2c0ae948 to your computer and use it in GitHub Desktop.
Stale Reference Manipulation 日本勢用ドキュメント

Stale Reference Manipulation 日本勢用ドキュメント

元資料の動画

https://www.youtube.com/watch?v=_7E4dFD8Bmw

用語

  • Actor(アクター)
    • 時オカを構成するオブジェクトひとつひとつを指す(?)
    • リンクや敵キャラも含む!!!(修正)
  • Actor File(アクターファイル)
    • メモリ内に保持する、各アクターの情報。
    • それがどのアイテムであるとか、どういう挙動をするとか、宝箱であれば中身は何かとかが書いてあるっぽい。
    • 各アイテムのアクターファイルは各マップで初めて使われたときに1度だけ読み込まれ、複数の同じアイテム内で使いまわされる。
  • Actor Instance(アクターインスタンス)
    • メモリ内に保持する、ゲーム内に生成された各アクターの状態の情報。
    • ゲーム内座標とか。
    • インスタンスは「実体」とかを意味する技術用語。その名の通りゲーム内に存在する実態の情報。
    • ゲーム内で消滅するアクター(ボムチュウとか、ビン系アイテム)のアクターインスタンスは、ゲーム内で消滅するとメモリからも消滅する。
  • Heap, Heap Memory(ヒープメモリ)
    • プログラムにおける動的メモリ空間のこと。
    • データの入れ物の集まりで、それぞれの入れ物にはどんなデータが入るかは決まっていない。
      • 仕切りのない大きな箱のイメージ
    • データが必要になったとき、必要な分だけヒープメモリにデータを入れてあげる。必要になるヒープの大きさはデータによって様々。
    • 不要になったデータは、不要になったタイミングで捨てることで、ヒープメモリに空きを作ってあげる。
      • ダンジョンの各部屋の切り替わりでヒープメモリをうまく使ってあげることで、不要なデータは読み込まずに必要なデータだけ読み込んでいたりする。
    • 各メモリ空間にはアドレス(番地)が割り振られている。
    • プログラム的には、どのデータを使っているかをアドレスで管理することが多い。例えば、「今リンクが持ち上げているアクターはアドレス1F0630のものだ」など。

前提知識(アクターと動的メモリのしくみ)

  • 各アクターは、ゲーム内での実体である「アクターインスタンス」と、各アクターの情報定義である「アクターファイル」から構成される。
  • アクターインスタンスは、ゲーム内の位置情報等をもち、自分が何者であるかはどのアクターファイルに書いてあるかだけ知っている。
    • アクターインスタンス「俺が何者であるかはアドレス1F2A60のアクターファイルに書いてあるぜ」
  • 同じアクターファイルであれば複数のアクターインスタンス内で使いまわすことができる。
  • 逆に、一度部屋の中で生成されたアクターファイルのデータは、部屋の切り替えが行われるまで動的メモリ内に残り続ける。
    • と思っていたけど、もしかしたら部屋の中に対象アクターインスタンスがなければアクターファイルも解放されるかも。
    • 後述するボムチュウの例で思った。
    • アクターファイルの解放はもっと複雑かもしれない。
  • リンクがものを持ち上げると、どのアドレスのアクターを持ち上げているかが保持される。
  • リンクの移動にあわせて、アクターインスタンスの座標情報が毎フレーム更新される。

わかりやすいイメージ図

  • image.png参照

動的メモリのしくみ

  • 部屋が読み込まれると、部屋内のアクターを全て読み込む。宝箱や草、ツボ、もしかしたら地形とかもあるかも
    • 各部屋で読み込まれるアクターの順番は固定っぽい(じゃないとこのバグ自体破綻する気がするので)。
  • 部屋の中で新たなアクター(アイテムとか)が作られると、そのアクターに必要な動的メモリの空間を確保して、データを格納する。
    • 始めて作られたアクターであればアクターファイルとアクターインスタンスのセットで。そうでなければアクターインスタンスだけ。
    • 基本的に空いているメモリ空間に上から(番地の速い順から)埋めていくが、バクダンの「アクターファイルだけ」は例外的に離れたアドレスに格納される。
      • アクターインスタンスは他と同じで上から。
  • ロードゾーン(ある程度範囲のあるエリアっぽい)に入ると、前の部屋と並行して次の部屋のアクターを読み込み始める。
    • 完全にロードしきるまでは、動的メモリ領域の中に前後の部屋のデータがどちらも格納されている状態。
  • 次の部屋が完全にロードされると、前の部屋のデータと前の部屋で作られたアクターのデータが動的メモリから解放される。
  • この時、次の部屋のアクターが、前の部屋で作られたアクター分後ろ(番地でいうと遅い方に)ズレて格納される。
    • 独立していたバクダンのアクターファイルは無視されるっぽい。
    • 格納されるアドレスがズレること自体はヒープメモリとして何らおかしくない挙動のハズ。。。
  • 恐らくこのズレは次の部屋をロードしたタイミングで元に戻ると思う。また新たに作ったアクター分はズレが生じるのだとは思うが。。。

ドドンゴの洞窟でのSRMの例

  • First Room(いっぱいアクターを作る部屋)=火柱部屋
  • Second Room(アクターのアドレスをずらしてあげる部屋)=バクダンのある部屋

目的

  • バクダンのある部屋、バクダンの宝箱の、「ズレが生じていない状態での」アクターインスタンスの座標1F0640の、ひとつ前の座標1F0630
  • 宝箱の真下の草のアクターインスタンス(ズレなしで1E8DC0)を読み込ませる
  • 必要なアドレスのズレは16進数で7870
    • Windows計算機のプログラマーモードで1F0630 - 1E8DC0をしてみよう!

火柱部屋(FirstRoom)での前準備

以下のアクターを使ってアドレスをズラす

  • ムシのアクターファイル
  • ムシのアクターインスタンス×2
  • サカナのアクターファイル
  • サカナのアクターインスタンス×2
  • ボムチュウのアクターファイルのみ
  • バクダンのアクターインスタンス×1

バクダンは前述したとおりアクターファイルが無視されるので問題ないが、ボムチュウのアクターファイルだけを利用するために小細工しているっぽい。

  • ボムチュウ2個とサカナとムシで、動的メモリのアドレスを進めたあと、ボムチュウ3個めを出す
  • ボムチュウは衝突で爆発、サカナとムシは時間経過で消滅し、ボムチュウ3個めのアクターインスタンスだけ残す
  • ボムチュウのアクターファイルと3個めのアクターインスタンスの間にかなり広い範囲の空きメモリができるので、ズレに使う本来のアクターを出す
  • 末尾の方にある3個めのボムチュウのアクターインスタンスは勝手に消えるので、ボムチュウのアクターファイルだけ活用できる

バクダンのある部屋からスーパースライド

  • アドレスがズレた状態のバクダンのある部屋から、草をスーパースライドで持ち出す。
  • ただし、部屋の切り替わり時に「草をカメラに入れていない」ことが条件。カメラにアクターが入っていると、次の部屋のアクターとして更新されてしまうっぽい。
  • スーパースライド後のリンクは、「バクダンのある部屋(Second Room)の1F0630番地のアクターを持っている」状態だけ保持される
  • もちろん草のデータもある程度の範囲を持っているので、ズレなしバクダン宝箱のアドレス1F0640~にも影響する

草(無)を持った状態でバクダンのある部屋へ戻る

  • 再度、バクダンのある部屋(Second Room)へのロードゾーンへ入る
  • 釣り橋部屋のデータと並行してバクダンのある部屋のデータがロードされる
  • リンクは相変わらず1F0630のアクターインスタンスを持っていることになっている
  • リンクが動けばこの草(無)のアクターインスタンスの座標情報を更新することになるが、すでにバクダン部屋の1F0640の宝箱はロードされている
  • 結果、草(無)の位置情報はバクダン部屋の宝箱の情報を書き換える
    • アドレスの向き先がすでに「バクダンの宝箱」であるため

こんな感じ?

随時更新していきたい。。。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment