Composition + injection (5.0.3)

5.0.3 projects wire GridBuilding through a composition container and an injector pattern.

If you are coming from the setup flow, complete Getting Started (5.0.3) first. This guide explains the wiring layer that sits behind that setup, not the initial addon install and first placement sequence.

What the container actually owns

GBCompositionContainer is the canonical composition root for one runtime grid-building context. Through helper methods it provides:

  • GBConfig
  • GBSettings
  • GBTemplates
  • GBActions
  • GBLogger
  • GBContexts
  • GBStates

Use one container per active runtime context.

What the injector actually does

GBInjectorSystem:

  • requires composition_container
  • injects any node that implements resolve_gb_dependencies(...)
  • performs initial recursive injection
  • injects newly added nodes inside the injection scope
  • runs editor validation automatically

Important runtime detail:

  • the injector helps with wiring
  • runtime validation is only meaningful once GBLevelContext and GBOwner have populated the contexts/states your systems depend on

Canonical scene wiring

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
MainLevel
  -> World
      -> TileMapLayer
      -> ObjectsRoot
      -> GBLevelContext
  -> Systems
      -> GBInjectorSystem
      -> BuildingSystem
      -> GridTargetingSystem
      -> GridPositioner2D
      -> TargetingShapeCast2D
      -> ManipulationSystem
      -> ManipulationParent
  -> Player
      -> GBOwner
  -> UI

Required scene contracts

  • GBInjectorSystem.composition_container must be assigned
  • GBLevelContext.target_map must be assigned
  • GBLevelContext.objects_parent must be assigned
  • GBOwner.owner_root must be assigned
  • any node that needs plugin dependencies must implement resolve_gb_dependencies(container: GBCompositionContainer)

What resolve_gb_dependencies(...) means

There is no formal interface keyword here. The injector simply checks whether a node has the method and, if so, calls it.

Typical runtime patterns:

  • GBOwner.resolve_gb_dependencies(...) registers the active owner into owner context
  • GBLevelContext.resolve_gb_dependencies(...) applies level maps and placement parent into the states
  • systems such as BuildingSystem, GridTargetingSystem, and ManipulationSystem register themselves into GBSystemsContext
  • UI and helper nodes read state/context references from the container
1
2
3
4
5
6
@onready var injector: GBInjectorSystem = $Systems/GBInjectorSystem

func _ready() -> void:
    var container: GBCompositionContainer = preload("res://path/to/my_container.tres")
    injector.composition_container = container
    injector.run_validation()

What should be in the container resource

  • config.settings.building
  • config.settings.manipulation
  • config.settings.targeting
  • config.settings.placement_rules
  • config.templates
  • config.actions

Example injection target

1
2
3
4
5
6
7
extends Node2D

func resolve_gb_dependencies(container: GBCompositionContainer) -> void:
    var states: GBStates = container.get_states()
    var systems: GBSystemsContext = container.get_systems_context()
    var logger: GBLogger = container.get_logger()
    var targeting_settings: GridTargetingSettings = container.get_settings().targeting

What is not automatic

  • the injector does not invent a GBLevelContext for you
  • the injector does not invent a GBOwner for you
  • the injector does not make placement work if target_map, objects_parent, or owner wiring are missing
  • the injector does not replace calling real system entry points like enter_build_mode(placeable)

Plugin-user checklist

  • create a GBCompositionContainer resource
  • assign a valid GBConfig
  • add GBInjectorSystem to your scene
  • assign composition_container
  • add GBLevelContext
  • assign target_map and objects_parent
  • add GBOwner
  • assign owner_root
  • add the systems/nodes you want to use
  • trigger placement through the system API or injected UI