Tier D - variable-length relocation
Every other data tier holds byte counts constant so nothing moves. This is the one where the edit's meaning forces a length change - a scene-transition door carries its destination's name inline, so re-pointing it at a differently-named scene resizes the record. That's only safe if you can rebuild the decompressed script, fix every internal offset the resize disturbs, and still land inside the asset's on-disc footprint.
Mechanism at a glance
- Target
- a MAN record whose length changes - the
0x3Fscene-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.
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.