Composition Container Configuration (v5.0)

The GBCompositionContainer is the central configuration hub for GridBuilding v5.0, organizing all sub-resources and providing dependency injection for the building system.

For a complete setup overview, see Getting Started Setup.

Overview

The composition container follows a hierarchical resource structure where each sub-resource controls a specific aspect of the building system. This design allows for modular configuration and live updates without system restarts.

Resource Hierarchy

GBCompositionContainer (Resource)
├── config: GBConfig
│   ├── settings: GBSettings
│   │   ├── building: BuildingSettings
│   │   ├── manipulation: ManipulationSettings  
│   │   ├── targeting: GridTargetingSettings
│   │   ├── visual: GBVisualSettings
│   │   ├── action_log: ActionLogSettings
│   │   ├── placement_rules: Array[PlacementRule]
│   │   ├── runtime_checks: GBRuntimeChecks
│   │   └── debug: GBDebugSettings
│   ├── templates: GBTemplates
│   └── actions: GBActions

Creating Resources (Editor-Based Approach)

Important: For v5.0, resource assignment must be done manually in the Godot Editor Inspector. There is no automatic assignment of resources. You must manually create and assign each sub-resource. Save frequently to prevent data loss.

Step 1: Base Container (Editor)

  1. In the Inspector, click “Create New Resource”
  2. Search for and select GBCompositionContainer
  3. Save immediately as composition_container.tres to prevent data loss
  4. Assign this resource to your InjectorSystem’s composition_container property

Step 2: Main Config (Editor)

  1. Click the config property in your composition container
  2. Select “Create New Resource” → GBConfig
  3. Save immediately as config.tres to prevent data loss
  4. The config is manually assigned to the container

Step 3: Settings Container (Editor)

  1. Click the settings property in your config resource
  2. Select “Create New Resource” → GBSettings
  3. Save immediately as settings.tres to prevent data loss
  4. The settings are manually assigned to the config

Step 4: Individual Settings (Manual Assignment Required)

Important: Each individual setting resource must be manually created and assigned:

  1. Building Settings:

    • Click building property in GBSettings
    • Select “Create New Resource” → BuildingSettings
    • Save immediately as building_settings.tres
  2. Manipulation Settings:

    • Click manipulation property in GBSettings
    • Select “Create New Resource” → ManipulationSettings
    • Save immediately as manipulation_settings.tres
  3. Targeting Settings:

    • Click targeting property in GBSettings
    • Select “Create New Resource” → GridTargetingSettings
    • Save immediately as targeting_settings.tres
  4. Visual Settings:

    • Click visual property in GBSettings
    • Select “Create New Resource” → GBVisualSettings
    • Save immediately as visual_settings.tres
  5. Templates:

    • Click templates property in GBConfig
    • Select “Create New Resource” → GBTemplates
    • Save immediately as templates.tres
  6. Actions:

    • Click actions property in GBConfig
    • Select “Create New Resource” → GBActions
    • Save immediately as actions.tres

Critical: Save each resource immediately after creation to prevent data loss if Godot crashes or the project is closed unexpectedly.

Why Editor-Based Assignment?

  • Visual Validation: The Inspector shows missing properties and validation errors
  • Type Safety: Godot ensures correct resource types are assigned
  • Live Updates: Changes propagate immediately to all systems
  • Debugging: Easy to inspect resource contents during development
  • Performance: No runtime loading overhead

Script-Based Assignment (Advanced Only)

1
2
3
4
5
6
7
# Only use this pattern if you need dynamic resource loading
# Most users should use the Inspector approach instead

func load_custom_configuration():
    var custom_config = preload("res://settings/custom_config.tres")
    $Systems/InjectorSystem.composition_container = custom_config
    # Note: This bypasses editor validation and can cause runtime errors

Individual Settings Configuration

BuildingSettings

Controls core building and placement behavior:

1
2
3
4
5
6
# Example building settings
extends BuildingSettings
@export var grid_size: Vector2i = Vector2i(16, 16)
@export var placement_validation: bool = true
@export var cost_requirements: Array[Resource] = []
@export var building_rules: Array[Resource] = []

Key Properties:

  • grid_size: Size of building grid cells
  • placement_validation: Enable/disable placement checks
  • cost_requirements: Resource costs for building
  • building_rules: Custom building logic rules

ManipulationSettings

Controls object movement and editing:

1
2
3
4
5
# Example manipulation settings
extends ManipulationSettings
@export var drag_sensitivity: float = 1.0
@export var snap_to_grid: bool = true
@export var manipulation_modes: Array[String] = ["move", "rotate", "delete"]

Key Properties:

  • drag_sensitivity: Mouse drag sensitivity
  • snap_to_grid: Force grid snapping during manipulation
  • manipulation_modes: Available editing modes

GridTargetingSettings

