Composition + injection (5.0.2)
How the 5.0.2 container/injector era wires systems together at initialization time.
Weight: 15
5.0.2 projects typically wire GridBuilding through a composition container and an injector pattern.
Initialization vs Runtime
This guide covers initialization-time dependency injection — wiring settings, services, and state when the scene loads.
For runtime placement validation (rules that run when placing objects), see Placement Rules.
The intent (5.0.2)
- Centralize dependency wiring (settings, state, references) so scene nodes do not hand-wire everything.
- Allow test environments to stand up “the whole stack” by instantiating a known scene.
Common 5.0.2 wiring pattern
1
2
3
4
5
6
7
| Scene root
↓
GBInjectorSystem / composition container
↓
Systems (BuildingSystem, ManipulationSystem, GridTargetingSystem, IndicatorManager)
↓
Shared state objects (mode/targeting/building/manipulation)
|
Testing implication (5.0.2)
Some features require a full environment scene to exist (not a minimal unit harness).
Example from the 5.0.2-era manipulation architecture notes:
- Minimal collision test scenes are good for geometry/collision math.
- But manipulation workflow tests require an “all systems” environment so that:
ManipulationSystem existsManipulationParent exists- targeting/building/indicator systems are present
This is one of the reasons the later 6.0 architecture tries to push more logic into testable services and shrink the engine glue surface.
Example: Basic Injector Setup
Here’s a concrete example of setting up the injector system in 5.0.2:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| # Main scene script that sets up the composition container
# See: res://addons/grid_building/test/e2e/all_systems_integration_tests.gd
class_name GameLevel
extends Node2D
@onready var injector: GBInjectorSystem = $GBInjectorSystem
func _ready() -> void:
# 1. Create the container (the root of all configuration)
# See: res://addons/grid_building/test/resources/composition_containers/test_composition_container.tres
var container := GBCompositionContainer.new()
# 2. Configure the GBConfig sub-resource
# This holds your settings, templates, and actions
# See: res://addons/grid_building/resources/gb_config.gd
container.config = GBConfig.new()
container.config.settings.building.add_placeable_instance = true
# 3. Assign the container to the injector
# The injector will automatically find nodes in the scene tree
# and call resolve_gb_dependencies(container) on them.
# See: res://addons/grid_building/systems/injection/gb_injector_system.gd (_ready -> _initialize -> _inject_existing)
injector.composition_container = container
# 4. (Optional) Manual validation
# The injector runs validation automatically on ready, but you can
# trigger it manually if you update configuration at runtime.
# See: res://addons/grid_building/systems/injection/gb_injector_system.gd (run_validation method)
injector.run_validation()
|
Dependency Resolution
In 5.0.2, nodes implement resolve_gb_dependencies(container: GBCompositionContainer) to receive their dependencies. Note that there is no implements keyword in GDScript; the injector simply checks for the method’s existence.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| # Example: A custom node receiving dependencies
# See: res://addons/grid_building/test/building/workflows/building_and_placement_tests.gd
class_name MyCustomBuildingNode
extends Node2D
var _building_settings: BuildingSettings
var _logger: GBLogger
func resolve_gb_dependencies(container: GBCompositionContainer) -> void:
# Access services and settings through the container
# See: res://addons/grid_building/resources/gb_composition_container.gd
_building_settings = container.get_settings().building
_logger = container.get_logger()
_logger.log_info("Custom node injected successfully!")
|
Scene Hierarchy
The standard 5.0.2 hierarchy places the injector and core systems near the scene root:
1
2
3
4
5
6
7
8
9
| GameLevel (Node2D)
├── GBInjectorSystem # Dependency injection
├── BuildingSystem # Placement management
├── GridPositioner2D # Snapping cursor
│ └── ManipulationParent # Rotation/Flipping
├── TileMapLayer # Grid source
├── Camera2D # Viewport
└── UI
└── PlaceableSelectionUI
|
Custom Injection Target
Since 5.0.2 uses method-based injection, you can easily extend the pattern for your own game services:
1
2
3
4
5
6
7
8
| # In your custom BuildingSystem or other node
func resolve_gb_dependencies(container: GBCompositionContainer) -> void:
# Standard dependencies
_logger = container.get_logger()
# Custom dependencies can be retrieved via meta or global services
# if they aren't part of the standard GBCompositionContainer
var economy = get_node("/root/Economy")
|
Testing with Full Environment
In 5.0.2, integration tests often use a specialized environment node to stand up the stack. See GBTestEnvironment for the implementation details.
1
2
3
4
5
6
7
8
9
10
11
| # Test helper example (similar to AllSystemsTestEnvironment)
# See: res://addons/grid_building/test/e2e/all_systems_integration_tests.gd
func test_placement_integration() -> void:
# stand up the environment
# See: res://addons/grid_building/test/scenes/env/gb_test_environment.gd
var runner := scene_runner("**res://addons/grid_building/test/scenes/env/all_systems_test_environment.tscn**")
var env := runner.scene() as AllSystemsTestEnvironment
# Access injected systems
var building_sys = env.building_system
assert_not_null(building_sys)
|
Cross Test Validation
- Injection Logic: res://addons/grid_building/systems/injection/gb_injector_system.gd — Core implementation of the recursive injection pattern:
_ready() and _initialize(): Trigger automatic injection when composition_container is assignedinject_recursive(): Performs initial scene tree injection_on_child_entered_tree(): Handles runtime node injection via signal callback_validate_after_injection(): Runs automatic validation after injection completes
- Integration Tests: res://addons/grid_building/test/e2e/all_systems_integration_tests.gd — Validates that all systems in a standard scene receive their dependencies.
- Environment Setup: res://addons/grid_building/test/scenes/env/gb_test_environment.gd — Demonstrates the “canonical” way to stand up a wired 5.0.2 environment for testing.
- Configuration Validation: res://addons/grid_building/test/utilities/gb_configuration_validator_test.gd — Confirms that the injector correctly triggers validation after wiring.