# Entity Class Family Split ## Purpose This note breaks the large seg001 `Entity` lane into a conservative class-family model that can later be promoted in Ghidra or emitted as C++ without pretending that every vtable and helper belongs to one monolithic base class. Current goal is not full inheritance recovery. Current goal is to identify the safest boundaries between: - one shared gameplay-entity core layout - projectile-specific allocation and movement behavior - debris/corpse variants - registry/helper surfaces that look adjacent but should not be merged automatically ## Core Shared Entity Object Strongest current common object is the gameplay entity body documented in [docs/ne-segment1.md](docs/ne-segment1.md). Stable shared anchors: - `0007:3f2f entity_spawn` - `0007:40d4 entity_remove` - `0007:4552 entity_set_position` - `0007:4591 entity_try_place` - `0007:5092 entity_deactivate` Stable shared fields from the current note set include: - `+0x00` vtable pointer - `+0x02` slot index - `+0x04` entity type - `+0x19/+0x1a` flags - `+0x3c` sprite handle - `+0x45/+0x47/+0x49` world position - `+0x4f/+0x51/+0x53` base position - `+0x54/+0x56/+0x58` previous position This is the safest current candidate for a future `Entity` or `ActorBase` style root. ## Candidate Split ### 1. `Entity` base gameplay family Best current scope: - allocation/spawn and placement - common position, flags, facing, and sprite ownership - generic remove/deactivate behavior - registry-facing slot identity Best current vtable anchor: - generic/AI entity vtable `0x29aa` Current caution: - this family likely includes several behaviorally different actors, but the verified note set still supports one shared base before the split gets more specific. ### 2. `ShotEntity` or projectile-derived family Strong anchors: - `0007:28ce shot_entity_alloc` - `0007:44a9 shot_entity_free` - `0007:4659 projectile_init_vector` - `0007:4b78 projectile_check_hit` - `0007:4c2e projectile_step_update` - `0007:4d28 projectile_trace_ray` - `0007:51ad projectile_update_tick` - `0007:5a99 projectile_apply_hit` Best current distinct evidence: - dedicated vtable `0x297e` - extra projectile ownership/target fields through `+0x6a..+0xbd` - separate shot sprite handle at `+0x3f` - dedicated cleanup path in `shot_entity_free` Current safest interpretation: - projectile objects are not just one mode of the generic entity vtable; they deserve at least one derived-family model with their own ctor/free/update surface. ### 3. `DebrisEntity` family Strong anchors: - `0007:7490 debris_spawn` - `0007:75ff entity_die` Best current distinct evidence: - dedicated debris/fragment vtable `0x2a57` - corpse/debris-adjacent vtable pair `0x2a1a` and `0x2a33` - death-spawn path uses separate velocity/facing behavior rather than only the generic entity update lane Current safest interpretation: - debris should stay separate from `ShotEntity`; both share movement-style fields but not the same lifecycle intent. ### 4. `CorpseEntity` or actor-remnant family Strong current evidence: - vtable pair `0x2a1a` and `0x2a33` - adjacency to `entity_die` and debris-spawn behavior Current caution: - the notes support a corpse/remnant family, but not yet a crisp split between static remains, actor corpse, and debris fragments. - keep this as a provisional derived branch until a dedicated caller pass closes object lifetime more tightly. ### 5. Adjacent but probably separate: dialog/menu object lane Anchor: - `0007:2c92 dialog_spawn` Why it should stay separate: - vtable `0x28b5` - callback registration at `0x39ca` - behavior is UI/dialog-style rather than ordinary gameplay entity movement or projectile logic Current safest interpretation: - this object is near the entity notes because it lives in the same broad segment lane, but it should not be promoted under the core gameplay `Entity` family automatically. ## Registry And Helper Surfaces That Should Not Be Mis-modeled ### Entity registry vtable `0x2969` Current evidence in [docs/ne-segment1.md](docs/ne-segment1.md) shows `0x2969` stored at `0x39ca + slot*4` as a registry vtable rather than as the entity instance's primary vtable. That means: - do not treat `0x2969` as a normal `Entity` virtual table - keep registry or handle-table behavior separate from per-instance inheritance ### Pure helpers that should remain free functions for now Examples: - `snap_entity_to_ground` - `spawn_entity_checked` - `map_find_spawn_point` - `actor_find_in_view` These may operate on entities or produce entities, but current evidence still reads better as subsystem helpers than as obvious instance methods. ## Recommended Promotion Order 1. model the shared `Entity` base layout first 2. split `ShotEntity` next because its ctor/free/update lane is strongest 3. split debris/corpse branches only after one more caller-side lifetime pass 4. leave dialog/menu object modeling separate from the entity inheritance tree ## Source-Emission Guidance If this family is emitted to provisional C++ later, safest first skeleton is: - one `Entity` base struct/class with the stable common layout - one `ShotEntity` derived placeholder - one `DebrisEntity` derived placeholder - one unresolved `CorpseLikeEntity` placeholder if needed - separate `DialogMenuObject` class rather than folding it into the gameplay entity tree ## Bottom Line The current evidence strongly supports a shared gameplay entity core, but it does not support flattening generic actor, projectile, debris, corpse, and dialog/menu behavior into one class. The right near-term move is `base first, derived families second, adjacent objects separate`.