Crusader_Decomp/docs/entity-vm-runtime-owner-resource-layout.md
2026-04-05 18:27:09 +02:00

6.7 KiB

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 and 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.