Crusader_Decomp/docs/entity-vm-runtime-owner-resource-layout.md

169 lines
6.7 KiB
Markdown
Raw Normal View History

2026-04-05 18:27:09 +02:00
# Entity VM Runtime And Owner-Resource Layout
## Purpose
This note gathers the current class-lift-relevant structure for the VM runtime lane into one place.
It focuses on four connected objects:
- `EntityVmRuntime`
- `EntityVmOwnerResource`
- `EntityVmContext`
- the slot/value helpers that connect gameplay entities to owner-loaded VM source data
The goal is not full opcode recovery. The goal is to make later class authoring and C++ skeleton emission faster by freezing the current ownership model.
## High-Level Ownership Model
Current best model from [docs/raw-0008-000c.md](docs/raw-0008-000c.md) and [docs/raw-000a-000d.md](docs/raw-000a-000d.md):
1. startup path resolves a configured EUSECODE root/path
2. `entity_vm_runtime_create` allocates the main runtime body
3. runtime constructor attaches one file-backed helper created by `entity_vm_runtime_owner_resource_create`
4. gameplay entities map to slot indices through `entity_vm_slot_index_from_entity`
5. masked-create helpers test owner-side capability bits and then build per-entity or per-slot `EntityVmContext` objects
6. contexts seed their local stream/value state from owner-loaded source rows and runtime slot caches
## `EntityVmRuntime`
Strong anchors:
- `000d:44df entity_vm_runtime_init_from_path_if_configured`
- `000d:4c99 entity_vm_runtime_create`
- `000d:4d36 entity_vm_runtime_init_slots`
- `000d:4d75 entity_vm_runtime_release_slots`
- `000d:4e01 entity_vm_runtime_destroy`
Current strongest structural claims:
- runtime body is the global owner behind `0x6611/0x6613`
- front region behaves like a `0x80` entry slot table with stride `0x26`
- tail region around `+0x1300..+0x1318` holds runtime budget/default metadata plus the owner-resource helper pointer
- helper attachment lives at `+0x1315/+0x1317`
Current safe class role:
- long-lived VM root object that owns slot state, owner resource, category-base words, and runtime-wide value budgets
## `EntityVmOwnerResource`
Strong anchors:
- `000d:7000 entity_vm_runtime_owner_resource_create`
- `000d:70fd entity_vm_runtime_owner_resource_destroy`
Best current helper shape:
- compact file-backed helper object
- helper-owned count at `+0x14`
- far-pointer table at `+0x10`
- paired 16-bit table at `+0x18`
- helper vtable `+0x04` acts as size query
- helper vtable `+0x0c` materializes the `0x0d`-stride owner rows later consumed by contexts
Current safest interpretation:
- this is the most bounded class-lift target in the VM lane
- it looks like a real helper object with a compact stable layout and a clear owner relationship to `EntityVmRuntime`
### seg070 loader contract
The paired loops rooted at raw windows `0009:67b6` and `0009:6916` are current best evidence that the helper is file-backed rather than a pure in-memory descriptor copier.
Verified behavior already captured in the main notes:
- iterate helper-owned count at `+0x14`
- index path/id tables at `+0x10` and `+0x18`
- build formatted paths with two distinct format strings
- open, seek/read, close, and free loop-local buffers through the DOS/file helper lane
Current caution:
- exact per-family record schema is still open, so the helper should be modeled as a loader/index object first, not as a final descriptor-schema class.
## `EntityVmContext`
Strong anchors:
- `000d:463a entity_vm_context_try_create_masked_for_entity`
- `000d:46ec entity_vm_context_create_from_slot_index`
- `000d:48b6 entity_vm_context_free_buffer`
- `000d:48da entity_vm_context_sync_global_value_and_dispatch`
- `000d:4962 entity_vm_context_destroy`
- `000d:498f entity_vm_context_save`
- `000d:4a78 entity_vm_context_load`
Current safe role:
- per-entity or per-slot execution/context object built from runtime slot state plus owner-loaded source data
Current layout claims that matter for class lifting:
- `+0x32` stores slot index
- `+0x34` stores the additive offset word used by the `slot_load_value_plus_offset` lane
- `+0x36` embeds the mini-VM/state object
- `+0xd6/+0xd8` hold the seeded source/control stream lane
- `+0x102` is the backward-growing local payload/buffer lane
- `+0x10c/+0x10e` store a derived low/high pair reused by save/load
- `+0x117/+0x119` cache the owner-linked source pair
- `+0x123` behaves as a busy or active flag in the sync/dispatch path
Current caution:
- context dispatch semantics are still active work, so this object should be modeled around lifecycle and data ownership first, not around final method names for every opcode-facing helper.
## Gameplay Entity To VM Bridge
### Slot selection
`entity_vm_slot_index_from_entity` (`000d:45c5`) is the key bridge from gameplay entity identity into the VM lane.
Current safest summary:
- it does not choose `NPCTRIG` versus `EVENT` directly
- it maps gameplay entities into category spans using runtime base words such as `0x8c7c/0x8c7e/0x8c80`
- owner-row capability bits and later slot-value materialization do the next stage of filtering
### Masked-create helpers
The masked-create family is already class-lift relevant even before final event labels are known.
What is safe now:
- the hub at `000d:463a` checks runtime-disable state and owner-side mask bits
- low-slot and high-slot wrappers differ by slot id, mask, and whether they pass an extra signed/additive word
- wrappers like slot `0x0a` / `0x0b` are offset-specialized context creators, not separate selector universes
This means future Ghidra or C++ modeling should treat them as helper factories around `EntityVmContext`, not as methods on unrelated gameplay classes.
## Best Class-Lift Targets In This Lane
1. `EntityVmOwnerResource`
2. `EntityVmRuntime`
3. `EntityVmContext`
Why this order:
- owner-resource helper is compact and structurally bounded
- runtime has clear ownership over the helper and slot table
- context has the richest semantics but also the most unresolved dispatcher behavior
## Source-Emission Guidance
If emitted as provisional C++ later, safest early skeleton is:
- `EntityVmOwnerResource` with explicit loader/index fields and placeholder virtual/helper methods
- `EntityVmRuntime` with fixed-size slot table, owner pointer, category-base fields, and create/destroy methods
- `EntityVmContext` with exact saved-field placeholders and a distinct embedded mini-VM state member
Avoid in the first skeleton:
- speculative opcode enums presented as final
- collapsing the owner-resource helper into plain runtime fields
- flattening the source/control stream pair into one host-only pointer abstraction if Track A remains active
## Bottom Line
The VM lane now supports a real class model, but it should start with ownership and layout rather than with overconfident script-semantic names.
The most defensible current model is `runtime owns helper and slot state; contexts are short-lived objects built from slot selection plus owner-loaded source rows`.