How One Edit Becomes a Building
In Pascal Editor, a visible wall or room is the end of a chain that begins with a semantic scene change. This chapter follows that chain from a user or agent mutation through the scene store, invalidation, registry lookup, geometry construction, and the viewer/editor boundary. The practical goal is to help the reader decide which layer should respond when a wall, opening, or room changes—and why a node that is valid in isolation can still produce an incomplete building result.
Take the small example from the scene model: a wall has two plan endpoints and a door hosted on it. Changing the wall's endpoint is not just a new pair of numbers. It can affect the wall's junction with a neighbour, the cutout for the door, the door's available position, the room boundary, and the floor-plan line. Pascal's rendering architecture exists to carry those relationships forward without making the rendered mesh the authority.
A wall edit begins in scene state
A user may drag a wall endpoint, an editor tool may create a room, or an agent may update a node through MCP. Each route ultimately targets the core scene store. The store changes the semantic node, records the document mutation for undo and redo, and marks relevant work for downstream consumers. The important event is the committed change to the graph. Rendering reacts to that event; it does not define it.
The store's dirty-node set is the bridge between document state and derived work. A mark means that a geometry or rendering consumer should inspect the node and rebuild or update something. For a wall, that may include a new mesh, a different miter at a junction, or a changed cutout around a hosted door or window. For a floor-placed item, the relevant work may be its support elevation. The mark is cleared when the responsible consumer has finished. It is a work request, not a permanent description of the node.
This distinction is useful when the application is busy. Pascal can avoid recomputing every wall and item on every frame by processing only marked nodes. It also avoids treating every relationship as a reason to redraw the whole scene. At the same time, the dependency must be explicit. If a wall's shape affects a neighbouring wall, the neighbour must be invalidated too. If a ceiling or stair depends on a changed level or slab, its own system must receive the corresponding signal.
The store guards this queue for kinds that have no dirty consumer. A mark that no system can clear would remain for the life of the session and make the runtime appear perpetually busy. That guard reflects a broader rule: a state transition should have an owner. The scene store owns the fact that a node changed; the geometry or viewer system owns the work needed to make a projection agree with it.
The registry connects IDs to live objects
Once the browser mounts the scene, renderers create Three.js groups or meshes for nodes. The scene registry maps each node ID to its live Object3D, and also maintains sets by type. A wall system can therefore find the registered object for a particular wall or iterate the walls it needs without traversing the entire Three.js tree. Registration happens as part of the renderer's mount lifecycle and is removed when that renderer unmounts.
That map is deliberately runtime state. It is not saved beside the node graph, and it cannot be assumed to exist in a headless MCP process. A graph may be loaded before a renderer mounts, or a renderer may temporarily be unavailable. The graph remains meaningful in either case; the registry is a current index of a projection.
The separation also constrains how a renderer should behave. A node has one registered representative, usually an outer group even when the visible result contains several meshes. Systems look up that representative when they need to change geometry, transforms, or named subparts. They do not retain a reference indefinitely across frames, because the renderer can be remounted and the live object can change.
Context lets geometry depend on relationships without owning state
Pascal's registry-driven node definitions offer a pure geometry builder for kinds whose meshes are a function of node data and related context. The builder receives the node plus a GeometryContext: it can resolve another node by ID, inspect resolved children, see same-kind siblings, and access a parent. It returns local-space geometry. It does not import the scene store or mutate it.
That design is particularly important for walls. A wall's geometry may depend on adjacent walls for corner mitering and on its child doors or windows for cutout footprints. A door or window may need the parent wall's thickness to align its frame with the opening. The builder can receive those relationships as inputs while remaining a function that can be tested with ordinary data. The scene store supplies context; the builder calculates a result.
The generic geometry system consumes the result. It finds the registered group, calls the builder for a dirty node, disposes the prior geometry children that the builder created, attaches the replacement children, and clears the dirty mark. A custom per-kind system may run alongside this process when the kind also needs animation, named-mesh material updates, or a cross-kind cascade. It is not a competing source of geometry truth.
This arrangement has a subtle but important ownership rule. A registered group can contain both children created by a geometry pass and children mounted by React for hosted nodes. The rebuild path must dispose only the generated geometry, not a hosted door or item that another part of the scene is still responsible for. In other words, rebuilding a projection must not destroy semantic children merely because they happen to share a runtime group.
The sequence has two stopping points worth keeping separate. In a browser, the chain can continue into Three.js and a floor-plan projection. In headless MCP, the bridge can still change the graph, run schema validation, and report dirty IDs, but no browser renderer consumes those marks. A successful agent mutation is therefore a semantic state change, not evidence that a new mesh has been built in the agent process.
Coordinates carry architectural meaning
Geometry becomes harder when a point's meaning depends on its frame. Pascal uses X and Z for the ground plane and Y for vertical position. Lengths are in metres and rotations are in radians. A wall's start and end are level-local plan points. A door attached to that wall uses a wall-local position along the wall. Treating that position as a global plan coordinate would put the door in the wrong place as soon as the wall rotated or moved.
The viewport adds another possible source of confusion. A plan panel may rotate its content for the user's view, while a three-dimensional top-down camera can retain its own azimuth. A layout computed outside the editor must therefore distinguish stored world conventions from screen orientation. The editor's own tools are internally consistent, but external geometry should be checked against known anchors rather than assuming that “up” on a source drawing means world Y or that the screen's horizontal axis is world X.
Vertical placement adds relationships that cannot be recovered from X and Z alone. A level has a height and a position in the building stack. A slab has an elevation and thickness. A wall may follow a level plane, attach to a support, or preserve an explicit height. A floor item may need the highest valid surface under its footprint. A ceiling may be clamped by the level or by a covering slab. These rules preserve authored intent while allowing the surrounding building to determine the effective result.
This is why Pascal's placement checks return more than a yes-or-no answer in some cases. A wall-attached item can receive an adjusted vertical position so it sits correctly on its host. A floor placement can be checked against rotation-aware dimensions and existing objects. A room-furnishing operation can protect a door clearance area and nudge or skip an item if the proposed footprint overlaps another item or leaves the room bounds.
The cost is that a point is no longer self-explanatory. A correct tool must know whether it is placing on a level, slab, wall, ceiling, or terrain-supported surface. A geometry builder that hardcodes a base of zero can look correct on a flat scene and fail on a sculpted site. The benefit is that the same scene can express support and intent instead of baking a fragile, one-time world transform into every object.
The 2D plan and 3D view are related projections
Pascal's node definitions can supply both 3D geometry and pure floor-plan geometry. The floor-plan side emits SVG-renderable data—lines, polygons, labels, images, handles, and dimensions—while the host applies the view transform. It does not require every node kind to own a separate semantic representation. A wall can remain one node while its 3D and 2D projections use the same endpoints, children, and contextual relationships.
The distinction matters during interaction. A floor-plan move may need to re-anchor a door to a different wall or move an attached item onto a ceiling or slab. The move handler can use the node's semantic host and commit a new relationship, rather than simply translating a screen-space icon. Similarly, live previews can use temporary overrides and commit once, so pointer movement does not create a stream of permanent document writes.
The editor's tools and overlays are not forced into the viewer package. The viewer stays responsible for presentation state such as camera, selection, level display, wall mode, theme, and visibility toggles. The editor injects tool managers, snap indicators, selection boxes, and other editor-specific systems as children. This lets the same viewer support a read-only route or an embedded application without importing the editor's private state.
That separation is a product capability. A read-only viewer can render a scene without pretending to offer editing. An embed can mount a 3D canvas with a 2D plan or split view. The full editor can add direct manipulation without changing what the core node means. Each surface has a clear owner, so a feature can be evaluated by asking whether it belongs to the document, the projection, or the interaction layer.
When the picture and the model disagree
This architecture does not eliminate failure; it makes different failures distinguishable. If a node fails schema validation, the problem is at the data boundary. If a wall is valid but its neighbour was not invalidated, the problem is dependency propagation. If the graph is correct but the registry has no object, the problem is a mount or runtime condition. If a door appears in the wrong place, the problem may be a wall-local versus plan-coordinate error or an incorrect support frame. If the MCP process reports success but the browser does not change, the missing renderer or live-sync boundary must be examined rather than blamed on geometry.
The same distinctions prevent a common overclaim. A rendered wall is evidence that one projection currently represents the graph. It is not, by itself, proof that every opening is correctly hosted, that every level has appropriate rooms, or that the layout satisfies a real construction requirement. Those judgments belong to schema-aware verification and spatial checks, and some remain outside the repository's supported evidence.
Pascal's edit-to-building flow is therefore a controlled chain, not a magic conversion from data to pixels. The store owns semantic change and history. The registry indexes live objects. Pure builders calculate local geometry from explicit context. Systems consume invalidation and maintain derived projections. Spatial rules resolve hosts and supports. The viewer renders, while the editor supplies interaction. Once those roles are clear, the next question is whether they remain coherent when several projections and clients are considered together.