Download Game! Currently 51 players and visitors. Last logged in:JumadanVenyaintFloppyDeino

Blitzer's Blog >> 71850

Back to blogs index
Posted: 29 Aug 2026 22:51 [ permalink ]
This is where the engine transforms from a simple math calculator into a true
object-oriented environment.
To maintain our crash-proof, Ring 0-compatible architecture, we must strictly
separate Logic (Blueprints) from State (Instances).
Here is the architectural specification for Phase 2: The Master Object Index
and the Blueprint Loader.
1. The Blueprint Registry (Immutable Logic)
Before an object can exist, its Blueprint must be loaded. The engine maintains
a global Blueprint Registry.
When the JS Compiler finishes compiling monster.c, the resulting binary block
is registered here and assigned a unique blueprint_id (e.g., 100).
The Blueprint provides the execution engine with:
 * The flat 32-bit bytecode array.
 * The VTable (Exported function hashes mapped to instruction pointers).
 * The Constant Pool.
 * The var_count (How many global variables this object requires).
2. The Master Object Index (MOI)
The MOI is a pre-allocated Int32Array that tracks every active object instance
in the game world. It operates similarly to your Global Handle Ledger, but the
nodes represent execution contexts.
Every object is assigned an Object ID (OID), which serves as the direct index
into this array. Each MOI node is 16 bytes (4 integers).
| Offset | Type (32-bit) | Field Name | Description |
|---|---|---|---|
| 0x00 | int32 | blueprint_id | Identifies which Blueprint this instance runs.
|
| 0x04 | int32 | state_offset | The index into the State Arena where variables
live. |
| 0x08 | int32 | var_count | Number of variables allocated for bounds
checking. |
| 0x0C | int32 | flags | Bitmask (0x1 = Master, 0x2 = Clone, 0x4 =
Destructed). |
3. The State Arena (Variable Storage)
Where do the object's global variables actually live?
Because all variables in our VM are strictly 32-bit Tagged Pointers, they do
not go into the byte-level Data Arena. They go into a new, dedicated
Int32Array called the State Arena.
 * Like the Data Arena, we use a bump-allocator pointer: stateArenaOffset.
 * If a monster.c Blueprint states it needs 5 variables (var_count = 5), the
Host reserves 5 consecutive integers in the State Arena.
 * All 5 integers are instantly initialized to TAG_NIL (e.g., 0x00000007).
4. Specification for the Blueprint Loader (clone_object)
When LPC executes clone_object("monster"), the Host OS performs this exact
sequence:
 * Look up "monster" in the Blueprint Registry to get its blueprint_id and
var_count.
 * Find the next free OID (index) in the Master Object Index.
 * Allocate var_count slots in the State Arena at the current
stateArenaOffset.
 * Initialize those slots to TAG_NIL.
 * Populate the MOI node:
   * blueprint_id = The ID from step 1.
   * state_offset = The current stateArenaOffset.
   * var_count = The count from step 1.
   * flags = 0x2 (Clone).
 * Increment stateArenaOffset += var_count.
 * Return the OID as a Tagged Pointer (Tag 0: Object Handle) to the VM.
5. Integration with VM Opcodes
To manipulate these variables, the VM bytecode needs two new opcodes: LOAD_VAR
and STORE_VAR.
To execute these safely, the VM must always know which object is currently
executing. We track this by adding a current_oid property to the
LPCVirtualMachine class (which will eventually be moved into the CTX struct in
Phase 3).
Executing 0x04: LOAD_VAR R1, 2 (Load the 3rd variable into R1):
 * Check current_oid. If invalid, trap.
 * Read the MOI node for current_oid.
 * Bounds Check: Ensure the requested index (2) is < var_count. If not, trap.
 * Calculate the memory location: target_index = state_offset + 2.
 * Read StateArena[target_index] and load the Tagged Pointer into R1.
Executing 0x05: STORE_VAR R1, 2 (Store R1 into the 3rd variable):
 * Read the Tagged Pointer currently in R1.
 * Perform the same MOI lookup and bounds check.
 * Overwrite StateArena[state_offset + 2] with the Tagged Pointer.
   (Note: In a full implementation, if the old variable was a String/Array
Tag, we must call REF_DEC on the old Handle, and REF_INC on the new Handle.
For this MVP iteration, simply overwriting the integer is sufficient to prove
the architecture).
The Goal for Your Next Dev-Session
In your dev-environment, your objective is to build the MOI and State Arena,
and prove they interact flawlessly.
Write a JS test script that:
 * Creates a mock Blueprint Registry entry requiring 3 variables.
 * Executes the clone_object logic to allocate an instance in the MOI and
State Arena.
 * Manually sets vm.current_oid to this new instance.
 * Executes a raw bytecode array that uses STORE_VAR to save a Tagged Integer
(42) into variable index 1.
 * Executes LOAD_VAR to pull it back out into a different register.