Skip to content

Project Architecture

The plugin architecture is layered to keep systems modular and testable while supporting flexible game integration.

LayerContentsNotes
Resource ConfigurationGBConfig, GBSettings, GBTemplates, GBMessages, rule resourcesEditable in inspector; serialized with project
Composition & InjectionGBCompositionContainer, GBInjectorSystemProvides dependency injection & lazy construction
Core SystemsPlacement, Targeting, Building, Manipulation, Validation, IndicatorEach focuses on a single domain concern
State ContainersGBStates (mode, targeting, building, manipulation)Shared by injected nodes; supports multi-context
ContextsGBContexts (placement, systems, owner, level)Encapsulate environment dependencies
UI & InteractionAction bar, selection lists, info displaysDriven by states & actions resources
Testing UtilitiesFactories, reports, test setupsFacilitate GdUnit coverage & deterministic assertions

Instead of global singletons, systems resolve dependencies from the injected composition container. Benefits:

  • Multitenancy (multiple players/levels)
  • Clear test seams (swap in a fresh container)
  • Lazy provisioning (logger/settings only built when required)

Nodes opt‑in via resolve_gb_dependencies pattern. See the Dependency Injection document.

Instead of a complex diagram, let’s walk through how the Grid Building system works in simple steps:

  1. You pick something to build: Click a placeable in the UI
  2. BuildingSystem wakes up: enter_build_mode() gets called with your choice
  3. GridPositioner2D handles targeting: Processes mouse/keyboard input to track where you’re pointing on the grid
  4. TargetingShapeCast2D detects collisions: Updates collision state based on GridPositioner2D position
  5. IndicatorManager provides live feedback: Sets up indicators that follow your cursor and show placement validity
  6. PlacementValidator checks rules: Runs tile-based rules as you move the cursor around
  7. IndicatorManager shows visual feedback: Colors/animations appear to show valid/invalid spots in real-time
  8. ManipulationSystem (optional): If enabled, lets you move/rotate the preview before placing
  9. You confirm placement: BuildingSystem.try_build() runs full validation (including non-tile rules)
  10. Object gets created: If everything checks out, your building appears in the world as a PlaceableInstance
  11. ManipulationSystem (post-placement): Now you can select, move, rotate, or delete the placed object

Clean System Boundaries:

GridPositioner2D ← Pure input handling & positioning
├── TargetingShapeCast2D ← Dedicated collision detection
└── ManipulationParent ← Transform handling container
├── IndicatorManager ← Visual feedback & validation manager
│ ├── RuleCheckIndicator ← Individual rule indicators
│ └── RuleCheckIndicator ← Individual rule indicators
└── PreviewObject ← Object being manipulated

Benefits:

  • Unit testable components - Each system tested in isolation
  • Composable collision strategies - Swap targeting implementations
  • Eliminated race conditions - No hidden coupling between systems
  • Reliable test execution - Consistent behavior in all environments
  • BuildingSystem orchestrates the entire build workflow - from mode entry to final placement
  • GridPositioner2D handles all input processing and grid coordinate conversion
  • IndicatorManager manages the visual feedback system (creates and parents rule indicators)
  • ManipulationParent serves as transform container for preview objects and indicators
  • ManipulationSystem has two jobs: preview adjustment (if enabled) and post-placement editing
  • Validation happens twice: quick tile rules during preview, full rule validation on confirmation
  • Each component has a single responsibility but they work together seamlessly
  1. UI Selection → User selects placeable from UI → BuildingSystem.enter_build_mode(placeable) is called
  2. Build Mode Initialization: BuildingSystem prepares preview with selected placeable
  3. Input Processing: GridPositioner2D processes mouse/keyboard input and converts to grid coordinates
  4. Collision Detection: TargetingShapeCast2D updates collision state based on positioner position
  5. Live Validation: PlacementValidator runs tile rules, IndicatorManager shows live feedback via rule indicators
  6. Preview Manipulation: If enabled in placeable settings, ManipulationSystem can move/rotate preview instances during placement
  7. Confirmation: User confirms placement, BuildingSystem.try_build() runs full rule validation (including non-tile rules)
  8. Instantiation: If valid, BuildingSystem spawns PlaceableInstance with metadata for manipulation & save/load
  9. Post-Placement: ManipulationSystem handles move/rotate/delete operations on placed instances

PlaceableInstance holds references back to originating Placeable enabling reconstruction. Systems should avoid storing raw scene node references across sessions; rely on IDs or resource paths.

GBDebugSettings gates verbosity. High verbosity surfaces:

  • Injection operations
  • Indicator setup summaries
  • Rule validation traces (future extension)
  • Favor composition (create a new rule resource) over conditionals inside existing rules.
  • Keep resource scripts lean; complex logic belongs in systems.
  • Add new UI affordances by observing states rather than polling systems directly.
  • Cross-context synchronization primitives (multiplayer scenarios).
  • Performance profiling hooks (duration_ms in reports).
  • Rule documentation tooling.

  • Context & State – Distinguishes long‑lived context objects from frequently mutating state containers; essential for understanding rule evaluation purity.
  • Placement Chain – End‑to‑end flow from input to instantiated object.
  • Dependency Injection – Container pattern enabling multi‑tenant/testable setup.
  • Placement Rules Pipeline – Validation composition & indicator generation.

Core Components:

Data Flow:

Last updated: 2025-08-20