Overview
Systems are React components that run in the render loop (useFrame) to update 3D geometry and transforms. They process dirty nodes marked by the store and use the scene registry to access Three.js objects directly.
System Pattern
Systems follow a consistent pattern:- Subscribe to
dirtyNodesfrom the scene store - Run in
useFrame(called every frame by React Three Fiber) - Check for dirty nodes of their target type
- Update Three.js geometry via scene registry
- Clear dirty flag when complete
packages/core/src/systems/wall/wall-system.tsx:26-81
Core Systems
The@pascal-app/core package provides systems for geometry generation:
WallSystem
Generates wall geometry with advanced features:- Mitering at wall junctions (corners and T-junctions)
- CSG cutouts for doors, windows, and items
- Slab elevation integration (walls extend below or sit on slabs)
packages/core/src/systems/wall/wall-system.tsx:106-137
Wall Mitering
The system calculates miter joints at wall junctions using computational geometry:packages/core/src/systems/wall/wall-mitering.ts:254-265
Mitering ensures clean corner and T-junction geometry without gaps or overlaps, even with walls of different thicknesses.
SlabSystem
Generates floor slab geometry from polygons:packages/core/src/systems/slab/slab-system.tsx:11-35
The geometry generator handles:
- Polygon extrusion
- Holes for openings (stairs, shafts)
- Automatic outset to extend under walls
packages/core/src/systems/slab/slab-system.tsx:40-155
ItemSystem
Positions items based on their attachment mode:packages/core/src/systems/item/item-system.tsx:13-58
CeilingSystem
Generates ceiling geometry (similar pattern to SlabSystem). Location:packages/core/src/systems/ceiling/ceiling-system.tsx
RoofSystem
Generates roof geometry from roof nodes. Location:packages/core/src/systems/roof/roof-system.tsx
WindowSystem & DoorSystem
Handle specialized item types for windows and doors. Location:packages/core/src/systems/window/window-system.tsx, packages/core/src/systems/door/door-system.tsx
System Priority
Systems run at different priorities (second argument touseFrame):
Lower priority numbers run first. This ensures slabs update before systems that depend on slab elevation data.
Scene Registry Integration
Systems access Three.js objects through the scene registry:useRegistry hook:
Processing Dirty Nodes
Systems only process nodes marked as dirty:Cascade Updates
Some systems need to update adjacent nodes:packages/core/src/systems/wall/wall-system.tsx:68-76
Adjacent walls are updated without clearing their dirty flag, as they may be dirty for other reasons.
Custom Systems
You can create custom systems following the same pattern:Best Practices
Early Exit
Check
dirtyNodes.size === 0 first to avoid unnecessary workType Filter
Filter by node type early to skip irrelevant nodes
Mesh Check
Check if mesh is registered before updating (keep dirty if not)
Dispose Geometry
Always dispose old geometry before replacing:
mesh.geometry.dispose()Clear Dirty
Only clear dirty flag after successful update
Priority Order
Set priority based on dependencies (lower = earlier)