Controls grid targeting and selection:

1
2
3
4
5
6
# Example targeting settings
extends GridTargetingSettings
@export var target_range: float = 100.0
@export var selection_shape: Shape2D
@export var collision_layers: int = 1
@export var target_highlight_color: Color = Color.YELLOW

Key Properties:

  • target_range: Maximum targeting distance
  • selection_shape: Shape for target detection
  • collision_layers: Physics layers for targeting
  • target_highlight_color: Visual feedback color

GBVisualSettings

Controls UI and visual feedback:

1
2
3
4
5
6
# Example visual settings
extends GBVisualSettings
@export var cursor_style: Texture2D
@export var highlight_color: Color = Color.CYAN
@export var show_target_info: bool = true
@export var ui_scale: float = 1.0

Key Properties:

  • cursor_style: Custom cursor texture
  • highlight_color: Selection highlight color
  • show_target_info: Display target information
  • ui_scale: UI element scaling

ActionLogSettings

Controls logging system behavior:

1
2
3
4
5
6
# Example action log settings
extends ActionLogSettings
@export var max_messages: int = 100
@export var message_duration: float = 5.0
@export var log_level: String = "INFO"
@export var show_timestamps: bool = true

Key Properties:

  • max_messages: Maximum logged messages
  • message_duration: How long messages display
  • log_level: Minimum log severity
  • show_timestamps: Include time information

Placement Rules

Array of validation rules for placement:

1
2
3
4
5
6
7
8
# Example placement rule
extends PlacementRule
@export var name: String = "Terrain Rule"
@export var terrain_types: Array[String] = ["grass", "stone"]

func can_place(position: Vector2i, context: PlacementContext) -> bool:
    var terrain = get_terrain_at(position)
    return terrain_types.has(terrain)

Common Rule Types:

  • Terrain validation
  • Cost requirements
  • Space availability
  • Custom game logic

GBRuntimeChecks

Controls system validation and debugging:

1
2
3
4
5
# Example runtime checks
extends GBRuntimeChecks
@export var enable_debug_overlays: bool = false
@export var performance_monitoring: bool = true
@export var strict_validation: bool = true

GBDebugSettings

Development and debugging configuration:

1
2
3
4
5
# Example debug settings
extends GBDebugSettings
@export var log_level: GBDebugSettings.LogLevel = GBDebugSettings.LogLevel.INFO
@export var show_debug_ui: bool = false
@export var enable_profiling: bool = false

Templates Configuration

GBTemplates

Define system and UI templates:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# Example templates
extends GBTemplates
@export var system_templates: Dictionary = {
    "standard": preload("res://templates/systems/standard_systems.tscn"),
    "isometric": preload("res://templates/systems/isometric_systems.tscn")
}
@export var ui_templates: Dictionary = {
    "selection_ui": preload("res://templates/ui/placeable_selection_ui.tscn"),
    "action_bar": preload("res://templates/ui/action_bar.tscn")
}

Actions Configuration

GBActions

Define input mappings:

1
2
3
4
5
6
7
8
# Example actions
extends GBActions
@export var action_mappings: Dictionary = {
    "build_confirm": "ui_accept",
    "build_cancel": "ui_cancel",
    "rotate_left": "rotate_left",
    "rotate_right": "rotate_right"
}

Resource Assignment Pattern

Critical: There is NO automatic assignment of resources. You must manually assign each sub-resource:

  1. Open your composition container resource in the Inspector
  2. For each property field (config, settings, building, manipulation, targeting, visual, templates, actions):
    • Click the property field
    • Select “Create New Resource” or “Load Resource”
    • Save immediately after creating each resource
  3. Repeat for all nested properties - each must be manually assigned

Visual Validation: The Inspector will show:

  • ✅ Green checkmarks for properly assigned resources
  • ❌ Red indicators for missing or invalid resources
  • ⚠️ Warnings for configuration issues

Save Strategy:

  • Save each resource immediately after creation
  • Use descriptive names (e.g., building_settings.tres, manipulation_settings.tres)
  • Keep all resources in a dedicated settings/ folder
  • Commit to version control frequently

Folder Structure

Use a consistent folder structure for organization:

res://settings/
├── composition_container.tres
├── config.tres
├── settings.tres
├── building/
│   ├── building_settings.tres
│   └── building_rules/
├── manipulation/
│   └── manipulation_settings.tres
├── targeting/
│   └── targeting_settings.tres
├── visual/
│   └── visual_settings.tres
├── templates/
│   └── templates.tres
└── actions/
    └── actions.tres

Script-Based Assignment (Advanced Only)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# WARNING: Only use this pattern for advanced dynamic loading scenarios
# Most users should use the Inspector approach instead

