A configurable building contains repeated parts with different responsibilities. Some determine dimensions. Some render surfaces. Some participate in selection. Others exist only in a material schedule.
An entity-component approach can organize those responsibilities, but it is a tool for a particular complexity, not a mandatory replacement for a scene graph.
Give parts stable identity
A window should remain the same window when its mesh is regenerated. A stud schedule should not depend on whichever object happened to be inserted first.
Use identifiers for meaningful parts and references for their relationships. Keep display names separate from identity.
This supports selection, undo, change tracking, and traceable output.
Separate data by use
A rendering system may need transforms and material handles. A constraint system may need dimensions and adjacency. A pricing system may need approved product identifiers.
Not every operation needs to traverse a large object containing all three.
Struct-of-arrays storage can help some repeated numerical workloads, but evaluate it against actual access patterns. Extra synchronization complexity can outweigh a theoretical locality advantage in a small application.
Track what became dirty
When the building gets longer, identify the affected assemblies. Avoid rebuilding unrelated materials, cameras, or interface state.
A dependency graph can make invalidation explicit. If a roof depends on a wall outline, that relationship should be represented in the model.
Be careful with partial GPU updates: the changed range must agree with the buffer layout and the current allocation.
Keep physics and rendering connected
If a worker updates simulation state, exchange a compact set of identified values. Handle creation and deletion on both sides.
A stale body identifier should not update a newly created object that reused the same array position. Generation counters or similarly explicit identities help prevent this class of error.
The scene graph can still be a useful rendering representation. It does not have to be the application’s complete domain model.
Keep buffer layout out of domain identity
A compact render buffer is an output of the model. Maintain a mapping from stable entity IDs to current buffer slots, and version that mapping when compaction moves entries. A delayed worker result should carry both the entity generation and the configuration revision that produced it.
The current Three.js BufferAttribute reference defines update ranges in attribute components, not vertices. For a three-component position attribute, a vertex range must be multiplied by three before marking the corresponding components dirty. Interleaved and packed layouts need their own calculation.
Test deletion in the middle of a packed buffer followed by a delayed update for the deleted entity. The replacement object must retain its own transform. This targets a realistic corruption path that a large scene benchmark might miss.
Compare incremental results with a clean rebuild
Property-based testing can explore combinations that handwritten fixtures overlook. fast-check provides generated inputs and shrinking of failing examples; the application still has to define a meaningful property.
For a building editor, generate bounded sequences of valid additions, moves, deletions, and undo operations. After each sequence, compare the incremental result with a fresh derivation from the saved domain document. Compare stable IDs, quantities, dimensions, and normalized relationships rather than incidental array order.
Use tolerances justified by the numerical operation for coordinates; use exact equality for identities and counts. Save the random seed and minimized failing sequence. Start with a small model where a person can inspect the expected structure, then expand the generator only after the reference derivation is trusted.
Test the dependency chain
Change one parameter and inspect which outputs changed. Verify dimensions, part counts, selection identity, and the final image.
Then test deletion, undo, rapid changes, and restoring a saved document. Those operations reveal hidden assumptions about ordering.
Choose the simplest representation that keeps the relationships clear. The goal is to make a building understandable to the software, not to make the software resemble a particular engine architecture.
Keep a good idea close.
Follow Signal Tower


