GridPlacement 5.1 GDScript (Legacy)
This folder documents the legacy GDScript implementation of the GridPlacement plugin (historically shipped as the
grid_buildingaddon) used by Godot demos. The canonical implementation for new work is C# in GridPlacement 6.0+.
Goals and Scope
Legacy focus
- 5.1 GDScript is feature-frozen; only low-risk bugfixes and stability work.
- New gameplay and systems should target GridPlacement 6.0 C# instead.
Audience
- People maintaining or debugging existing 5.1 GDScript projects/demos.
- People migrating projects from 5.1 GDScript -> 6.0 C#.
Out of scope
- New GDScript APIs or major redesigns.
- Full re-port of all 6.0 features back into 5.1.
Where the GDScript Addon Lives
The 5.1-era addon is organized around the historical grid_building plugin, but the demo addon is now the canonical edit location and single source of truth for GDScript.
Runtime addon (canonical edit location)
- Location:
demos/grid_building_dev/godot/addons/grid_building - Contains the GDScript implementations of grid placement, targeting, and helpers used by the demo scenes.
- This is where you should open files to get full Godot language-server feedback (parse errors, type hints, etc.).
- There is no separate
migration_backups/gdscripttree anymore; all 5.1 GDScript withclass_namelives under this addon path in the demo project.
- Location:
Inventory addon (canonical edit location)
- Location:
demos/grid_building_dev/godot/addons/grid_building_inventory - Provides the inventory factory (
GridBuildingInventory) andItemContainer/item scripts used by the demo. - Edits should be made here first, then synced back into the plugin repositories.
- Location:
Mirrored plugin sources (sync targets, not edit roots)
- GridPlacement:
plugins/gameplay/GridPlacement/gdscript/grid_building - GridPlacementInventory:
plugins/gameplay/GridPlacementInventory/gdscript/grid_building_inventory - These folders are kept in sync from the demo via scripts like
scripts/sync_gp.sh(rsync from demo → plugins). - Do not make manual edits in the plugin copies; always change the demo addon first, then re-sync.
- GridPlacement:
GDScript tests
- Main test root:
demos/grid_building_dev/godot/addons/grid_building/test/grid_building - Inventory tests:
demos/grid_building_dev/godot/test/grid_placement_inventory - Tests are executed via the GodotToolkit TestOrchestrator (see testing docs below).
- Main test root:
Source of truth vs C#
- For behaviour, C# 6.0+ is still the canonical reference.
- The 5.1 GDScript code remains a legacy reference implementation, but its authoring surface is the demo project addon.
Support and Maintenance Policy
What we will do
- Fix critical crashes and severe logic bugs that block existing users.
- Keep the demo project loading and running on supported Godot versions.
- Maintain strong typing in runtime GDScript code (no loosening types for tests).
- Maintain a minimal, reliable GdUnit test slice for high-value paths.
What we will not do
- No new major systems or mode types in GDScript.
- No large refactors whose only goal is style alignment.
- No attempt to perfectly mirror every 6.0 C# feature in 5.1.
Testing Strategy (GDScript)
- Runtime typing rules
- Runtime GDScript must stay strongly typed (classes, members, arrays, signals).
- If tests break due to typing, we fix the tests or harness, not the types.
- This keeps runtime behaviour predictable and easier to migrate to C#.
Typed GDScript First (avoid duck typing)
- Prefer precise, static types over duck-typed access.
- Avoid runtime reflection/dynamic invocation:
call(),has_method(),get_method_list(),get_property_list()
- Avoid duck-typed property access as a default pattern:
obj.get("name"),obj.set("name", value)- Use these only as a narrow exception when forced by a truly dynamic engine surface.
- Prefer typed variables + direct member access:
var ctx: PlacementRuleContext = ...ctx.target_map = map
- Prefer shallow container shapes in authored code:
- Arrays:
Array[Vector2i],Array[PlaceableMetadata] - Dictionaries:
Dictionary[StringName, int]orDictionary[Vector2i, bool] - Avoid deep nesting (more than 1 level of
Dictionary/Array) unless the type is wrapped behind a focused adapter.
- Arrays:
Placement rules (5.1+): use PlacementRuleContext (not GridTargetingState)
In GridPlacement 5.1+, PlacementRule implementations are written against a
data-only input called PlacementRuleContext.
PlacementRuleContextexists to keep rule evaluation:- Deterministic (no mutable engine state / no surprise side effects)
- Unit-testable (you can construct a context and validate rules without a live targeting node)
- Decoupled from the targeting implementation (TargetingState/TargetingService can evolve without breaking rule APIs)
What changed vs older guides
Older 5.0-era docs and examples sometimes describe rules reading directly from
GridTargetingState.
For 5.1+:
- Rules should not depend on
GridTargetingState. - Rules should only read what they need from
p_context.
Minimal rule template (5.1+)
| |
Where PlacementRuleContext comes from
PlacementService provides a canonical builder:
PlacementService.build_rule_context_for_build(...)
That method gathers the relevant snapshot/map data and packages it into
PlacementRuleContext so all rules see the same stable inputs.
Test selection
- Keep a small set of high-value tests that:
- Cover core placement flows.
- Cover key inventory behaviours used by demos.
- Exercise adapters and integration points (but not every internal detail).
- Low-value or overly brittle tests are deleted or not ported.
- Keep a small set of high-value tests that:
Execution path
- Tests run via GodotToolkit.TestOrchestrator using a GdUnit runner script.
- Example (conceptual) flow:
- Orchestrator starts Godot with the demo project.
- GdUnit discovers and executes suites under the
addons/grid_building/testtree. - Results surface back to the .NET test runner for CI.
Hang-safe test running rules (Godot / GdUnit)
Do not run automation through a login shell (avoid
bash -lc).Require an explicit Godot binary path:
- Prefer
GODOT_BIN=/absolute/path/to/godot. - Avoid PATH-probing scripts that may execute slow/interactive shell init.
- Prefer
Always run Godot-based test commands behind a timeout (hang guard):
- Use
timeout --foreground -k 5 <seconds> <command...>.
- Use
Prefer the repo runner scripts that already include a timeout guard (where available).
Boundary between Core and Godot tests
- Core tests (C#) own behavioural rules: grid math, targeting semantics, placement validation, and state machines.
- Godot GDScript tests are thin wiring smokes:
- Ensure scenes load and services resolve.
- Verify adapters call into the correct core services.
- Avoid re-encoding full behaviour already covered by C# tests.
Naming & mapping convention
- For each 5.1 GDScript file that declares a
class_name, include a short docstring that:- Points to
docs/6.0/Core/GRIDBUILDING_CLASS_MAPPING.mdas the canonical C# mapping, and - Names the corresponding C# concept(s) where they exist (e.g.
PlacementService,ServiceRegistry,CompositionContainer).
- Points to
- This keeps GDScript naming in sync with the C# architecture and makes future migration and test porting easier.
Docstring template (recommended):
| |
Production-Ready Criteria for 5.1 GDScript
For the 5.1 GDScript addon, “production-ready” means:
Canonical edit surface and plugin mirrors are in sync
- Day-to-day edits happen in the demo project under
demos/grid_building_dev/godot/addons/grid_buildinganddemos/grid_building_dev/godot/addons/grid_building_inventory. - Plugin copies under
plugins/gameplay/GridPlacement/gdscript/grid_buildingandplugins/gameplay/GridPlacementInventory/gdscript/grid_building_inventoryare mirrors, updated via scripted sync (e.g.sync_gp.sh), not hand-edited.
- Day-to-day edits happen in the demo project under
Demo + addon load cleanly on supported Godot versions
- Main demo scenes open and run without red errors.
- Warnings from the addon are reduced to a small, understood set documented in
HEALTH.md.
Curated GdUnit slice is green and runnable via orchestrator
- A small, high-value set of GdUnit suites passes via
GodotToolkit.TestOrchestrator. - Run commands and expected health are documented in
docs/5.1/gdscript/HEALTH.mdand test roadmaps.
- A small, high-value set of GdUnit suites passes via
Public 5.1 GDScript API surface is stable
- External-facing scripts, nodes, and signals are treated as frozen for 5.1.
- Changes are limited to critical bugfixes; breaking changes are avoided or clearly documented.
Path-first UID policy is respected in scripts
- Authored code (runtime and tests) uses
res://preloads/loads where paths are stable. - Remaining
uid://references live only inside.tscn/.tresfiles managed by Godot.
- Authored code (runtime and tests) uses
Status is reflected in health and roadmap docs
HEALTH.mdcaptures the current score, top risks, and recent changes.- Remaining 5.1 work is intentionally small, focused, and tracked in
GDSCRIPT_5_1_REMAINING_WORK.md.
Migration to GridPlacement 6.0 C#
For new development and long-term maintenance, we recommend migrating to 6.0 C#.
High-level approach
- Treat existing 5.1 GDScript as behavioural examples, not authoritative API.
- Map concepts to 6.0 C# equivalents using the central migration docs
under
docs/grid-placement(class and service mappings, service registry, etc.).
Suggested migration steps
- Identify the minimal runtime subset of GDScript your project truly uses.
- Port those behaviours into C# core services first, with unit tests.
- Replace GDScript wiring with C# components and service registry usage.
- Leave the remaining GDScript addon as a reference-only artifact.
How This Folder Should Evolve
- Capture notes and diagrams that clarify how 5.1 GDScript works today.
- Record known limitations and intentional divergences from 6.0 C#.
- Add focused docs per subsystem (placement, targeting, inventory) only when
they help either:
- Debug legacy behaviour, or
- Migrate that behaviour into 6.0 C# cleanly.
When in doubt, prefer improving C# 6.0 docs and tests and keep 5.1 GDScript notes lightweight and maintenance-friendly.