func load_runtime_configuration():
    # This bypasses editor validation and can cause runtime errors
    var custom_config = preload("res://settings/runtime_config.tres")
    $Systems/InjectorSystem.composition_container = custom_config
    
    # Manual validation required
    var issues = custom_config.get_runtime_issues()
    if not issues.is_empty():
        push_error("Configuration errors: " + str(issues))
        return false
    
    return true

When to Use Script-Based Assignment:

  • Multi-environment configurations (dev/staging/prod)
  • User-configurable settings
  • Mod support with custom configurations
  • A/B testing different configurations

Risks of Script-Based Assignment:

  • No editor validation
  • Runtime errors if resources are missing
  • Harder to debug configuration issues
  • Performance overhead from runtime loading

Shared Resource Behavior

All settings resources are shared Godot Resources with these properties:

  • Live Updates: Changes propagate immediately to all systems
  • Reference Sharing: Multiple systems can reference the same resource
  • Scene Local: Use resource_local_to_scene = true for per-scene instances

Example Live Update

1
2
3
4
# Change grid size at runtime
var settings = composition_container.get_settings()
settings.building.grid_size = Vector2i(32, 32)
# All systems immediately use the new grid size

Validation

The composition container provides automatic validation:

Editor Validation

  • Checks for missing required resources
  • Validates resource types and properties
  • Reports configuration issues in the Inspector

Runtime Validation

  • Verifies system dependencies
  • Checks runtime state consistency
  • Provides detailed error reporting
1
2
3
4
5
# Check configuration status
var issues = composition_container.get_runtime_issues()
if not issues.is_empty():
    for issue in issues:
        print("Configuration issue: ", issue)

Best Practices

1. Modular Organization

  • Keep individual settings in separate files
  • Use descriptive naming conventions
  • Group related settings together

2. Version Control

  • Commit resource files alongside code
  • Use meaningful commit messages for setting changes
  • Document breaking changes in settings

3. Performance Considerations

  • Avoid heavy computations in setting getters
  • Cache expensive calculations
  • Use lazy initialization where appropriate

4. Testing

  • Create test configurations for different scenarios
  • Validate settings with automated tests
  • Test live updates during gameplay

Common Configuration Patterns

Minimal Setup

1
2
3
4
5
6
7
# Basic configuration for prototyping
extends GBCompositionContainer

func _init():
    config = GBConfig.new()
    config.settings = GBSettings.new()
    # Uses default values for all sub-settings

Production Setup

1
2
3
4
5
6
7
8
# Full production configuration
extends GBCompositionContainer

@export var production_config: GBConfig

func _init():
    config = production_config
    # All settings pre-configured for production

Multi-Environment Setup

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Environment-specific configuration
extends GBCompositionContainer

func load_environment(env: String):
    match env:
        "development":
            config = preload("res://settings/dev_config.tres")
        "staging":
            config = preload("res://settings/staging_config.tres")
        "production":
            config = preload("res://settings/prod_config.tres")

Troubleshooting

Common Issues

  1. Missing Resources: Ensure all sub-resources are properly assigned
  2. Invalid References: Check that all resource paths are valid
  3. Type Mismatches: Verify resource types match expected classes
  4. Circular Dependencies: Avoid circular references between resources
  5. Data Loss: Resources not saved when Godot crashes or closes unexpectedly

Data Loss Prevention

Critical Issues:

  • Resources created but not saved before Godot crash
  • Manual assignment errors causing resource loss
  • Version control not committing resource files

Prevention Strategies:

1
2
3
4
5
6
7
# Save workflow checklist:
 Create resource
 Save immediately (Ctrl+S)
 Assign to parent property  
 Save parent resource
 Test in Inspector
 Commit to version control

Recovery Steps:

  1. Check Godot’s autosave/ folder for recent backups
  2. Look in your project’s .godot/ directory for cached resources
  3. Restore from version control if available
  4. Recreate missing resources using the detailed setup guide

Manual Assignment Verification

Checklist for Complete Setup:

  • GBCompositionContainer created and saved
  • GBConfig created, assigned, and saved
  • GBSettings created, assigned, and saved
  • BuildingSettings created, assigned, and saved
  • ManipulationSettings created, assigned, and saved
  • GridTargetingSettings created, assigned, and saved
  • GBVisualSettings created, assigned, and saved
  • GBTemplates created, assigned, and saved
  • GBActions created, assigned, and saved
  • All resources committed to version control

Debug Tools

  • Use get_runtime_issues() to identify problems
  • Enable debug settings for detailed logging
  • Check the Inspector for validation warnings

Integration with Systems

The composition container automatically integrates with:

  • InjectorSystem: Provides dependency injection
  • BuildingSystem: Uses building and placement settings
  • ManipulationSystem: Uses manipulation settings
  • TargetingSystem: Uses targeting and visual settings
  • UI Systems: Use templates and actions

This integration ensures all systems have access to the correct configuration without manual wiring.