Skip to content

Declare dScMgBase_c slot 31 (Virtual7C) across the minigame family - #2106

Merged
andrewboudreau merged 1 commit into
mainfrom
cpp/minigame-slot31
Sep 1, 2026
Merged

Declare dScMgBase_c slot 31 (Virtual7C) across the minigame family#2106
andrewboudreau merged 1 commit into
mainfrom
cpp/minigame-slot31

Conversation

@andrewboudreau

Copy link
Copy Markdown
Collaborator

Slot 31 of the 18-35 keystone range, stacked on #2102 (slot 30). Review only the top commit; the rest is the stack below.

What lands

Thirty-two vtables gain their thirty-second word. Seven override the slot; three need a declaration (dScMgD3DBase_c, dScMgAmida_c, dScMgSmartball_c) and the other four — dScMgJump_c, dScMgJump2_c, dScMgTrampoline_c, dScMgTrampoline2_c — inherit dScMgD3DBase_c's body. No occupied-slot trap.

romdata_check vs slot 30:  verifiedBytes 35412 -> 35416  (+4)
                           partialBytes  11624 -> 11748  (+124)

128 bytes = 32 tables x one word. _ZTV14dScMgD3DBase_c is the one table already VERIFIED, so its word lands in the verified pool and the other thirty-one land in the partial one. differs 6, partial 253, verified 465, symbols 1246, totalRecords 7560 — all unchanged, and no symbol changed verdict.

rombuild -j16 --no-rom: 11,088/11,088 reproducing, 106/106 exact, 100.000000%, ROM-build analysis PASS.

The part worth reading: the borrowed names never applied

Slots 18-30 carry include/dActor_c.h's names because they sit at dActor_c's indices. At 31 that argument runs out — dActor_c.h stops at slot 30 — and reaching the end of the borrowed table is what makes the borrowing legible:

fBase_c -> dBase_c -> dActor_c                  (adds slots 18-30)
fBase_c -> dBase_c -> dScene_c -> dScMgBase_c   (adds slots 18-35)

include/fBase_c.h:130-146 declares slots 0-15 plus the destructor pair at 16/17; dBase_c adds no virtual; dScene_c declares nothing above slot 11. The two branches are siblings that each begin appending at 18. dScMgBase_c is a scene, not an actor, and is not a dActor_c descendant at any depth. The indices coincide; nothing was inherited.

That is one root cause for three findings this campaign recorded separately — the ROM contradicting the name at slot 26, at 29, and at both halves of it at 30. It applies to all eighteen, not to those three.

Kill specifically came from _ZN10dBgActor_c4KillEv (ov002:0x020ee55c) — a genuine mangled ROM symbol, but dBgActor_c derives from dActor_c. It is a nephew branch, one fork further away still, and Kill is the one new virtual it appends at its slot 31. The name was carried across a fork to an index that does not exist on the branch it was taken from.

So this slot takes Virtual7C — the spelling fBase_c already uses (Virtual34, Virtual38), the family uses (Virtual50/08/10/18), and slots 33/34/35 are already recorded under. No new convention, and verified free tree-wide.

Whether to retro-rename 18-30 is yours to call, not this PR's. What this PR declines to do is add a nineteenth borrowed name on top of the explanation.

What the slot does

Three read-modify-writes on the sub engine's BG1CNT at 0x0400100a leave it holding exactly the class's own base bits — 0x10 base, 0x800 D3DBase, 4 Amida/Smartball — then the layer scroll is reset, BG1's bit is cleared from the sub BG-enable shadow that slot 30 restores the sub DISPCNT from, and a language-indexed character file plus the shared screen map (file 0x5b) are installed. dScMgD3DBase_c wraps that in the VRAM bank juggling only the 3D minigames need.

It builds the touch-screen background, from BeforeInitResources, which calls it last and discards the result. It destroys nothing — the second reason not to keep the name.

