5.2 KiB
Remorse First Class-Authoring Checklist
Purpose
This note turns the current class-lift preparation into a concrete execution checklist for the first real Ghidra/MCP authoring batch.
It is intentionally operational. The goal is to remove startup cost once the necessary MCP class/vtable/datatype tools exist.
Recommended First Pilot Order
Current best pilot ranking:
EntityDispatchEntrySpriteNodeEntityVmOwnerResource
Why this order:
EntityDispatchEntryhas strong ctor/release and field-group evidenceSpriteNodehas a compact, visible virtual surfaceEntityVmOwnerResourceis structurally bounded but still slightly more loader-schema-sensitive
Batch 0: Preconditions
Before touching class ownership in Ghidra:
- re-read docs/remorse-class-lift-index.md
- re-read the target family note
- confirm the ABI note and compatibility-header draft are still aligned with the intended source track
- confirm the MCP tool surface actually supports namespace/class creation, datatype authoring, and method ownership changes
Do not start with authoring if any of those are still missing.
Batch 1: Authoring Rules
These rules should hold for the first pilot family regardless of which family is chosen:
- move only strongly owned methods first
- preserve raw slot order in provisional vtables
- keep uncertain fields explicit as padding or unknown words/bytes
- prefer conservative owner names over polished but speculative subsystem names
- add provenance comments when a layout or slot label is imported from an earlier note rather than re-derived in-session
Pilot A: EntityDispatchEntry
Use docs/entity-dispatch-entry-class-layout.md as the source note.
Minimum Ghidra/MCP deliverables
- create owner namespace/class for the base family
- create provisional instance struct for the base layout
- create provisional vtable datatype with stable known slots only
- move base ctor/release methods under that owner
- keep subtype/overlay-specific methods outside the base owner until the split is tighter
First methods to move
- base ctor at
0008:ba00 - release/destroy surface at
0008:dbec - runtime-state init/release pair
000d:7e00/000d:8078only if the owner relationship is still judged direct in-session
Fields that should stay visible immediately
- type and subtype-related words near
+0x04/+0x06/+0x08 - active/hold/runtime flags around
+0x16/+0x18 - runtime-state and paired resource lanes around
+0x3c/+0x40
Things to avoid in the first pass
- flattening every derived constructor into one base class
- forcing final names for every slot in the vtable
- pretending all runtime-state fields belong to the same subtype
Pilot B: SpriteNode
Use docs/sprite-node-class-layout.md as the source note.
Minimum Ghidra/MCP deliverables
- create owner namespace/class for
SpriteNode - create provisional vtable with only the slot order and best current role labels
- move destructor and event-dispatch surface under that owner
- create instance struct with the known layout anchors and visible unknown regions
First methods to move
000b:326e sprite_node_destroy000b:3ab2 sprite_node_dispatch_event000b:3380 sprite_node_is_dirty000b:33a6 sprite_node_mark_dirty
Things to avoid in the first pass
- pushing traversal helpers into the class just because they walk the tree
- overcommitting to child/sibling field semantics beyond the already-noted anchors
Pilot C: EntityVmOwnerResource
Use docs/entity-vm-runtime-owner-resource-layout.md as the source note.
Minimum Ghidra/MCP deliverables
- create helper class owner
- create compact helper instance struct
- create provisional method table for the
+0x04and+0x0chelper callbacks - move create/destroy pair under that owner
Things to avoid in the first pass
- baking in final file-family schema labels
- collapsing the helper into the runtime object as anonymous fields
Source-Emission Readiness Gate
Do not emit the first C++ skeleton immediately after Ghidra authoring.
Only emit when all of these are true:
- owner namespace/class exists
- provisional instance struct exists
- provisional vtable exists when relevant
- top 3-5 strongly owned methods are moved
- unresolved fields remain explicit instead of silently renamed away
- Track A versus Track B assumptions are recorded for that family
Success Criteria For The First Real Batch
The first class-authoring batch is successful if:
- one family becomes visibly easier to navigate in Ghidra
- method ownership is improved without speculative over-grouping
- instance layout is more explicit than raw offset math
- the result can drive one hand-maintained C++ header/source skeleton with the compatibility layer
Bottom Line
The first class-authoring batch should be judged by structural clarity, not by how polished or object-oriented the output looks.
EntityDispatchEntry remains the best first pilot because it offers the highest ratio of stable object evidence to remaining subtype ambiguity.