Architecture¶
The framework is a pipeline from “a structure exists in the registry” to “real
IsoObjects exist in the world, in a room, synced to everyone.” Each stage is a module you
can use, replace, or skip.
The pipeline¶
register → plan → validate → resolve materials → build → finalize
The numbered steps below walk each stage and name the module(s) that own it.
Registration -
Registry.registerStructurerecords a def;PieceLibraryrecords the pieces a player can paint. This is all that’s required for a structure to exist.A plan is produced - either interactively by the
RCStructurePlacementUI(drag a footprint, paint pieces) or programmatically by you. The result is anRCSFPlan: rects, walls, cells, roofs, and entity pieces in world coordinates.Validation -
PlacementValidationruns the default validators you opted into, then your customvalidate*callbacks.Material resolution - a
MaterialSourceis resolved from the def ("raw"/"universal"/"bag"or a custom factory).Build -
Builder.buildFromPlanwalks the plan piece by piece. Each piece kind (wall, cell, roof, furniture, …) has a handler that consumes its material, resolves its sprite, and places theIsoObjectviaPlacementHelpers. Any failure rolls the whole build back.Finalize - the room is created (
RoomPersistence), lighting wired (RoomLighting), andOnRCSFStructureBuiltfires.
The interactive path wraps steps 3-6 in a server-authoritative timed action; the
headless path (RCSF.build) runs them directly on the server.
Modules by job¶
Job |
Module(s) |
|---|---|
Structure & piece registration |
|
Interactive placement UI |
|
Plan data + geometry |
|
Validation |
|
Material consumption (pluggable) |
|
Generic per-piece builder + rollback |
|
Runtime |
|
Light switches in runtime rooms |
|
Door/window-frame walkability fix |
|
Ghost-preview persistence (across relogs) |
|
Presets (save/load layouts) |
|
Disassembly + refund |
|
Headless entry points |
|
Two design choices worth knowing¶
Pluggable piece kinds. The builder dispatches on a small registry of piece-kind handlers
(wall, cell, roof, furniture, appliance, decorative, vegetation). You can
Builder.registerPieceKind(name, handler) to add your own kind without touching the core
loop.
Warn, don’t throw. Registration validates your def but only errors on a missing id;
everything else is a warning. This keeps a mod built against a newer framework version from
hard-crashing on an older one (forward compatibility). See
registration is validated.
See also
The plan - the data structure steps 2-5 pass around.
Authority & rooms - what makes steps 5-6 multiplayer-safe.
Vendoring - which of these modules you can use standalone.