Arity measured at the only in-family dispatch site (ov004:0x020b0a0c): mov r0,r4; ldr r1,[r0]; ldr r1,[r1,#0x7c]; blx r1, so r1 is the loaded pointer and cannot also be an argument. Scanning arm9 + all 103 overlays for the ldr/blx pair at +0x7c finds 39 sites; the other 38 are dBgActor_c's Kill on the other branch. Return type int is a hint, not a pin — the fourth consecutive slot no body pins.

Also in here

  • Ninth recovered name: correction, eighth on dScMgD3DBase_c, and the first wrong in both halves: ov006:0x020e72c0 was labelled dScMgTrampoline2_c_Kill and included that header. Five vtables reference the address, so the class is dScMgD3DBase_c's; include and this cast move with it. Each wrong line is kept visible with the correction beside it.
  • Prose re-counted in four headers. In dScMgAmida_c.h, Unk36 moves from 31 to 32 — one index closer to its true slot 36. _ZTV12dScMgAmida_c stays DIFFERS until slot 35 lands; expected and unchanged.
  • A deferred cleanup is recorded, not done. The base bodies for slots 31, 32 and 33 all live in one src_tu candidate unit, src_tu/actors/unit_ov004_020b0a38.cpp, which still names them func_ov004_*. Nothing reads it today — "status": "text-verified", not enrolled, src_tu/ is not in the ROM build, check_src_tu_compiles 97/97 green, and tiers_ratchet only follows "promoted" entries — and it goes stale again at 32 and 33. Regenerate once, through tubuild, after slot 33. Noted in notes/dScMgBase_c-slots-18-35.md.

Gates

check_dead_references clean · port_refcheck 405/405 · check_header_offsets --changed origin/main 7 headers, 0 mismatched · check_src_tu_compiles 97/97 · check_duplicate_sources 11038 stems, none doubled · langmode ratchet PASS.

Four slots left: 32-35.

🤖 Generated with Claude Code

https://claude.ai/code/session_01QhhAeJwXBnfPp7B5DNjCwh

Slot 31 of the 18-35 keystone range. Thirty-two vtables gain their
thirty-second word; seven override it, three of those need a declaration
(dScMgD3DBase_c, dScMgAmida_c, dScMgSmartball_c) and the other four --
dScMgJump_c, dScMgJump2_c, dScMgTrampoline_c, dScMgTrampoline2_c -- all
inherit dScMgD3DBase_c's body. No occupied-slot trap.

  romdata_check vs slot 30:  verifiedBytes 35412 -> 35416  (+4)
                             partialBytes  11624 -> 11748  (+124)
  128 bytes = 32 tables x one word, split the usual way: _ZTV14dScMgD3DBase_c
  is the one table already VERIFIED so its word lands in the verified pool.
  Every count -- differs 6, partial 253, verified 465, symbols 1246,
  totalRecords 7560 -- is unchanged, and no symbol changed verdict.

  rombuild -j16 --no-rom: 11,088/11,088 reproducing, 106/106 exact,
  100.000000% of compared bytes, ROM-build analysis PASS.

THE NAME IS DELIBERATELY A NON-NAME, AND REACHING THIS SLOT IS WHY

Slots 18-30 carry include/dActor_c.h's names because they sit at dActor_c's
indices. That was the whole of the argument, and at 31 it runs out:
dActor_c.h stops at slot 30. Reaching the end of the borrowed table is what
finally makes the borrowing legible.

  fBase_c -> dBase_c -> dActor_c                  (adds slots 18-30)
  fBase_c -> dBase_c -> dScene_c -> dScMgBase_c   (adds slots 18-35)

include/fBase_c.h:130-146 declares slots 0-15 plus the destructor pair at
16/17. dBase_c adds no virtual of its own. dScene_c declares nothing above
slot 11. So the two branches are SIBLINGS that each begin appending at 18 --
dScMgBase_c is a scene, not an actor, and it is not a dActor_c descendant at
any depth. Two independent extensions of the same 18-slot base land on the
same indices for the same reason two books have a page 19. Nothing was
inherited; the indices merely coincide.

That is the single root cause behind three findings this campaign recorded
separately: the ROM contradicting the name at slot 26, at 29, and at both
halves of it at 30. It applies to all eighteen, not to those three.

Whether to retro-rename 18-30 is not this commit's call. What this commit
will not do is add a nineteenth borrowed name on top of the explanation.

WHERE `Kill` CAME FROM

The bodies said `Kill`, and ov002 really does carry _ZN10dBgActor_c4KillEv
at 0x020ee55c -- a genuine mangled ROM symbol. But dBgActor_c derives FROM
dActor_c: it is a nephew of this branch, one fork further away still, and
Kill is the one new virtual it appends at ITS slot 31. The name was carried
across a fork, to an index that does not even exist on the branch it was
taken from. Nothing in the cartridge names this function -- its RTTI carries
class names only.

Virtual7C is what fBase_c already spells for exactly this situation
(Virtual34, Virtual38), what the family spells at Virtual50/08/10/18, and
what slots 33, 34 and 35 are already recorded under in
notes/dScMgBase_c-slots-18-35.md. It costs no new convention and it is free
tree-wide. `_ZN11dScMgBase_c9Virtual7CEv`.

WHAT THE SLOT ACTUALLY DOES

All four bodies are one shape. Three read-modify-writes on the sub engine's
BG1CNT at 0x0400100a (`& 0x43`, `| X`, `& ~0x40`, `& ~3`) leave the register
holding exactly X -- priority 0, no mosaic, and the class's own base bits:
0x10 in the base, 0x800 in dScMgD3DBase_c, 4 in both dScMgAmida_c and
dScMgSmartball_c. Then SetSubBg1Offset(0, 0) resets the layer's scroll,
`data_0209d454 &= ~2` clears BG1's bit in the sub BG-enable shadow that slot
30 restores the sub DISPCNT from, and two LoadCompressedFileAt calls install
a language-indexed character file at G2S::GetBG1CharPtr() and the shared
screen map, file 0x5b, at G2S::GetBG1ScrPtr(). dScMgD3DBase_c wraps that in
the VRAM bank juggling only the 3D minigames need.

It builds this minigame's touch-screen background. It destroys nothing, which
is the second reason not to keep the name.

BeforeInitResources (ov004:0x020b0930) calls it last and returns a literal 1
without touching the result. Setup, at scene construction.

ARITY AND RETURN TYPE, MEASURED

No explicit parameters. Scanning arm9 and all 103 overlays for the dispatch
PAIR -- `ldr rN,[rM,#0x7c]` immediately followed by `blx rN`, not any load at
+0x7c -- finds 39 sites, of which exactly one is in ov004 or ov006:
ov004:0x020b0a0c, inside BeforeInitResources. It reads
`mov r0,r4; ldr r1,[r0]; ldr r1,[r1,#0x7c]; blx r1`, so r1 is the loaded
pointer and cannot also be a second argument. The other thirty-eight are in
ov002, ov015, ov018, ov027, ov064, ov079, ov081 and ov098 -- dBgActor_c's
Kill, on the other branch, which is a further check on the fork above.

Return type `int` is a HINT, the fourth consecutive slot no body pins. The
base sets r0 to #0 on its second instruction -- as SetSubBg1Offset's first
argument, before anything reads it -- and never assigns a result. The one
caller discards it.

ALSO IN THIS CHANGE

  * Ninth `recovered name:` correction, eighth on dScMgD3DBase_c, and the
    first wrong in BOTH halves: ov006:0x020e72c0 was labelled
    dScMgTrampoline2_c_Kill and included that header. Five vtables reference
    the address, so the class is dScMgD3DBase_c's; the include and the `this`
    cast move with it. Each wrong line is kept visible with the correction
    beside it.
  * Prose re-counted in dScMgBase_c.h (tables now stop at 31),
    dScMgD3DBase_c.h (one undeclared slot left, 33), dScMgSingle3DBase_c.h
    (32-slot prefix) and dScMgAmida_c.h, where Unk36 moves from 31 to 32 --
    one index closer to its true slot 36. _ZTV12dScMgAmida_c stays DIFFERS
    until slot 35 lands; that is expected and unchanged.
  * A deferred cleanup is recorded rather than done. The base bodies for
    slots 31, 32 and 33 all live in one src_tu candidate unit,
    src_tu/actors/unit_ov004_020b0a38.cpp, which still names them
    func_ov004_*. Nothing reads it today -- the unit is "text-verified", not
    enrolled, src_tu/ is not in the ROM build, check_src_tu_compiles is 97/97
    green and tiers_ratchet only follows "promoted" entries -- and it will go
    stale again at 32 and at 33. Regenerate it once, through tubuild, after
    slot 33.

Gates: check_dead_references clean, port_refcheck 405/405,
check_header_offsets --changed origin/main 7 headers 0 mismatched,
check_src_tu_compiles 97/97, check_duplicate_sources 11038 stems none
doubled, langmode ratchet PASS.

Four slots left: 32-35.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QhhAeJwXBnfPp7B5DNjCwh
@andrewboudreau andrewboudreau added the attribution-override Maintainer accepts this PR's contributor-credit changes; validation reports them as warnings label Aug 31, 2026
@tangos-validator

tangos-validator Bot commented Aug 31, 2026

Copy link
Copy Markdown

✅ PR validation — Passed

Committed merge passes; 1 contributor credit reassignment(s) noted, not a blocker.

Full merge validation

Check Result
Committed test merge yes
Byte-verified functions 10,781 / 11,347 (95.01%, +0)
Byte-verified code bytes 2,004,460 / 2,211,124 (90.65%, +0)
Claimed, not byte-verified 436 functions, 101,220 bytes (+0)
Perfect source moves 0 R100
Enrolled ranges (delinks complete) 11,059 functions, 2,053,148 bytes (92.86%, +0) -- differs from byte-verified by +278
Contributor credit 0 added, 1 changed, 0 lost
Relocation check 303 checked; 303 VERIFIED
Port reference check 405 checked; 0 stale
Module fidelity 106/106 exact; 100.000000% compared bytes
Code linked from verified source 11,088 functions, 2,067,148 bytes (93.49%)
Module bytes from source 2,067,148 / 3,049,600 (67.8%); 811,492 (26.6%) are data no delink entry reaches
ROM data reproduced from source 465 symbol(s) exact, 253 partial, 6 differ

Contributor credit moved (1)

Function Source Before After
ov004:0x020b2880 src/func_ov004_020b2880.c -> src/_ZN11dScMgBase_c9Virtual7CEv.c tangosdev andrewboudreau

Byte-verified means the range carries complete in a delinks.txt, so the ROM build compiled it and compared it to the cartridge. The 436 claimed functions have a src/ file named after the symbol with no NONMATCHING banner, and nothing compiles them -- dsd fills their addresses with the ROM's own bytes. Both together are the 11,217 this project calls matched.

Warnings: contributor attribution changed, not a blocker (1 changed, 0 lost -- src/_ZN11dScMgBase_c9Virtual7CEv.c: tangosdev -> andrewboudreau).

Per-file link-check detail

All 193 changed file(s) compile to the ROM byte-for-byte with correct relocation targets.

File Symbol Result Slots checked
src/_ZN10dScMgCup_c13InitResourcesEv.cpp _ZN10dScMgCup_c13InitResourcesEv ✅ verified 1
src/_ZN10dScMgCup_c6RenderEv.cpp _ZN10dScMgCup_c6RenderEv ✅ verified 1
src/_ZN10dScMgCup_c8BehaviorEv.cpp _ZN10dScMgCup_c8BehaviorEv ✅ verified 1
src/_ZN10dScMgCup_cD0Ev.cpp _ZN10dScMgCup_cD0Ev ✅ verified 1
src/_ZN10dScMgCup_cD1Ev.cpp _ZN10dScMgCup_cD1Ev ✅ verified 1
src/_ZN11dScMgBase_c15OnHitByMegaCharEv.cpp _ZN11dScMgBase_c15OnHitByMegaCharEv ✅ verified 1
src/_ZN11dScMgBase_c15graphCallback_c14GraphCallback0Ev.cpp _ZN11dScMgBase_c15graphCallback_c14GraphCallback0Ev ✅ verified 1
src/_ZN11dScMgBase_c15graphCallback_c14GraphCallback1Ev.cpp _ZN11dScMgBase_c15graphCallback_c14GraphCallback1Ev ✅ verified 1
src/_ZN11dScMgBase_c15graphCallback_c14GraphCallback2Ev.cpp _ZN11dScMgBase_c15graphCallback_c14GraphCallback2Ev ✅ verified 1
src/_ZN11dScMgBase_c15graphCallback_c14GraphCallback3Ev.cpp _ZN11dScMgBase_c15graphCallback_c14GraphCallback3Ev ✅ verified 1
src/_ZN11dScMgBase_c16OnAimedAtWithEggEv.cpp _ZN11dScMgBase_c16OnAimedAtWithEggEv ✅ verified 1
src/_ZN11dScMgBase_c19OnHitFromUnderneathEv.cpp _ZN11dScMgBase_c19OnHitFromUnderneathEv ✅ verified 1
src/_ZN11dScMgBase_c25OnAimedAtWithEggReturnVecEv.cpp _ZN11dScMgBase_c25OnAimedAtWithEggReturnVecEv ✅ verified 1
src/_ZN11dScMgBase_c8OnPushedEv.cpp _ZN11dScMgBase_c8OnPushedEv ✅ verified 1
src/_ZN11dScMgBase_c9Virtual7CEv.c _ZN11dScMgBase_c9Virtual7CEv ✅ verified 1
src/_ZN11dScMgBase_cC2Ev.cpp _ZN11dScMgBase_cC2Ev ✅ verified 1
src/_ZN11dScMgBase_cD0Ev.cpp _ZN11dScMgBase_cD0Ev ✅ verified 1
src/_ZN11dScMgBase_cD1Ev.cpp _ZN11dScMgBase_cD1Ev ✅ verified 1
src/_ZN11dScMgBase_cD2Ev.cpp _ZN11dScMgBase_cD2Ev ✅ verified 1
src/_ZN11dScMgCoin_c13InitResourcesEv.cpp _ZN11dScMgCoin_c13InitResourcesEv ✅ verified 1
src/_ZN11dScMgCoin_c13OnYoshiTryEatEi.cpp _ZN11dScMgCoin_c13OnYoshiTryEatEi ✅ verified 1
src/_ZN11dScMgCoin_c6RenderEv.cpp _ZN11dScMgCoin_c6RenderEv ✅ verified 1
src/_ZN11dScMgCoin_c8BehaviorEv.cpp _ZN11dScMgCoin_c8BehaviorEv ✅ verified 1
src/_ZN11dScMgCoin_cD0Ev.cpp _ZN11dScMgCoin_cD0Ev ✅ verified 1
src/_ZN11dScMgCoin_cD1Ev.cpp _ZN11dScMgCoin_cD1Ev ✅ verified 1
src/_ZN11dScMgJump_c13InitResourcesEv.cpp _ZN11dScMgJump_c13InitResourcesEv ✅ verified 1
src/_ZN11dScMgJump_c13OnTurnIntoEggEi.cpp _ZN11dScMgJump_c13OnTurnIntoEggEi ✅ verified 1
src/_ZN11dScMgJump_c16CleanupResourcesEv.cpp _ZN11dScMgJump_c16CleanupResourcesEv ✅ verified 1
src/_ZN11dScMgJump_c6RenderEv.cpp _ZN11dScMgJump_c6RenderEv ✅ verified 1
src/_ZN11dScMgJump_c8BehaviorEv.cpp _ZN11dScMgJump_c8BehaviorEv ✅ verified 1
src/_ZN11dScMgJump_cD0Ev.cpp _ZN11dScMgJump_cD0Ev ✅ verified 1
src/_ZN11dScMgJump_cD1Ev.cpp _ZN11dScMgJump_cD1Ev ✅ verified 1
src/_ZN12dScMg3DEsp_c13InitResourcesEv.cpp _ZN12dScMg3DEsp_c13InitResourcesEv ✅ verified 1
src/_ZN12dScMg3DEsp_c13OnYoshiTryEatEi.cpp _ZN12dScMg3DEsp_c13OnYoshiTryEatEi ✅ verified 1
src/_ZN12dScMg3DEsp_c16CleanupResourcesEv.cpp _ZN12dScMg3DEsp_c16CleanupResourcesEv ✅ verified 1
src/_ZN12dScMg3DEsp_c6RenderEv.cpp _ZN12dScMg3DEsp_c6RenderEv ✅ verified 1
src/_ZN12dScMg3DEsp_c8BehaviorEv.cpp _ZN12dScMg3DEsp_c8BehaviorEv ✅ verified 1
src/_ZN12dScMg3DEsp_cD0Ev.cpp _ZN12dScMg3DEsp_cD0Ev ✅ verified 1
src/_ZN12dScMg3DEsp_cD1Ev.cpp _ZN12dScMg3DEsp_cD1Ev ✅ verified 1
src/_ZN12dScMgAmida_c13InitResourcesEv.cpp _ZN12dScMgAmida_c13InitResourcesEv ✅ verified 1
src/_ZN12dScMgAmida_c21AfterCleanupResourcesEj.cpp _ZN12dScMgAmida_c21AfterCleanupResourcesEj ✅ verified 1
src/_ZN12dScMgAmida_c5Unk36Ev.cpp _ZN12dScMgAmida_c5Unk36Ev ✅ verified 1
src/_ZN12dScMgAmida_c6RenderEv.cpp _ZN12dScMgAmida_c6RenderEv ✅ verified 1
src/_ZN12dScMgAmida_c8BehaviorEv.cpp _ZN12dScMgAmida_c8BehaviorEv ✅ verified 1
src/_ZN12dScMgAmida_c9Virtual7CEv.cpp _ZN12dScMgAmida_c9Virtual7CEv ✅ verified 1
src/_ZN12dScMgAmida_cD0Ev.cpp _ZN12dScMgAmida_cD0Ev ✅ verified 1
src/_ZN12dScMgAmida_cD1Ev.cpp _ZN12dScMgAmida_cD1Ev ✅ verified 1
src/_ZN12dScMgJump2_c13InitResourcesEv.cpp _ZN12dScMgJump2_c13InitResourcesEv ✅ verified 1
src/_ZN12dScMgJump2_c16CleanupResourcesEv.cpp _ZN12dScMgJump2_c16CleanupResourcesEv ✅ verified 1
src/_ZN12dScMgJump2_c6RenderEv.cpp _ZN12dScMgJump2_c6RenderEv ✅ verified 1
src/_ZN12dScMgJump2_c8BehaviorEv.cpp _ZN12dScMgJump2_c8BehaviorEv ✅ verified 1
src/_ZN12dScMgJump2_cD0Ev.cpp _ZN12dScMgJump2_cD0Ev ✅ verified 1
src/_ZN12dScMgJump2_cD1Ev.cpp _ZN12dScMgJump2_cD1Ev ✅ verified 1
src/_ZN12dScMgLuigi_c13InitResourcesEv.cpp _ZN12dScMgLuigi_c13InitResourcesEv ✅ verified 1
src/_ZN12dScMgLuigi_c21AfterCleanupResourcesEj.cpp _ZN12dScMgLuigi_c21AfterCleanupResourcesEj ✅ verified 1
src/_ZN12dScMgLuigi_c6RenderEv.cpp _ZN12dScMgLuigi_c6RenderEv ✅ verified 1
src/_ZN12dScMgLuigi_c8BehaviorEv.cpp _ZN12dScMgLuigi_c8BehaviorEv ✅ verified 1
src/_ZN12dScMgLuigi_cD0Ev.cpp _ZN12dScMgLuigi_cD0Ev ✅ verified 1
src/_ZN12dScMgLuigi_cD1Ev.cpp _ZN12dScMgLuigi_cD1Ev ✅ verified 1
src/_ZN12dScMgPanel_c13InitResourcesEv.cpp _ZN12dScMgPanel_c13InitResourcesEv ✅ verified 1
src/_ZN12dScMgPanel_c6RenderEv.cpp _ZN12dScMgPanel_c6RenderEv ✅ verified 1
src/_ZN12dScMgPanel_c8BehaviorEv.cpp _ZN12dScMgPanel_c8BehaviorEv ✅ verified 1
src/_ZN12dScMgPanel_cD0Ev.cpp _ZN12dScMgPanel_cD0Ev ✅ verified 1
src/_ZN12dScMgPanel_cD1Ev.cpp _ZN12dScMgPanel_cD1Ev ✅ verified 1
src/_ZN12dScMgSlot1_c13InitResourcesEv.cpp _ZN12dScMgSlot1_c13InitResourcesEv ✅ verified 1
src/_ZN12dScMgSlot1_c15OnHitByMegaCharEv.cpp _ZN12dScMgSlot1_c15OnHitByMegaCharEv ✅ verified 1
src/_ZN12dScMgSlot1_c19OnHitFromUnderneathEv.cpp _ZN12dScMgSlot1_c19OnHitFromUnderneathEv ✅ verified 1
src/_ZN12dScMgSlot1_c6RenderEv.cpp _ZN12dScMgSlot1_c6RenderEv ✅ verified 1
src/_ZN12dScMgSlot1_c9betIcon_c6RenderEv.cpp _ZN12dScMgSlot1_c9betIcon_c6RenderEv ✅ verified 1
src/_ZN12dScMgSlot1_c9betIcon_c8BehaviorEv.cpp _ZN12dScMgSlot1_c9betIcon_c8BehaviorEv ✅ verified 1
src/_ZN12dScMgSlot1_cD0Ev.cpp _ZN12dScMgSlot1_cD0Ev ✅ verified 1
src/_ZN12dScMgSlot1_cD1Ev.cpp _ZN12dScMgSlot1_cD1Ev ✅ verified 1
src/_ZN12dScMgSlot3_c13InitResourcesEv.cpp _ZN12dScMgSlot3_c13InitResourcesEv ✅ verified 1
src/_ZN12dScMgSlot3_c6RenderEv.cpp _ZN12dScMgSlot3_c6RenderEv ✅ verified 1
src/_ZN12dScMgSlot3_c8BehaviorEv.cpp _ZN12dScMgSlot3_c8BehaviorEv ✅ verified 1
src/_ZN12dScMgSlot3_cD0Ev.cpp _ZN12dScMgSlot3_cD0Ev ✅ verified 1
src/_ZN12dScMgSlot3_cD1Ev.cpp _ZN12dScMgSlot3_cD1Ev ✅ verified 1
src/_ZN12dScMgSound_c13InitResourcesEv.cpp _ZN12dScMgSound_c13InitResourcesEv ✅ verified 1
src/_ZN12dScMgSound_c6RenderEv.cpp _ZN12dScMgSound_c6RenderEv ✅ verified 1
src/_ZN12dScMgSound_c8BehaviorEv.cpp _ZN12dScMgSound_c8BehaviorEv ✅ verified 1
src/_ZN12dScMgSound_cD0Ev.cpp _ZN12dScMgSound_cD0Ev ✅ verified 1
src/_ZN12dScMgSound_cD1Ev.cpp _ZN12dScMgSound_cD1Ev ✅ verified 1
src/_ZN13dScMgFlower_c13InitResourcesEv.cpp _ZN13dScMgFlower_c13InitResourcesEv ✅ verified 1
src/_ZN13dScMgFlower_c6RenderEv.cpp _ZN13dScMgFlower_c6RenderEv ✅ verified 1
src/_ZN13dScMgFlower_c8BehaviorEv.cpp _ZN13dScMgFlower_c8BehaviorEv ✅ verified 1
src/_ZN13dScMgFlower_cD0Ev.cpp _ZN13dScMgFlower_cD0Ev ✅ verified 1
src/_ZN13dScMgFlower_cD1Ev.cpp _ZN13dScMgFlower_cD1Ev ✅ verified 1
src/_ZN13dScMgMemory_c13InitResourcesEv.cpp _ZN13dScMgMemory_c13InitResourcesEv ✅ verified 1
src/_ZN13dScMgMemory_c13OnTurnIntoEggEi.c _ZN13dScMgMemory_c13OnTurnIntoEggEi ✅ verified 1
src/_ZN13dScMgMemory_c13OnYoshiTryEatEi.c _ZN13dScMgMemory_c13OnYoshiTryEatEi ✅ verified 1
src/_ZN13dScMgMemory_c15OnGroundPoundedEv.c _ZN13dScMgMemory_c15OnGroundPoundedEv ✅ verified 1
src/_ZN13dScMgMemory_c6RenderEv.cpp _ZN13dScMgMemory_c6RenderEv ✅ verified 1
src/_ZN13dScMgMemory_c8BehaviorEv.cpp _ZN13dScMgMemory_c8BehaviorEv ✅ verified 1
src/_ZN13dScMgMemory_cD0Ev.cpp _ZN13dScMgMemory_cD0Ev ✅ verified 1
src/_ZN13dScMgMemory_cD1Ev.cpp _ZN13dScMgMemory_cD1Ev ✅ verified 1
src/_ZN13dScMgTeresa_c13InitResourcesEv.cpp _ZN13dScMgTeresa_c13InitResourcesEv ✅ verified 1
src/_ZN13dScMgTeresa_c6RenderEv.cpp _ZN13dScMgTeresa_c6RenderEv ✅ verified 1
src/_ZN13dScMgTeresa_c8BehaviorEv.cpp _ZN13dScMgTeresa_c8BehaviorEv ✅ verified 1
src/_ZN13dScMgTeresa_cD0Ev.cpp _ZN13dScMgTeresa_cD0Ev ✅ verified 1
src/_ZN13dScMgTeresa_cD1Ev.cpp _ZN13dScMgTeresa_cD1Ev ✅ verified 1
src/_ZN14dScMgBomroom_c13InitResourcesEv.cpp _ZN14dScMgBomroom_c13InitResourcesEv ✅ verified 1
src/_ZN14dScMgBomroom_c6RenderEv.cpp _ZN14dScMgBomroom_c6RenderEv ✅ verified 1
src/_ZN14dScMgBomroom_c8BehaviorEv.cpp _ZN14dScMgBomroom_c8BehaviorEv ✅ verified 1
src/_ZN14dScMgBomroom_cD0Ev.cpp _ZN14dScMgBomroom_cD0Ev ✅ verified 1
src/_ZN14dScMgBomroom_cD1Ev.cpp _ZN14dScMgBomroom_cD1Ev ✅ verified 1
src/_ZN14dScMgCurling_c13InitResourcesEv.cpp _ZN14dScMgCurling_c13InitResourcesEv ✅ verified 1
src/_ZN14dScMgCurling_c13OnYoshiTryEatEi.cpp _ZN14dScMgCurling_c13OnYoshiTryEatEi ✅ verified 1
src/_ZN14dScMgCurling_c6RenderEv.cpp _ZN14dScMgCurling_c6RenderEv ✅ verified 1
src/_ZN14dScMgCurling_c8BehaviorEv.cpp _ZN14dScMgCurling_c8BehaviorEv ✅ verified 1
src/_ZN14dScMgCurling_cD0Ev.cpp _ZN14dScMgCurling_cD0Ev ✅ verified 1
src/_ZN14dScMgCurling_cD1Ev.cpp _ZN14dScMgCurling_cD1Ev ✅ verified 1
src/_ZN14dScMgD3DBase_c11AfterRenderEj.cpp _ZN14dScMgD3DBase_c11AfterRenderEj ✅ verified 1
src/_ZN14dScMgD3DBase_c12BeforeRenderEv.cpp _ZN14dScMgD3DBase_c12BeforeRenderEv ✅ verified 1
src/_ZN14dScMgD3DBase_c14BeforeBehaviorEv.cpp _ZN14dScMgD3DBase_c14BeforeBehaviorEv ✅ verified 1
src/_ZN14dScMgD3DBase_c16OnAimedAtWithEggEv.cpp _ZN14dScMgD3DBase_c16OnAimedAtWithEggEv ✅ verified 1
src/_ZN14dScMgD3DBase_c18AfterInitResourcesEj.cpp _ZN14dScMgD3DBase_c18AfterInitResourcesEj ✅ verified 1
src/_ZN14dScMgD3DBase_c19BeforeInitResourcesEv.cpp _ZN14dScMgD3DBase_c19BeforeInitResourcesEv ✅ verified 1
src/_ZN14dScMgD3DBase_c21AfterCleanupResourcesEj.cpp _ZN14dScMgD3DBase_c21AfterCleanupResourcesEj ✅ verified 1
src/_ZN14dScMgD3DBase_c25OnAimedAtWithEggReturnVecEv.c _ZN14dScMgD3DBase_c25OnAimedAtWithEggReturnVecEv ✅ verified 1
src/_ZN14dScMgD3DBase_c9Virtual7CEv.c _ZN14dScMgD3DBase_c9Virtual7CEv ✅ verified 1
src/_ZN14dScMgD3DBase_cD0Ev.cpp _ZN14dScMgD3DBase_cD0Ev ✅ verified 1
src/_ZN14dScMgD3DBase_cD1Ev.cpp _ZN14dScMgD3DBase_cD1Ev ✅ verified 1
src/_ZN14dScMgMemory2_c13InitResourcesEv.cpp _ZN14dScMgMemory2_c13InitResourcesEv ✅ verified 1
src/_ZN14dScMgMemory2_c13OnTurnIntoEggEi.c _ZN14dScMgMemory2_c13OnTurnIntoEggEi ✅ verified 1
src/_ZN14dScMgMemory2_c13OnYoshiTryEatEi.c _ZN14dScMgMemory2_c13OnYoshiTryEatEi ✅ verified 1
src/_ZN14dScMgMemory2_c15OnGroundPoundedEv.c _ZN14dScMgMemory2_c15OnGroundPoundedEv ✅ verified 1
src/_ZN14dScMgMemory2_c6RenderEv.cpp _ZN14dScMgMemory2_c6RenderEv ✅ verified 1
src/_ZN14dScMgMemory2_c8BehaviorEv.cpp _ZN14dScMgMemory2_c8BehaviorEv ✅ verified 1
src/_ZN14dScMgMemory2_cD0Ev.cpp _ZN14dScMgMemory2_cD0Ev ✅ verified 1
src/_ZN14dScMgMemory2_cD1Ev.cpp _ZN14dScMgMemory2_cD1Ev ✅ verified 1
src/_ZN15dScMgCurling2_c13InitResourcesEv.cpp _ZN15dScMgCurling2_c13InitResourcesEv ✅ verified 1
src/_ZN15dScMgCurling2_c13OnYoshiTryEatEi.cpp _ZN15dScMgCurling2_c13OnYoshiTryEatEi ✅ verified 1
src/_ZN15dScMgCurling2_c6RenderEv.cpp _ZN15dScMgCurling2_c6RenderEv ✅ verified 1
src/_ZN15dScMgCurling2_c8BehaviorEv.cpp _ZN15dScMgCurling2_c8BehaviorEv ✅ verified 1
src/_ZN15dScMgCurling2_cD0Ev.cpp _ZN15dScMgCurling2_cD0Ev ✅ verified 1
src/_ZN15dScMgCurling2_cD1Ev.cpp _ZN15dScMgCurling2_cD1Ev ✅ verified 1
src/_ZN15dScMgHanachan_c13InitResourcesEv.cpp _ZN15dScMgHanachan_c13InitResourcesEv ✅ verified 1
src/_ZN15dScMgHanachan_c16CleanupResourcesEv.cpp _ZN15dScMgHanachan_c16CleanupResourcesEv ✅ verified 1
src/_ZN15dScMgHanachan_c6RenderEv.cpp _ZN15dScMgHanachan_c6RenderEv ✅ verified 1
src/_ZN15dScMgHanachan_c8BehaviorEv.cpp _ZN15dScMgHanachan_c8BehaviorEv ✅ verified 1
src/_ZN15dScMgHanachan_cD0Ev.cpp _ZN15dScMgHanachan_cD0Ev ✅ verified 1
src/_ZN15dScMgHanachan_cD1Ev.cpp _ZN15dScMgHanachan_cD1Ev ✅ verified 1
src/_ZN15dScMgPachinko_c13InitResourcesEv.cpp _ZN15dScMgPachinko_c13InitResourcesEv ✅ verified 1
src/_ZN15dScMgPachinko_c6RenderEv.cpp _ZN15dScMgPachinko_c6RenderEv ✅ verified 1
src/_ZN15dScMgPachinko_c8BehaviorEv.cpp _ZN15dScMgPachinko_c8BehaviorEv ✅ verified 1
src/_ZN15dScMgPachinko_cD0Ev.cpp _ZN15dScMgPachinko_cD0Ev ✅ verified 1
src/_ZN15dScMgPachinko_cD1Ev.cpp _ZN15dScMgPachinko_cD1Ev ✅ verified 1
src/_ZN15dScMgRoulette_c13InitResourcesEv.cpp _ZN15dScMgRoulette_c13InitResourcesEv ✅ verified 1
src/_ZN15dScMgRoulette_c13OnYoshiTryEatEi.cpp _ZN15dScMgRoulette_c13OnYoshiTryEatEi ✅ verified 1
src/_ZN15dScMgRoulette_c16CleanupResourcesEv.cpp _ZN15dScMgRoulette_c16CleanupResourcesEv ✅ verified 1
src/_ZN15dScMgRoulette_c6RenderEv.cpp _ZN15dScMgRoulette_c6RenderEv ✅ verified 1
src/_ZN15dScMgRoulette_c8BehaviorEv.cpp _ZN15dScMgRoulette_c8BehaviorEv ✅ verified 1
src/_ZN15dScMgRoulette_cD0Ev.cpp _ZN15dScMgRoulette_cD0Ev ✅ verified 1
src/_ZN15dScMgRoulette_cD1Ev.cpp _ZN15dScMgRoulette_cD1Ev ✅ verified 1
src/_ZN15dScMgSnowball_c13InitResourcesEv.cpp _ZN15dScMgSnowball_c13InitResourcesEv ✅ verified 1
src/_ZN15dScMgSnowball_c16CleanupResourcesEv.cpp _ZN15dScMgSnowball_c16CleanupResourcesEv ✅ verified 1
src/_ZN15dScMgSnowball_c6RenderEv.cpp _ZN15dScMgSnowball_c6RenderEv ✅ verified 1
src/_ZN15dScMgSnowball_c8BehaviorEv.cpp _ZN15dScMgSnowball_c8BehaviorEv ✅ verified 1
src/_ZN15dScMgSnowball_c8OnKickedEv.c _ZN15dScMgSnowball_c8OnKickedEv ✅ verified 1
src/_ZN15dScMgSnowball_cD0Ev.cpp _ZN15dScMgSnowball_cD0Ev ✅ verified 1
src/_ZN15dScMgSnowball_cD1Ev.cpp _ZN15dScMgSnowball_cD1Ev ✅ verified 1
src/_ZN16dScMgPachinko2_c13InitResourcesEv.cpp _ZN16dScMgPachinko2_c13InitResourcesEv ✅ verified 1
src/_ZN16dScMgPachinko2_c6RenderEv.cpp _ZN16dScMgPachinko2_c6RenderEv ✅ verified 1
src/_ZN16dScMgPachinko2_c8BehaviorEv.cpp _ZN16dScMgPachinko2_c8BehaviorEv ✅ verified 1
src/_ZN16dScMgPachinko2_cD0Ev.cpp _ZN16dScMgPachinko2_cD0Ev ✅ verified 1
src/_ZN16dScMgPachinko2_cD1Ev.cpp _ZN16dScMgPachinko2_cD1Ev ✅ verified 1
src/_ZN16dScMgSmartball_c21AfterCleanupResourcesEj.cpp _ZN16dScMgSmartball_c21AfterCleanupResourcesEj ✅ verified 1
src/_ZN16dScMgSmartball_c6RenderEv.cpp _ZN16dScMgSmartball_c6RenderEv ✅ verified 1
src/_ZN16dScMgSmartball_c8BehaviorEv.cpp _ZN16dScMgSmartball_c8BehaviorEv ✅ verified 1
src/_ZN16dScMgSmartball_c9Virtual7CEv.c _ZN16dScMgSmartball_c9Virtual7CEv ✅ verified 1
src/_ZN16dScMgSmartball_cD0Ev.cpp _ZN16dScMgSmartball_cD0Ev ✅ verified 1
src/_ZN16dScMgSmartball_cD1Ev.cpp _ZN16dScMgSmartball_cD1Ev ✅ verified 1
src/_ZN17dScMgTrampoline_c13InitResourcesEv.cpp _ZN17dScMgTrampoline_c13InitResourcesEv ✅ verified 1
src/_ZN17dScMgTrampoline_c13OnYoshiTryEatEi.c _ZN17dScMgTrampoline_c13OnYoshiTryEatEi ✅ verified 1
src/_ZN17dScMgTrampoline_c16CleanupResourcesEv.cpp _ZN17dScMgTrampoline_c16CleanupResourcesEv ✅ verified 1
src/_ZN17dScMgTrampoline_c6RenderEv.cpp _ZN17dScMgTrampoline_c6RenderEv ✅ verified 1
src/_ZN17dScMgTrampoline_c8BehaviorEv.cpp _ZN17dScMgTrampoline_c8BehaviorEv ✅ verified 1
src/_ZN17dScMgTrampoline_cD0Ev.cpp _ZN17dScMgTrampoline_cD0Ev ✅ verified 1
src/_ZN17dScMgTrampoline_cD1Ev.cpp _ZN17dScMgTrampoline_cD1Ev ✅ verified 1
src/_ZN18dScMgTrampoline2_c13InitResourcesEv.cpp _ZN18dScMgTrampoline2_c13InitResourcesEv ✅ verified 1
src/_ZN18dScMgTrampoline2_c16CleanupResourcesEv.cpp _ZN18dScMgTrampoline2_c16CleanupResourcesEv ✅ verified 1
src/_ZN18dScMgTrampoline2_c6RenderEv.cpp _ZN18dScMgTrampoline2_c6RenderEv ✅ verified 1
src/_ZN18dScMgTrampoline2_c8BehaviorEv.cpp _ZN18dScMgTrampoline2_c8BehaviorEv ✅ verified 1
src/_ZN18dScMgTrampoline2_cD0Ev.cpp _ZN18dScMgTrampoline2_cD0Ev ✅ verified 1
src/_ZN18dScMgTrampoline2_cD1Ev.cpp _ZN18dScMgTrampoline2_cD1Ev ✅ verified 1
src/actors/dScMgBSC_c.cpp _ZN10dScMgBSC_cD1Ev + _ZN10dScMgBSC_cD0Ev + func_ov006_02124a04 + func_ov006_02124a08 + func_ov006_02124ae4 + func_ov006_02124b58 + func_ov006_02124bb4 + func_ov006_02124cb4 + func_ov006_02124dc0 + func_ov006_02124e1c + func_ov006_02124ec4 + func_ov006_02124fd8 + func_ov006_021250e4 + _ZN10dScMgBSC_c15OnGroundPoundedEv + _ZN10dScMgBSC_c13OnTurnIntoEggEi + _ZN10dScMgBSC_c13OnYoshiTryEatEi + _ZN10dScMgBSC_c6RenderEv + _ZN10dScMgBSC_c8BehaviorEv + _ZN10dScMgBSC_c13InitResourcesEv ✅ verified 19
src/actors/dScMgBase_c.cpp _ZN11dScMgBase_c16OnPendingDestroyEv + _ZN11dScMgBase_c6RenderEv + _ZN11dScMgBase_c12BeforeRenderEv + _ZN11dScMgBase_c8BehaviorEv + _ZN11dScMgBase_c14BeforeBehaviorEv + _ZN11dScMgBase_c21AfterCleanupResourcesEj + _ZN11dScMgBase_c18AfterInitResourcesEj + _ZN11dScMgBase_c19BeforeInitResourcesEv ✅ verified 8
src/actors/dScMgCard_c.cpp _ZN11dScMgCard_cD1Ev + _ZN11dScMgCard_cD0Ev + func_ov006_020d96e0 + func_ov006_020d96f0 + func_ov006_020d970c + func_ov006_020d978c + func_ov006_020d9998 + func_ov006_020d99a4 + func_ov006_020d99ec + func_ov006_020d9a14 + func_ov006_020d9bd0 + func_ov006_020d9bdc + func_ov006_020d9c5c + func_ov006_020da00c + func_ov006_020da0ac + func_ov006_020da154 + func_ov006_020da174 + func_ov006_020da420 + func_ov006_020da4ac + func_ov006_020da5e8 + func_ov006_020da834 + func_ov006_020da860 + func_ov006_020da88c + func_ov006_020da8b8 + func_ov006_020da8e4 + func_ov006_020da974 + _ZN11dScMgCard_c16CleanupResourcesEv + _ZN11dScMgCard_c6RenderEv + _ZN11dScMgCard_c8BehaviorEv + func_ov006_020dac34 + _ZN11dScMgCard_c15OnGroundPoundedEv + _ZN11dScMgCard_c13OnTurnIntoEggEi + _ZN11dScMgCard_c13OnYoshiTryEatEi + _ZN11dScMgCard_c13InitResourcesEv ✅ verified 34
src/actors/dScMgMCarlo2_c.cpp _ZN14dScMgMCarlo2_cD1Ev + _ZN14dScMgMCarlo2_cD0Ev + func_ov006_020f8ff0 + func_ov006_020f9000 + func_ov006_020f94f4 + func_ov006_020f9560 + func_ov006_020f95f0 + func_ov006_020f9668 + func_ov006_020f96e0 + func_ov006_020f9760 + func_ov006_020f98dc + func_ov006_020f9994 + func_ov006_020f9bec + func_ov006_020f9cbc + func_ov006_020f9d68 + func_ov006_020f9db8 + func_ov006_020f9f40 + _ZN14dScMgMCarlo2_c16CleanupResourcesEv + _ZN14dScMgMCarlo2_c6RenderEv + _ZN14dScMgMCarlo2_c8BehaviorEv + _ZN14dScMgMCarlo2_c13OnTurnIntoEggEi + _ZN14dScMgMCarlo2_c13OnYoshiTryEatEi + _ZN14dScMgMCarlo2_c13InitResourcesEv ✅ verified 23
src/actors/dScMgMCarlo_c.cpp _ZN13dScMgMCarlo_cD1Ev + _ZN13dScMgMCarlo_cD0Ev + func_ov006_020f7730 + func_ov006_020f7740 + func_ov006_020f7994 + func_ov006_020f7a00 + func_ov006_020f7a90 + func_ov006_020f7b10 + func_ov006_020f7b90 + func_ov006_020f7c10 + func_ov006_020f7e2c + func_ov006_020f7ee4 + func_ov006_020f8154 + func_ov006_020f8224 + func_ov006_020f82d0 + func_ov006_020f8320 + func_ov006_020f84a8 + func_ov006_020f8540 + _ZN13dScMgMCarlo_c6RenderEv + _ZN13dScMgMCarlo_c8BehaviorEv + _ZN13dScMgMCarlo_c13OnTurnIntoEggEi + _ZN13dScMgMCarlo_c13OnYoshiTryEatEi + _ZN13dScMgMCarlo_c13InitResourcesEv ✅ verified 23
src/actors/dScMgSingle3DBase_c.cpp _ZN19dScMgSingle3DBase_cD1Ev + _ZN19dScMgSingle3DBase_cD0Ev + func_ov006_0210a534 + _ZN19dScMgSingle3DBase_c24OnHitByCannonBlastedCharEv + _ZN19dScMgSingle3DBase_c21AfterCleanupResourcesEj + _ZN19dScMgSingle3DBase_c12BeforeRenderEv + _ZN19dScMgSingle3DBase_c14BeforeBehaviorEv + _ZN19dScMgSingle3DBase_c18AfterInitResourcesEj + func_ov006_0210a708 ✅ verified 9
src/func_ov004_020b0a54.cpp func_ov004_020b0a54 ✅ verified 1
src/func_ov006_0210d6b8.cpp func_ov006_0210d6b8 ✅ verified 1

The private worker commits a test merge, builds the stock ROM profile, compares every executable module, measures matched and source-built code, checks contributor lineage, and verifies affected relocations. The mod profile is opt-in and is not part of this merge gate.

@andrewboudreau

Copy link
Copy Markdown
Collaborator Author

Self-review. I wrote this, and this repo has one shared account so no PR here can be APPROVED by a second identity — signing off in a comment instead, with what I actually checked and what I could not.

Verified on the merge tree, not just the branch. tools/premerge_check.py --base origin/main --fetch 2099 2100 2102 2106 — all four merge trees green on all eight static gates (converted-ratchet, dead-references, duplicate-sources, header-offsets, langmode-ratchet, layout-check, src-tu-refs, source-coverage), nothing base-green goes merge-red. Merge tree for this PR: 35d3297644b3.

Byte evidence. rombuild -j16 --no-rom 11,088/11,088 reproducing, 106/106 exact, 100.000000%. romdata_check --json diffed against the slot-30 baseline field by field: verifiedBytes +4, partialBytes +124, everything else identical, differing set unchanged in both directions (nothing gained, nothing lost). +128 is exactly 32 tables x one word, which is the arithmetic this campaign has hit at every slot.

What I checked hardest, because the naming claim is the load-bearing part. The sibling-branch argument is five independent header reads, not an inference from one: fBase_c.h:130-146 (slots 0-15 + the D1/D0 pair at 16/17), dBase_c adding no virtual, dScene_c declaring nothing above slot 11, dActor_c.h ending at slot 30, and dScMgBase_c's own chain. The dispatch scan is the independent check — 39 ldr/blx pairs at +0x7c across arm9 and all 103 overlays, 1 in ov004/ov006 and 38 in the eight overlays where dBgActor_c lives. If the two were one chain, that split would not fall that way.

One correction to my own earlier work, stated plainly: slots 26, 29 and 30 each shipped with a note saying "the ROM contradicts this name." Those notes are right but they undersold it — the names do not apply to any of slots 18-30, for a structural reason, not a per-slot one. The prose in those headers stands; the general conclusion is new here.

What this PR does NOT establish, and I want it on the record:

  • Virtual7C is not a ROM-derived name either. It is an honest placeholder in the repo's own established spelling. Nothing in the cartridge names this method; RTTI carries class names only.
  • Return type int is a HINT and the PR body says so. Nothing pins it.
  • Retro-renaming slots 18-30 is deliberately not attempted here. It is eighteen slots of churn across ~30 classes and it is your call, not a thing to slip into a slot commit.

A gate defect I found while checking this one, and did not act on. The langmode ratchet's baseline is supposed to live on chaos-data — the workflow's own header calls the repo-root langmode-baseline.json an escape hatch to be deleted in a follow-up. But a root langmode-baseline.json is tracked on main (last written 2026-08-27 by the "Refresh progress" job, commit 9e3532e0e) and langmode-ratchet.yml prefers it over the banked copy. It reads unmigrated_total: 558 against a tree that currently measures 154, so the gate cannot see a rise of up to ~+400 and has been effectively inert for four days. Checked against the real banked baseline (origin/chaos-data:langmode-baseline.json, f838695c5), this stack measures 142 -> 154 — about +2 per slot, which is inherent to the campaign: naming a slot converts anonymous func_* files into hand-spelled mangled names, which is the step before real member-function migration, not a regression.

I am not deleting the root file in this PR — doing so would turn this stack red on a technicality unrelated to it, and the file appears to be regenerated by a bot, so the real fix is in that job, in its own tools-only PR. Flagging it so it is not discovered later as a surprise.

Landing stays with you.

@andrewboudreau andrewboudreau left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at 723cec8ec. Two asks, one of them the same systemic issue that already holds #2099, #2100 and #2102, plus one thing I want to say plainly in your favour.

The Virtual7C name is right, and I am not going to argue with it

I want this on the record because a placeholder name usually draws a block from me. This one should not.

Virtual7C is a deliberate non-name, the header says so, and the reasoning is correct: _ZN11dScMgBase_c9Virtual50Ev is already in tracked config on origin/main, and fBase_c declares Virtual34 / Virtual38 there too. Slot 31 is vtable+0x7C, so the spelling follows the landed convention exactly and invents no new one.

It is also the honest option. "Nothing in the cartridge names this function" is the sentence that makes this safe — a placeholder that admits it is a placeholder cannot later be mistaken for a ROM-proven identity, which is the failure mode I keep having to chase. The Kill-came-from-a-nephew derivation (dBgActor_c is under dActor_c, so Kill crossed a fork rather than descending a chain) is the good kind of argument: it explains the wrong answer instead of just deleting it.

The arity measurement is real work and it holds up — 39 ldr rN,[rM,#0x7c] + blx rN dispatch pairs across arm9 and 103 overlays, exactly one in ov004/ov006, and r1 is the loaded pointer so it cannot also be a second argument.

1. Four new header/definition return-type disagreements

The four headers declare:

include/dScMgBase_c.h:648        virtual int  Virtual7C();     /* slot 31 */
include/dScMgD3DBase_c.h:100     virtual int  Virtual7C();
include/dScMgAmida_c.h:58        virtual int  Virtual7C();
include/dScMgSmartball_c.h:77    virtual int  Virtual7C();

All four definitions return void:

src/_ZN11dScMgBase_c9Virtual7CEv.c:28       void _ZN11dScMgBase_c9Virtual7CEv(void)
src/_ZN14dScMgD3DBase_c9Virtual7CEv.c:44    void _ZN14dScMgD3DBase_c9Virtual7CEv(char *c)
src/_ZN12dScMgAmida_c9Virtual7CEv.cpp:20    extern "C" void _ZN12dScMgAmida_c9Virtual7CEv(void)
src/_ZN16dScMgSmartball_c9Virtual7CEv.c:17  void _ZN16dScMgSmartball_c9Virtual7CEv(void)

Nothing in the tree compares those two surfaces, so this compiles and links clean. A C++ caller reaching the method through the class header reads r0 from a body that never wrote it.

This is not new with you, and I am not treating it as if it were. I audited every dScMgBase_c virtual against its src/_ZN11dScMgBase_c* definition across the stack:

ref header/definition mismatches
origin/main 2 — OnYoshiTryEat, Virtual50
origin/cpp/minigame-slot30 5 — + OnHitFromUnderneath, OnAimedAtWithEgg, OnAimedAtWithEggReturnVec
origin/cpp/minigame-slot31 6 — + Virtual7C

Every one is header int, src def void. The stack adds exactly one per PR, monotonically, and this would be the fourth.

The ask is consistency, not a particular type. These bodies genuinely do not set r0, and your own header says int is A HINT, so I am not claiming the ROM says void. I measured the neutrality directly on slot 29 earlier in this campaign: int returning the value already in r0 byte-matches, and so does void. The ROM does not care. What it cannot tolerate is the two spellings disagreeing.

So either:

  • declare void in all four headers — smallest change, and it matches what the bodies actually do; or
  • keep int and return the free value in the definitions (for slot 31 that is LoadCompressedFileAt's return, which is already in r0 — do not write return 0;, that manufactures a mov r0,#0 the ROM does not have and reads like a false refutation).

Either is fine. Split is not.

Note this is a third declaration surface. Virtual7C is absent from include/decl_common.h, so the checker I opened in #2105 reports no new disagreement on this branch — it joins decl_common.h against class headers and does not read src/ definitions. That is a real gap in my tool, measured on your PR, and I will extend it. On this tree the union of both surfaces is 8 distinct symbols with a return-type disagreement somewhere.

2. Off-by-one: this is the fourth consecutive non-pin, not the third

Inside include/dScMgBase_c.h on this branch:

:366  slot 28 -- "return type: int, A HINT -- and slot 28 is the first in this campaign"
:425  slot 29 -- "A HINT, the second consecutive slot that no body pins"
:510  slot 30 -- "A HINT, and the THIRD consecutive slot no body pins"
:606  slot 31 -- "A HINT, the third consecutive slot no body pins"

Slots 30 and 31 both claim third. Slot 31 is the fourth. One word.

Where this sits

Stack is #2099#2100#2102#2106, and the three below all carry CHANGES REQUESTED from me on this same disagreement. I would rather that be settled once at the base than patched four times, so I am not asking you to fix the five inherited rows here — just to not add the sixth without the decision being made.

Everything else in this PR I checked and it holds: the Virtual7C symbol renames in config/arm9/overlays/{ov004,ov006}/symbols.txt are address-preserving and size-preserving (0x8c/0x104 unchanged), and the ninth name correction — 0x020e72c0 was carrying recovered name: dScMgTrampoline2_c_Kill while five tables reference it, so it is dScMgD3DBase_c's — is the right call for the right reason.

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

Labels

attribution-override Maintainer accepts this PR's contributor-credit changes; validation reports them as warnings

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant