Grid Placement
Development ⚠️ GridPlacement 6.0 (GECS) is in active development. This is the GDScript ECS architecture.

Validation and Rules (6.0)

Configure and debug the system-driven placement validation pipeline in 6.0 ECS.

In GridBuilding 6.0, validation is no longer a scattered set of function calls. Instead, it is a unified pipeline managed by the PlacementValidationSystem. This system runs every frame to ensure that the current placement intent (PlacementRequestComponent) is valid before execution is even considered.

The Validation Pipeline

Validation occurs in strict layers, ordered by cost and criticality. If an earlier layer fails, subsequent layers are skipped to save performance.

Layer 1: Base Sanity Checks

  • Purpose: Ensure the request itself is malformed.
  • Checks:
    • Is the placeable_id a valid resource path?
    • Is the target grid_position within the world boundaries?
    • Is the PlacementRequestComponent properly initialized?

Layer 2: Physics Query (Collision)

  • Purpose: Prevent overlapping with existing objects.
  • Mechanism: The system performs an intersect_shape query using the PhysicsServer2D.
  • Configuration: Rely on the collision layers/masks defined in your project settings. The “Placeable” layer should collide with “Terrain” and “Obstacles”.

Layer 3: Rule Evaluation

  • Purpose: Execute custom game logic.
  • Mechanism: The system iterates over all PlacementRuleComponent instances attached to the entity.
  • Examples:
    • ResourceConsumptionRule: Do I have enough gold?
    • SpacingRule: Am I too close to another tower?
    • BiomeRule: Can this tree grow on sand?

Configuring Rules (ECS)

In 6.0, rules are data components. To add a rule to a placeable object, you simply add the corresponding component to its entity definition (or scene root).

1
2
3
4
5
6
7
8
9
# Example: Adding a rule via code (or Scene editor)
var entity = Entity.new()

# 1. Base placement logic
entity.add_component(PlacementComponent.new())

# 2. Add specific rules
entity.add_component(ResourceConsumptionRuleComponent.new(wood_cost))
entity.add_component(BiomeRuleComponent.new(Biome.FOREST))

The PlacementValidationSystem automatically detects these components and includes them in the validation pass.

Creating New Rules

To create a new validation logic, you don’t need to register it in a central list. Just create the component and its system.

  1. Define Component:

    1
    2
    
    class_name StructureIntegrityRuleComponent extends Component
    @export var max_height: int = 5
    
  2. Define System:

    1
    2
    3
    4
    5
    
    class_name StructureIntegritySystem extends System
    func _process(delta):
        # Query for placement requests + rule component
        # Check logic
        # If fail, add failure to ValidationResultComponent
    
  3. Attach: Add the component to your building templates.

Debugging Failed Validation

When a placement fails, the system provides detailed feedback in the PlacementValidationResult.

Inspecting the Result

In your UI or debug script, you can listen to the validation signal:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
func _on_validation_update(result: PlacementValidationResult):
    if not result.is_valid:
        print("Validation Failed:")
        for issue in result.issues:
            print("- ", issue.message)
            
        # Check specific failure types
        if result.has_failure("collision"):
             show_red_outline()
        if result.has_failure("resource"):
             flash_resource_bar()

Common Issues

  • Ghost Collisions: If placement is blocked by “invisible” objects, check your collision layers. debug -> Visible Collision Shapes is your friend.
  • Missing Rule: If a rule isn’t running, ensure the component is actually added to the entity and that the system has cached the rule via PlacementRuleRegistry.
  • Stale State: Validation happens before execution. If you modify state (like inventory) during validation, you will cause bugs. Validation must be read-only.

Test Verification

The validation pipeline is rigorously tested to ensure layered execution and correct error reporting.

  • System Integration: res://addons/grid_placement/tests/integration/validation/test_placement_validation_system.gd

    • Pipeline Order: Verifies that collision checks happen before expensive logic rules.
    • Result Aggregation: Confirms that multiple rule failures are collected into a single result object.
  • Rule Logic: res://addons/grid_placement/tests/systems/test_placement_validation_system.gd

    • Unit Tests: Focuses on the PlacementValidationSystem’s internal logic for processing components.
  • Workflow: res://addons/grid_placement/tests/unit/placement/test_placement_core.gd

    • Registry: Validates that rules are correctly looked up and instantiated from the central registry.