Place names Confirmed
"Rim Elm", "Sol Tower", "Ancient Wind Cave" - a place name shows up in three spots while you play: the quick-travel list, the label floating over the world map, and the banner that slides in when you walk into a town. Each of those reads its own copy off the disc. There is no single name table, which is why a rename that only edits the well-known executable table leaves the world map and the entry banner still saying the old name.
At a glance
- Magic
- none - three carriers: a static table in
SCUS_942.54, the trailer of each kingdom MAN, and section 2 of each scene MAN - Where
- site 1:
0x80073B18(16 cells); site 2: pointerDAT_80073EE0into the kingdom MAN trailer (29 records); site 3:_DAT_801C6EA0into the scene MAN - Parsers
legaia_asset::worldmap_menu(site 1),legaia_asset::place_names(sites 2 and 3); editorlegaia-patcher --rename-locationedits all three together- Confidence
- Confirmed - layouts read off the disc, both MAN consumers pinned live, and a rename read back out of RAM on a patched disc
- Used by
- World overview (quick-travel table), Game world, Randomizer, ROM patcher
The three carriers
One name, three displays, three byte layouts. The shared cap for a rename is 23 characters - the tightest of the three.
| Site | What it draws | Carrier | Shape |
|---|---|---|---|
| 1 | the quick-travel / Door-of-Wind destination list | SCUS_942.54 0x80073B18 | 16 fixed 0x20-byte NUL-padded cells |
| 2 | the labels drawn over the world map at each place's position | the trailer of every kingdom MAN (map01 / map02 / map03) | [u8 count][count x 0x20 record] |
| 3 | the banner on entering a scene, and the save-screen location row | each scene MAN's section 2 | bare strlen + 1 NUL-terminated string |
The three name spaces are not the same set. Site 1 holds 16 names; site 2 holds 29, naming 14 places the quick-travel menu has no room for (Hunter's Spring, Mt. Rikuroa, Snowdrift Cave, the Voz Forests, Zeto's Dungeon, Shadow Gate, Sol Tower, Nivora Ravine and so on). Site 3 holds one name per scene bundle, so a multi-scene place repeats its name - Sol Tower across 13 bundles, Rim Elm across 7. Near-miss names are genuinely distinct strings: site 1's "Sol" is not site 2's "Sol Tower".
Site 2 - the world-map location table
MAN section 5 is the chain terminator in every scene bundle, so its "body" is whatever trails the chain. In the three kingdom MANs that trailing data is the location table, and the MAN walker installs a pointer to its count byte (how we know). All three kingdom MANs carry a byte-identical copy of the whole 29-record table, filtered by region at draw time - so a rename must edit every kingdom MAN, not just the one whose continent the place sits on.
| Offset | Type | Field |
|---|---|---|
+0x00 | u8 | region - 0 = Drake, 1 = Sebucus, 2 = Karisto |
+0x01 | u8 | map x (world coordinate = x << 7) |
+0x02 | u8 | map y (world coordinate = y << 7) |
+0x03 | u16 | discovery flag, queried through FUN_8003CE64 (0x0484..0x04A0; the two element caves share 0x048E and differ by region) |
+0x05 | 3 bytes | reserved, zero across the retail corpus |
+0x08 | 0x18 bytes | name, NUL-padded ASCII |
The world-map band's per-frame label pass draws each record whose region matches the current kingdom and whose discovery flag is set (or the show-all debug flag is on): project the map position to the screen, draw the name, measure it, underline it. So the name is drawn at the place's own map position, gated on having discovered it (how we know).
Site 3 - the scene display name
MAN section 2's body is the scene's display name. The MAN walker installs the body pointer, and the field
overlay's scene-entry state machines hand it to the banner panel script, latching it in a global buffer on the
way. The body is not padded - exactly strlen + 1 bytes - so a longer name means
resizing the section.
The menu overlay reads the latched name twice, both times for the save screen: once to draw the save-slot location row, once to copy it into the save block's location field. That is why a save state captured mid-scene holds the last scene entered in that buffer: it is filled at save time from the latch, not per frame.
How site 3 was pinned
Statically the chain ends at a panel script, one indirection short of proof. It was closed live: a breakpoint on the glyph renderer FUN_80036888 across an overworld-into-town transition captures the banner draw arriving with a0 == _DAT_801C6EA0, spelling the scene's section-2 name. Probe: scripts/pcsx-redux/autorun_location_banner_source.lua.
How we know
| Function | Address | What it proves | Dump / probe |
|---|---|---|---|
| MAN walker | FUN_8003AEB0 | Installs the site-2 table pointer (DAT_80073EE0) and the site-3 body pointer (_DAT_801C6EA0) | funcs/8003aeb0.txt |
| World-map label pass | 0x801CEBB6..0x801CEC30; discovery query FUN_8003CE64, projection FUN_8003D368, glyph draw FUN_80036888, measure FUN_80035F04 | Per-record region filter, discovery gate (debug show-all _DAT_8007B868), draw-at-map-position | funcs/overlay_world_map_top_801ce9c4.txt |
| Banner latch | state machines 0x801EE634 / 0x801EAC7C / 0x801EEAE4 | The section-2 pointer handed to the banner panel script, latched in _DAT_8007B44C | field-overlay dumps; live probe autorun_location_banner_source.lua |
| Save-screen readers | 0x801E1D9C (row draw), 0x801E1A28 (copy to SC block +0x200) | The latch's two menu-overlay consumers - both save-screen, neither per-frame | menu-overlay dumps |
| Patched-disc read-back | - | A rename re-parses at every site; resized banner + edited world-map table read back out of live RAM | crates/patcher/tests/place_names_real.rs |
Editing a name
- Site 1 - same-size overwrite of a 32-byte cell, zero-padded.
- Site 2 - same-size overwrite of the record's 24-byte name field, then an LZS re-pack of each kingdom MAN.
- Site 3 - resize the section. No relocation work is needed: the partition tables and
u24_at_28address the region before section 0, and sections 3..5 are reached by walking the chain, so rewriting section 2's length prefix moves every later section correctly by construction. What must move is the MAN's decompressed size in the scene bundle's descriptor word (scene_asset_table::encode_size_word). - Every scene MAN is the last asset in its bundle, so the re-packed stream can grow into the entry's sector padding (smallest headroom in the corpus ~430 bytes). Clamp the budget to the entry's true footprint, never to an over-reading length.
- Ten scene MANs carry an untranslated Shift-JIS name in section 2 (the ending scenes plus
other7) and seven carry an empty one; both read as "no name".