Tier D overview
Tier D of the A–F ladder - the only data tier that changes a byte count. It's the variable-length cousin of tier C. Start at the series index for the same-size-vs-relocate editing model.

Mechanism at a glance

Target
a MAN record whose length changes - the 0x3F scene-transition's inline destination name
Engine
legaia_asset::man_edit: rebuild the decompressed MAN, apply the resize, fix every disturbed offset
Fix-ups
partition tables + partition-2 record-offset table + u24_at_28 + intra-record relative-jump deltas + the external descriptor size word
Bound
the recompressed stream must still fit the asset footprint (or the scene is skipped); disc total size never changes
Edit class
relocate / variable-length - footprint-bounded
Oracles
door_patch_real.rs · starting_bag_real.rs

The reversing: everything a resize disturbs

A door's destination is reached through the MAN's partition-2 record-offset table, and the destination scene's name is stored inline in that record. Re-pointing the door at a scene with a longer or shorter name changes the record's byte length - and the moment a record's length changes, every structure that encodes a position past it is wrong. Making the edit safe meant enumerating, from the MAN layout, the complete set of things a resize moves: the partition tables, the partition-2 record-offset table that indexes destinations, a u24 length field at +0x28, the relative-jump deltas inside records that straddle the edit, and the external asset descriptor's size word. Miss one and the script desyncs or the door points into garbage. The relocation engine fixes all of them in one rebuild - see MAN relocation.

A record grows; offset tables and deltas are fixed up in one rebuild before records door rec later records after records door rec (longer name) shifted +Δ fix-ups: partition tables · partition-2 record-offset table · u24_at_28 · intra-record jump deltas · descriptor size word
The door record grows by Δ; everything after it shifts, and five classes of offset are corrected in one rebuild. If the recompressed result won't fit the footprint, the scene is left vanilla rather than corrupted.

Worked examples

Doors (scene transitions)

Re-pointing a 0x3F transition at a new destination is the canonical relocation: the inline name resizes the record, the relocation engine fixes the offset tables and deltas, and the recompressed MAN stays within footprint. Coupling can be bidirectional (a door and its return both move) or one-way.

High-capacity starting bag (variant G)

The same machinery powers a different shape: rather than re-point a record, the starting-bag feature inserts a guarded grant block into the opening scene's script - a story-flag test (0x70), a run of GIVE_ITEM ops (0x39), and a flag set (0x50) so it fires exactly once. That byte-insert is a length change like any other, relocated by man_edit::apply_insertions, which lifts the seven-slot cap of the same-size new-game seed path.

Composition

Relocation is the one technique that changes byte counts, so it's the most constrained: an edit either fits the asset footprint after recompression or the scene is skipped, and the disc's total size is invariant either way (no LBA, PROT TOC, or ISO 9660 record ever moves). Because same-size passes (tier C) leave descriptor offsets fixed, a relocation pass over a scene composes with them as long as it runs on the stable footprint - the boundary the budget is always read from.

Mods using this technique

  • Doors (scene transitions) (--doors) - re-point a transition, resizing its inline destination name.
  • High-capacity starting bag (--starting-items, variant G) - insert a guarded grant block into the opening MAN.

Adding a tier-D mod: enumerate every offset/table/delta a resize disturbs from the container layout, fix them in one rebuild, keep the recompressed stream within the asset footprint (skip on overflow), and add a disc-gated oracle that re-decodes the patched image.

See also