Breaking Changes
Naming & Versioning (GridPlacement vs GridBuilding)
- Plugin name (6.0+): GridPlacement – this is the canonical name for the plugin going forward.
- Legacy name (≤ 5.x): GridBuilding – used throughout older docs, demos, and the GDScript plugin line.
- Assemblies (6.0):
GridPlacement.Core,GridPlacement.Godot, andGridPlacement.Godot.Tests. - Namespaces (6.0): Still rooted at
GridBuilding.*for C# (for exampleGridBuilding.Core,GridBuilding.Godot), to preserve existing API surface and documentation links.
Versioning shorthand:
- 5.1+ → branded GridPlacement
- 5.0.x and earlier → branded GridBuilding
- Namespaces remain
GridBuilding.*for C# in 6.0. When this guide refers to “GridBuilding 6.0” it is describing the same C# runtime that powers the GridPlacement plugin.
6.0.0 Breaking Changes - ManipulationData API Improvements
What Changed
The ManipulationData API was refactored to eliminate semantic confusion between targeting and manipulation:
Property Renamed:
- ❌ OLD:
ManipulationData.target(confusing - which “target”?) - ✅ NEW:
ManipulationData.move_copy(clear - the temporary manipulation preview)
Helper Method Added:
- ✅ NEW:
ManipulationData.get_move_copy_root()- Safe null-check access to the root node
Related Changes:
- ❌ REMOVED:
ManipulationState.active_target_nodeproperty (redundant withGridTargetingState.target) - ✅ ADDED:
ManipulationState.get_active_root()helper method
Why This Change?
Problem: Semantic confusion between two “target” properties:
GridTargetingState.target= What is being aimed at (collision detection target)ManipulationData.target= Temporary manipulation preview (NOT the target being aimed at)
Solution: Rename to move_copy to clearly indicate it’s the temporary manipulation preview object.
Migration Guide
Pattern 1: Direct Property Access
| |
Pattern 2: Using Helper Method (Recommended)
| |
Pattern 3: ManipulationState Access
| |
Architecture Benefits
- Semantic Clarity: Clear distinction between
move_copy(preview) andGridTargetingState.target(actual target) - Single Source of Truth: Reinforces GridTargetingState as authoritative for targeting
- Null Safety: Helper methods eliminate error-prone nested null checks
- Self-Documenting: Code reads as “move the copy” not “move the target”
Files to Update
Search your project for these patterns and update:
manipulation_data.target→manipulation_data.move_copymanipulation_state.active_target_node→manipulation_state.get_active_root()- Nested null checks → Use
get_move_copy_root()helper
Related Documentation
- See ManipulationData API for complete API reference
- See ManipulationState API for state management details
- See Manipulation System Guide for architectural overview
6.0.0 Breaking Changes - Legacy StateBridge Node Removed
What Changed
- ❌ REMOVED: The monolithic
StateBridgeGodot node pattern as the canonical integration layer. - ✅ NEW (6.0+): Integration is based on services + domain events, with thin adapter or system nodes that:
- Resolve Core services via the DI/service registry.
- Subscribe to Core domain events.
- Emit Godot signals or update local Godot state.
There is no single required StateBridge node in the scene tree for 6.0+ projects.
Why This Change?
- The StateBridge pattern tightly coupled C# state, Godot scenes, and UI to a single global node.
- Service + event-based integration scales better, matches the documented service architecture, and avoids a new “god object” at the integration boundary.
Migration Guide
For existing projects that used StateBridge as documented in the legacy C# State Integration guide:
- Treat
StateBridgeas legacy only- Keep using it only in pre-6.0 projects.
- Do not add new dependencies on
StateBridgein 6.0+ code.
- Introduce service-based adapters
- Create one or more C# adapter/system nodes that:
- Resolve Core services (for example
IBuildingService,IModeService, etc.) via the DI container/registry. - Subscribe to relevant domain events.
- Expose Godot signals and helper methods tailored to your UI.
- Resolve Core services (for example
- Create one or more C# adapter/system nodes that:
- Update call sites
- Replace calls like
get_node("/root/StateBridge")andstate_bridge.get_*()with references to your new adapter/system nodes. - Connect to adapter signals instead of StateBridge-specific signals.
- Replace calls like
Files to Review
- Legacy reference (pre-6.0):
docs/gridplacement/content/gridbuilding/CSHARP_STATE_INTEGRATION.md - 6.0+ canonical integration:
docs/gridplacement/content/v6.0/guides/core-godot-integration.md
6.0.0 Breaking Changes – C# API Deprecations
The 6.0 C# edition removes or deprecates several legacy APIs from the early injector-based design. These remain only for short-term compatibility and will be removed in a future 6.x release.
Injector-era types and patterns
Deprecated (C# 6.0):
GridBuilding.Godot.Core.Base.Injectableand GB injector-era components.GBCompositionContainerand composition-container-centric wiring.- Static factory methods named
CreateWithInjection(...)on Godot components. ResolveGbDependencies(...)methods that accept GB composition containers.- Injector-style
GetRuntimeIssues()methods that depend on a global/implicit container.
Replacements:
- Use the Enhanced Service Registry Pattern:
ServiceCompositionRoot+ServiceRegistryto construct and register services.IInjectable+ explicitInjectDependencies(ICompositionContainer)/ValidateDependencies(ICompositionContainer)where DI is still required.
- Prefer explicit constructor injection for pure C# services (no Godot dependency).
- For Godot-facing components, resolve services from
ServiceRegistryinstead of GB injector nodes.
Existing helper types such as ObsoleteGBInjectorAttribute and migration tools in toolkits/cs can be used to mechanically convert injector-era code to the new pattern.
Legacy C# examples and facades
Deprecated (C# 6.0):
GBConfigas a C# configuration root type.BuildingMode(useGridModeinstead).- Example/bridge classes such as
ComposableBuildingNode,BuildingBehavior,HybridPlaceableDefinition, andPlaceableSequenceFactory. - Godot constant facades
GBConstants/Constantsthat forward to newerMetadataConstants,ResourcePaths,ThemeConstants,IconPaths,AudioPaths, andMetadataUtilstypes.
Replacements:
- Use
Configin theGridBuildingnamespace as the canonical 6.0 C# configuration type (root of the configuration hierarchy), with migration tooling mapping legacy GDScriptGBConfigresources toConfig. - Use the value types and enums in
GridBuilding.Core.Types(for example,GridMode). - For building flows, prefer PlacementSystem + IPlacementService and service-based behaviors instead of attaching legacy example behaviors directly.
- Use the newer domain-specific constant classes directly (
MetadataConstants,ResourcePaths,ThemeConstants,IconPaths,AudioPaths,MetadataUtils) instead of the GBConstants/Constants facades.
These deprecated APIs remain for 6.0 to ease migration but should be treated as legacy-only and avoided in new code.
6.0.0 Architectural Note – Canonical Types & Analyzer Exceptions
This is a non-breaking architectural clarification for 6.0.0.
- Canonical type configuration is now per plugin.
- Each plugin owns a
configs/canonical-types.jsonunder its plugin root (for exampleplugins/gameplay/GridBuilding/configs/canonical-types.json). - This file defines which types are treated as canonical and which names are monitored by integrity tools.
- Each plugin owns a
- Analyzers consult a small per-plugin exception allowlist.
- Code analysis tools (duplicate-type scanner, type-contract validator,
namespace-boundary checks) read a shared
configs/code-smell-exceptions.jsonconfiguration. - Plugins can register a small set of explicit type-name exceptions and
allowed cross-plugin namespaces so that:
- Prefixed/suffixed domain type variants used to avoid .NET/engine collisions are treated as first-class architectural patterns.
- Analyzers remain strict by default but do not flag these deliberate variants as smells or contract violations.
- Code analysis tools (duplicate-type scanner, type-contract validator,
namespace-boundary checks) read a shared
End users normally do not need to edit these files directly; they are managed by plugin authors and internal tooling. They are documented for advanced users under the Code Integrity Toolkit and developer checklists.
5.1 GDScript Bridge Release
Goals
- Provide a stable GDScript path for existing projects during the 6.0 C# rollout.
- Keep the familiar 5.x GDScript API and demo flow available while the new 6.0 service‑based architecture lands.
- Clearly separate legacy GDScript demos from new C# demos in this repo.
Demo Layout (5.1 vs 6.0)
The repository will keep two parallel demo roots:
| Folder | Language | Purpose |
|---|---|---|
demos/grid_building_dev/ | GDScript | Canonical 5.x/5.1 GDScript demo, matching the legacy docs and upgrade guides. |
demos/GridBuildingDev/ | C# | Future 6.0+ C# demo, showcasing the service + domain‑event integration pattern. |
Important:
demos/grid_building_dev/should remain a GDScript‑only demo for the 5.1 line.- The C# demo will live in a separate folder (
GridBuildingDev) in the same repo, to avoid mixing languages and to keep migration guidance clear. - Engine‑agnostic, production‑ready code continues to live under
plugins/gameplay/GridPlacement/Core(GridBuilding.Core).
Versioning Guidance
- Projects that are GDScript‑only today can safely:
- Pin to 5.1 while GridPlacement 6.0 C# stabilizes.
- Use
demos/grid_building_dev/as the reference implementation.
- New C#‑heavy projects, or projects actively migrating to 6.0, should:
- Plan to adopt the 6.0 service/event architecture.
- Treat
demos/GridBuildingDev/(once available) and the 6.0 guides underv6.0/as canonical examples.
Summary of major breaking changes (4.3.1 → 5.0.0)
- 🏗️ Node Hierarchy Architecture: Well-defined hierarchy with specific class names (GridPositioner2D → TargetingShapeCast2D → ManipulationParent → IndicatorManager). Major functionality relocated from high-level coordinators to individual components.
- Dependency Injection / Composition Container is now the primary integration pattern. See GBCompositionContainer and GBInjectorSystem.
- Configuration consolidated into the GBConfig resource.
- 🆕 Automatic validation: GBInjectorSystem now handles validation automatically - no manual validation calls required!
- 🔄 Functionality redistribution: GridTargetingSystem and ManipulationSystem simplified to coordination roles; core functionality moved to specific component classes.
- Validation contract standardized:
validate()results are represented as boolean success + diagnostic collections viaget_runtime_issues()/get_editor_issues()(multiple files expose these methods). - Godot API change: migrate any
TileMapusage toTileMapLayerfor 2D tile placement/queries. - Important signature/rename breaks (examples):
GBOwnerContext.set_owner(...)now requires a GBOwner;DragBuildManagerwas renamed to DragManager and exposesis_dragging().
The sections below expand each item with concrete before/after examples and file references.
1) Dependency Injection (DI) and Composition Container
What changed
- The plugin moved from ad-hoc, direct node/system instantiation to a composition-based approach. New public resources/classes include GBCompositionContainer, GBInjectorSystem, and GBSystemsContext.
Impact
- Callsites that previously created systems directly (e.g.,
BuildingSystem.new()) should now obtain systems via the injector/composition pattern. - For most end users the recommended integration is:
- Add a GBInjectorSystem node to your gameplay (runtime) scene where grid-building features are used — this keeps injection local to the gameplay context rather than embedding injector state in level resources.
- Create or use a GBCompositionContainer resource and assign it to the GBInjectorSystem using its exported
composition_containerproperty. You can use the supplied composition container templates or create your own GBCompositionContainer resource file (.tres).
Migration guidance (example)
Previously, systems like GridTargetingSystem might have had direct exported properties for settings (e.g., @export var settings : GridTargetingSettings).
Now, the workflow is:
- Add a GBInjectorSystem node to your gameplay scene.
- Assign a GBCompositionContainer resource to its
composition_containerexported property (use provided templates or create your own.tresfile). - Optionally, set the
injection_rootsproperty to specify which part of the scene hierarchy to inject into (can include multiple paths if needed). - Systems like GridTargetingSystem will automatically have their
resolve_gb_dependencies()method called by the injector, resolving settings from the container without manual assignment.
This avoids direct instantiation and manual wiring, letting the injector handle dependency resolution automatically for nodes in the scene that implement the required methods.
Files to review
Notes
- The GBInjectorSystem listens for scene tree additions and injects dependencies automatically into nodes it manages. Prefer wiring composition via the injector’s exported
composition_containerproperty rather than instantiating containers in gameplay code. - Use the provided composition container templates (look under the plugin templates folder) or author a GBCompositionContainer resource and save it into your project.
– Important: before upgrading, save any existing configuration or exported setting resources (templates, visuals, action sets, etc.) to disk as
.tresor.resfiles in your project and then reassign them into a GBConfig resource. Many exported properties were removed in favor of DI and will not be present after upgrade; saving them ensures you don’t lose configuration.
For a step-by-step migration checklist (recommended), see Migration — v5.0.0.
2) Configuration consolidated under GBConfig
What changed
- Multiple scattered exported properties were consolidated into a single GBConfig resource. See GBConfig for the API and structure.
Impact
- If you previously used exported properties on different nodes for configuration, move those values into a GBConfig resource and assign it to the composition container (or via the GBInjectorSystem’s assigned composition container).
Migration example (before) Previously, systems like GridTargetingSystem might have had direct exported properties for settings:
| |
After (example)
Create or edit a GBConfig resource in the editor inspector. The GBConfig has a nested settings property of type GBSettings, which contains a targeting exported property for GridTargetingSettings. Set the targeting property (and other configuration values) there. Save the resource as a .tres file and assign it to your GBCompositionContainer used by the GBInjectorSystem.
Files to review: GBConfig
Consolidated exports you should save before upgrading
Many exported properties that previously lived directly on systems, UI nodes, or indicator scenes have been consolidated into GBConfig (under settings, templates, or actions). To avoid losing values during upgrade, save any resources or exported values used in your project to .tres/.res files and reassign them into the appropriate GBConfig subresource after upgrading.
The table below lists the common exported properties you may have used, where they were commonly exported previously, and their new GBConfig location. This is intended as a practical checklist — if you see an exported property in your project that matches one below, save it as a resource and note the recommended target path in GBConfig.
| Old class / location | Export/resource | New GBConfig location | Notes |
|---|---|---|---|
| GridTargetingSystem / targeting nodes | GridTargetingSettings (resource) | GBConfig.settings.targeting | Save your GridTargetingSettings resource as .tres and assign to GBConfig.settings.targeting. |
| BuildingSystem / preview nodes | BuildingSettings (resource) | GBConfig.settings.building | Save your BuildingSettings resource as .tres and assign to GBConfig.settings.building. |
| ManipulationSystem / manipulation UI | ManipulationSettings (resource) | GBConfig.settings.manipulation | Save your ManipulationSettings resource as .tres and assign to GBConfig.settings.manipulation. |
| RuleCheckIndicator / indicator scenes | IndicatorVisualSettings (resource) | GBConfig.templates.rule_check_indicator (inside the saved template) | Save IndicatorVisualSettings and indicator PackedScene templates; store the template under GBConfig.templates.rule_check_indicator and reference visuals from the saved template. |
| IndicatorManager / PlacementValidator | PackedScene templates | GBConfig.templates.* (e.g., rule_check_indicator) | Save PackedScene templates and assign them under GBConfig.templates. |
| UI nodes (placeable lists / selection UIs) | UI PackedScene templates | GBConfig.templates.* | Save UI PackedScenes and assign under GBConfig.templates, or keep local where appropriate. |
| GBActionButton / input helpers | GBActions (resource) | GBConfig.actions | Save a GBActions resource as .tres and assign to GBConfig.actions. |
ActionLog / UI | ActionLogSettings (resource) | GBConfig.settings.action_log | Save ActionLogSettings as .tres and assign to GBConfig.settings.action_log. |
| Various systems / messages | Message strings now in ManipulationSettings and ActionLogSettings | Message strings are now @export properties directly in settings resources. Configure in GBConfig.settings.manipulation and GBConfig.settings.action_log. | |
| Placeable / placeable sequence definitions | Placeable resource files | Assigned via Placeable Selection UI (see your project UI) | Save Placeable resource files as .tres and keep them centralized (for example res://placeables/). Placeables are assigned to the Placeable Selection UI in your scenes — they are not typically assigned directly to GBConfig. At runtime the project may optionally autoload a configured folder of placeable resources; for upgrades, prefer saving and assigning .tres files via your Placeable Selection UI. |
| Validation / placement rules | PlacementRule (resources) | GBConfig.settings.placement_rules | Save PlacementRule resources as .tres and assign to GBConfig.settings.placement_rules. |
| Debug tuning / indicator debug toggles | GBDebugSettings (resource) | GBConfig.settings.debug | Save GBDebugSettings as .tres and assign to GBConfig.settings.debug. |
| Cursor / visual configuration | GBVisualSettings (resource) | GBConfig.settings.visual | Save GBVisualSettings as .tres and assign to GBConfig.settings.visual. |
| Input/action name resources | GBActions (resource) | GBConfig.actions | Centralize action name identifiers into a GBActions resource and assign to GBConfig.actions. |
Notes on using this table
- If you find an exported property in your scenes or nodes that matches an entry above, save the resource or value to disk (as
.tres/.res) before upgrading and record the intended GBConfig path. - After upgrading, create or edit a GBConfig resource in the editor and populate
settings,templates, andactionswith the saved resources or values. GBConfig’s_lazy_init_subresources()will create sub-resources if missing. - Template reassignment: PackedScene templates (for indicators, placeable views, lists) should be saved as separate
.tscn/.tscnpacked scenes in your project and referenced fromGBConfig.templates.
3) Validation contract standardized + Automatic validation
What changed
- Validation flows now use a simple boolean success contract for
validate()and explicit issue collection viaget_runtime_issues()/get_editor_issues(). Many systems and resources implement these helpers. - 🆕 Automatic validation: GBInjectorSystem now automatically validates configuration after dependency injection completes - no manual validation calls required!
- 🗑️ Removed methods:
validate_runtime_deferred(),_validate_after_injection(), and similar manual validation methods have been removed from GBCompositionContainer
Migration Impact
- Remove manual validation calls: If you have code calling
validate_runtime_deferred()or_validate_after_injection(), you must remove these calls - they no longer exist and validation now happens automatically. - Simplified setup: Grid Building systems now validate automatically without user intervention.
- Cleaner code: No validation boilerplate needed in your setup code.
Before (manual validation required):
| |
After (automatic validation):
| |
Important: The following methods have been REMOVED and are NOT backwards compatible:
GBCompositionContainer.validate_runtime_deferred()- REMOVEDGBCompositionContainer._validate_after_injection()- REMOVEDvalidate_runtime_configuration()- REMOVED (outdated reference)
If your code calls any of these methods, you will get runtime errors. Simply remove the calls - GBInjectorSystem handles validation automatically after dependency injection.
Two supported workflows for custom validation
Automatic validation + logging (convenience): call
validate()when you want the system to run its internal checks and perform any built-in logging;validate()returnstruewhen no issues were found. This is the simple path when you only need a pass/fail result and want the system to handle logging for you.Manual inspection (detailed handling): call
get_runtime_issues()to retrieve the list of issue objects/strings and handle logging, breakpoints, or special reporting yourself.get_runtime_issues()does not log by itself — it merely reports the collected issues.
Notes on logging
- The logger helpers (for example
container.get_logger().log_issues(...)) will safely ignore an empty issues array, so you can call them unconditionally if that fits your flow. Alternatively, checkif issues.size() > 0:before logging if you prefer an explicit guard.
Examples
Automatic validation vs direct issue inspection
Use validate() when you want the system to run its internal checks and let the system handle any built-in logging or diagnostics. validate() returns true when no issues were found and will typically log detected issues to the configured logger.
| |
Use get_runtime_issues() or get_editor_issues() when you want to examine the issue collection yourself (for example to run custom reporting, break into the debugger, or filter/transform entries). Call the editor variant only when running inside editor-validation flows.
| |
Guidance summary
- During gameplay use
validate()for a single-pass check that also performs any default logging. - If you want full control over logging or to avoid any automatic logger output, call
get_runtime_issues()(gameplay) orget_editor_issues()(editor-time) and handle the results yourself. - Avoid calling
validate()and then immediately callingget_runtime_issues()just to re-log the same issues unless you have a specific reason to aggregate or transform the results first.
Common locations of issue helpers (examples)
../api/GBLogger/(hasget_runtime_issues())../api/BuildingSystem/../api/GridTargetingSystem/- Many
../api/*pages correspond toresources/*andplacement/*GDScript files and exposeget_runtime_issues()/get_editor_issues()in their API.
4) Godot TileMap → TileMapLayer
What changed
- Godot deprecated some
TileMapusages for tile-layer operations. Code and exported properties that previously referencedTileMapshould be migrated toTileMapLayerwhere appropriate.
Migration example
| |
Search and update: any script that used TileMap APIs for 2D placement/queries.
5) Node Hierarchy Architecture & Functionality Relocation
What changed
v5.0.0 introduces a well-defined node hierarchy with specific class names and clear responsibility distribution. This represents a major architectural shift from the previous loosely-defined structure.
New Hierarchy Structure
The Grid Building system now follows this specific hierarchy (see Project Architecture for complete details):
- GridPositioner2D - Root node handling targeting and input movement
- TargetingShapeCast2D - Target collision detection using shape casting
- ManipulationParent - Handles rotations and flips for objects
- IndicatorManager - Manages visual feedback indicators
- RuleCheckIndicator nodes - Individual rule validation indicators
- Preview Object - Temporary preview during build/move modes
- IndicatorManager - Manages visual feedback indicators
Functionality Redistribution
Major system functionality has been relocated from high-level coordinators to specific component classes:
GridTargetingSystem → Individual Components:
- Input handling → GridPositioner2D
- Collision detection → TargetingShapeCast2D
- Transform operations → ManipulationParent
ManipulationSystem → ManipulationParent:
- Direct input processing → ManipulationParent
- Transform coordination → ManipulationParent
- Indicator synchronization → ManipulationParent (via native Node2D inheritance)
Migration Impact
Before (v4.x)
| |
After (v5.0.0)
| |
Code Migration Examples
Targeting functionality relocation:
| |
Manipulation functionality relocation:
| |
Benefits
- Clear Architecture: Specific class names eliminate ambiguity
- Better Performance: Direct component communication without delegation
- Improved Maintainability: Each component has well-defined responsibilities
- Automatic Synchronization: Leverages Godot’s native transform inheritance
- Easier Testing: Components can be tested in isolation
Files affected
- GridPositioner2D: Enhanced with direct input processing
- TargetingShapeCast2D: Dedicated collision detection
- ManipulationParent: Direct transform and input handling
- GridTargetingSystem: Simplified coordination role
- ManipulationSystem: High-level lifecycle management only
7) Legacy Manipulation System Architecture (Related Changes)
What changed
The manipulation system has been refactored to follow the Single Responsibility Principle with clear separation between:
- ManipulationSystem: High-level coordination, mode management, and manipulation lifecycle
- ManipulationParent: Direct input handling, transform coordination, and indicator synchronization
Impact
This architectural change primarily affects internal implementation and provides several improvements:
- Bug Fix: Resolves the “indicators don’t rotate/flip with preview objects” issue
- Improved Architecture: Better separation of concerns and reduced coupling
- Better Maintainability: Cleaner code with elimination of delegation anti-patterns
- Performance: Leverages Godot’s native transform inheritance for indicator synchronization
Migration guidance
For most users, this change is non-breaking as the public API remains the same. The improvements happen automatically:
- ManipulationSystem continues to handle high-level manipulation coordination
- Transform operations now happen directly through ManipulationParent with automatic child synchronization
- Input processing is handled more efficiently without delegation chains
Files affected
- ManipulationSystem: Simplified to focus on coordination
- ManipulationParent: Enhanced with direct input processing and dependency injection
- ManipulationState: Updated to work with the new architecture
Benefits
- Automatic indicator synchronization: Child indicators now inherit transforms automatically via Godot’s Node2D system
- Reduced complexity: Elimination of transform input delegation between components
- Better testability: Components can be tested in isolation with clear responsibilities
- Leverages Godot patterns: Uses engine’s natural parent-child transform relationships
8) Signature and class renames (notable breaking items)
GBOwnerContext.set_owner(value: GBOwner) -> void- Commit note:
BREAKING: GBOwnerContext.set_owner now requires GBOwner (tests updated) - Impact: Call sites that passed other types (or no type) may now fail static checks or runtime typed calls. Update callsites to pass a GBOwner instance (see
../api/GBOwnerContext/and../api/GBOwner/).
- Commit note:
DragBuildManager→ DragManager andis_dragging()- The internal drag controller class was renamed to DragManager. Where code referenced
DragBuildManagerdirectly in older versions, update to DragManager. The BuildingSystem providesis_drag_building()as a compatibility delegate, but preferDragManager.is_dragging()for new code. See../api/DragManager/.
- The internal drag controller class was renamed to DragManager. Where code referenced
Logger centralization
- Instead of creating GBLogger manually across systems, obtain the logger from the composition container assigned to your injector (e.g. the container referenced by the GBInjectorSystem), or call
composition_container.get_logger(). See../api/GBLogger/and../api/GBCompositionContainer/.
- Instead of creating GBLogger manually across systems, obtain the logger from the composition container assigned to your injector (e.g. the container referenced by the GBInjectorSystem), or call
Files & symbols to scan for updates
../api/GBOwnerContext/(set_owner signature)../api/DragManager/(class & is_dragging)../api/GBCompositionContainer/(get_logger / composition usage)
9) GBInjectable / reference-count changes
What changed
- Many classes were converted to ref-counted types and unified under a GBInjectable base so they can participate in the plugin’s DI and lifecycle expectations without being Node-derived.
Important integration notes
- Injection is node-centric: the injector (GBInjectorSystem) walks the scene tree and automatically injects dependencies into Node-derived objects it manages. Ref-counted objects (Resources or plain Objects) are NOT injected automatically just because they exist as sub-objects of a Node.
- To integrate ref-counted sub-objects with DI you should:
- Make the owner Node (the Node that holds the ref-counted instance) a target for injection (e.g., it lives under an injection root handled by GBInjectorSystem).
- Implement
resolve_gb_dependencies(container)(or the project’s standard resolve method) on the Node and, inside that implementation, forward configuration and dependencies to the owned ref-counted objects. For example, call a setter or invoke aresolve_gb_dependencies()-like method on the resource if it implements GBInjectable. - Treat the Node as the injection entry point — it is responsible for wiring its ref-counted sub-objects. Ref-counted objects do not get injected by traversing the tree on their own.
Why this matters
- Previously the project had no built-in pattern or base class specifically for non-node, ref-counted objects in the grid-building system. GBInjectable provides a common base and optional hooks to make ref-counted objects easier to integrate, but nodes remain the primary injection unit.
Practical example (prose)
- Suppose
MyGridComponentResourceis aResourcethat extends GBInjectable and is owned byMyGridNode(aNodein the scene). To ensure the resource receives the necessary dependencies,MyGridNode.resolve_gb_dependencies(container)should obtain the resolved services/config fromcontainerand then call intoMyGridComponentResourceto supply them (for examplemy_resource.setup(logger, settings)ormy_resource.resolve_gb_dependencies(container)). This explicit forwarding guarantees the ref-counted object receives configuration and services even though it is not injected directly by the scene injector.
Impact
- If you extended or relied on specific GC/lifetime behaviors, review classes inheriting GBInjectable (search
class_name GBInjectableandextends GBInjectable). See GBInjectable.
Files to review: GBInjectable, GBInjectorSystem, GBCompositionContainer
10) Migration checklist (concrete)
For detailed step-by-step migration, see Migration — v5.0.0.
- Save any existing exported settings or resource instances to disk as
.tres/.resBEFORE UPGRADING. This prevents resources from disappearing when exported properties are consolidated into the GBCompositionContainer (or moved into the GBConfig resource) — an exported property that previously lived on a system or UI node may otherwise no longer exist after upgrade. - Upgrade assets to Godot 4.4+.
- Replace direct
*.new()system instantiation by adding a GBInjectorSystem node to your gameplay scene and assigning a GBCompositionContainer resource (via the GBInjectorSystem exported property), or use a provided container template saved as a.tresresource. - Update calls to
GBOwnerContext.set_owner(...)to pass a GBOwner instance. - Replace direct logger instantiation with the container-provided logger.
- Migrate any
TileMapreferences toTileMapLayerwhere applicable.
11) Hide on Handled Mouse Input Dependency
Change: The hide_on_handled visibility setting now respects the enable_mouse_input setting, preventing unwanted hiding when mouse input is disabled.
Reason: Previously, hide_on_handled would apply even when enable_mouse_input was false, causing the positioner to hide when hovering UI elements during keyboard-only or code-driven positioning modes.
Impact: This is a behavioral fix rather than a breaking API change. Most users will see improved behavior, but if your code relied on the previous behavior where hide_on_handled applied regardless of mouse input state, you may need to adjust your visibility logic.
Before (v5.0.0 and earlier)
| |
After (6.0.0+)
| |
Migration
- For mouse-enabled modes: No changes needed, behavior is preserved
- For keyboard/code-driven modes: Visibility now works correctly without workarounds
- For mixed modes: Review your visibility logic if you were working around the previous behavior
Files to review: GridTargetingSettings, GridPositionerLogic
12) Removed Message Resource Files - Messages Now in Settings
Change: Message resource files and their scripts have been completely removed. Message strings are now exported properties directly in settings resources.
Architecture Change:
- Old approach (v4.x): Separate ManipulationMessages and GBMessages resource files
- New approach (v5.0.0): Message strings are
@exportproperties in ManipulationSettings and ActionLogSettings
Files Removed:
godot/addons/grid_building/systems/manipulation/manipulation_messages.gd- Script removedgodot/addons/grid_building/resources/messages/gb_messages.gd- Script removedgodot/demos/shared/settings/demo_messages.tres- Demo resource removedgodot/demos/shared/settings/manipulation_messages.tres- Demo resource removed
Impact: All message strings are now configured directly in the settings resources where they’re used, not in separate message resource files.
Migration
Before (v4.x):
| |
After (v5.0.0):
| |
Where messages are now located:
Manipulation operation messages → ManipulationSettings properties:
demolish_success,demolish_already_deleted,failed_not_demolishablemove_started,move_success,failed_to_start_move,no_move_targetfailed_placement_invalid,target_not_rotatable,target_not_flippable_horizontally, etc.
UI/ActionLog display messages → ActionLogSettings properties:
built_message,fail_build_message,mode_change_messageshow_demolish,show_moves,show_mode_changes(display toggles)
Resource file updates:
If you have .tres files that reference the old script paths, delete those resource files and configure messages directly in your ManipulationSettings and ActionLogSettings resources instead.
Files to review: ManipulationSettings, ActionLogSettings, GBSettings
13) Property Rename: mouse_handled → ui_mouse_handled
Change: The property name mouse_handled has been renamed to ui_mouse_handled for clarity.
Location: GridTargetingSystem
Impact: If your code directly accesses this property, update the property name.
Migration
Before (v4.x):
| |
After (v5.0.0):
| |
Rationale: The new name ui_mouse_handled more clearly indicates that this flag tracks whether UI elements have consumed mouse input, distinguishing it from general mouse handling logic.
Files to review: GridTargetingSystem
14) GridPositioner2D Position Utility Methods Removed
Change: Position conversion helper methods have been removed from GridPositioner2D in favor of centralized utility functions in GBPositioning2DUtils.
Removed Methods:
- Direct position conversion helpers (moved to GBPositioning2DUtils)
- Internal positioning methods (use utility functions instead)
Impact: If your code directly called positioning helper methods on GridPositioner2D instances, migrate to the static utility functions.
Standard Dependency Injection (No Change)
Important: resolve_gb_dependencies(container) is the standard method for dependency injection and remains fully supported. This is how GBInjectorSystem injects dependencies into Grid Building components.
| |
The GBInjectorSystem automatically calls resolve_gb_dependencies() on all nodes under its injection roots. This is the primary integration pattern and is not deprecated.
Migration
Position utilities (removed → use static utilities):
| |
Rationale:
- Utility functions follow DRY principles and provide a single source of truth
- Static utility methods are easier to test and maintain
- Reduces coupling between components
Files to review: GridPositioner2D, GBPositioning2DUtils
15) BuildingSettings.drag_multi_build Removed
Change: The drag_multi_build setting has been completely removed from BuildingSettings. This setting is now obsolete with the new DragManager component architecture.
Architectural Change:
- Old approach (v4.x): Enable/disable drag building via
BuildingSettings.drag_multi_buildboolean - New approach (v5.0.0): Control drag building by adding/removing DragManager component or setting its
process_mode
Why this changed:
- DragManager is now a separate, optional component that can be added to any scene
- Drag building functionality is decoupled from BuildingSystem
- Simpler architecture: presence of DragManager node = drag building enabled
Impact: If you have code or settings referencing drag_multi_build, you must update to use the new component-based approach.
Migration
Before (v4.x):
| |
After (v5.0.0):
| |
Scene-based approach (recommended):
| |
Resource file cleanup:
Remove drag_multi_build = true lines from all .tres BuildingSettings resource files:
godot/demos/top_down/config/settings/td_building_settings.tresgodot/demos/isometric/settings/isometric_building_settings.tresgodot/demos/platformer/settings/platformer_building_settings.tres- Any custom BuildingSettings resources in your project
Test file updates:
If you have test code setting drag_multi_build, remove those lines - the tests should work with DragManager component presence instead:
| |
Benefits of new approach:
- Clearer architecture: Component presence = feature enabled
- Better separation of concerns: Drag logic lives in dedicated component
- Runtime flexibility: Add/remove drag support dynamically without settings
- Easier testing: Test drag behavior in isolation by testing DragManager directly
Files to review: BuildingSettings, DragManager, BuildingSystem
16) BuildType Enum Parameter System (v5.0.0)
Change: Build operations now use a BuildType enum parameter instead of a boolean dragging flag to differentiate between build operation modes.
Architectural Change:
- Old approach: BuildActionData accepted
dragging: boolparameter (always passed asfalse, breaking drag suppression) - New approach: BuildActionData accepts
build_type: GBEnums.BuildTypeparameter with SINGLE, DRAG, and AREA values
Why this changed:
- Boolean flag was always
falsein BuildingSystem, breaking action log drag suppression - Enum provides clearer semantic meaning (SINGLE vs DRAG vs AREA)
- Future-proofed for area building features (fence lines, walls)
- Enables proper differentiation throughout the system (action log, audio, analytics)
Impact: Breaking change to BuildActionData constructor signature and related method signatures.
BuildType Enum
| |
Migration
BuildActionData Constructor:
| |
BuildingSystem Methods:
| |
Parameter Flow:
- DragManager →
building_system.try_build(GBEnums.BuildType.DRAG) - BuildingSystem →
report_built(report, build_type)orreport_failure(report, build_type) - BuildActionData → Stores
build_typeand emits through signals - GBActionLog → Checks
build_typeto suppress non-SINGLE builds - GBAudioInstancer (demos) → Checks
build_typeto skip drag sounds and throttle failures
Benefits:
- ✅ Action log drag suppression now works correctly (
print_on_drag_buildsetting) - ✅ Audio failure sound throttling prevents spam during drag building
- ✅ Clearer code semantics (DRAG vs
true, SINGLE vsfalse) - ✅ Future-ready for AREA building (fence lines, walls)
Backward Compatibility: Default parameters maintain backward compatibility for basic usage, but any code directly instantiating BuildActionData or calling report methods must be updated.
Files to review: BuildActionData, BuildingSystem, DragManager, GBActionLog
Summary of major breaking changes (5.0.0 → 6.0.0)
- 🎯 Smart Target Resolution: GridTargetingState now automatically resolves logical targets from collision objects using metadata and Manipulatable components, instead of always using the collision object itself as the target.
The sections below expand this change with concrete before/after examples and migration steps.
1) Target Resolution Enhancement (6.0.0)
What changed The Grid Targeting system now intelligently resolves targets through collision objects rather than treating collision objects as direct targets. This enables more flexible scene hierarchies where collision shapes can be on child nodes while targeting parent objects.
Impact
- Collision objects detected by TargetingShapeCast2D are now resolved to logical target nodes
- Code that relied on
GridTargetingState.get_target()returning the collision object itself may need updates - Objects without resolution metadata continue to work as before (collision object = target)
Migration guidance (example)
Previously, collision objects were always used directly as targets:
| |
Now, collision objects are resolved to logical targets:
| |
Resolution Strategies
- Metadata Resolution (recommended for custom objects):
| |
- Manipulatable Component (automatic for manipulatable objects):
| |
Benefits
- ✅ More flexible scene hierarchies
- ✅ Collision shapes can be positioned independently of logical targets
- ✅ Backward compatible for objects without metadata
- ✅ Automatic resolution for Manipulatable objects
Files to review
- GridTargetingState -
set_collider()now resolves targets - GBMetadataResolver - New utility for target resolution
- Manipulatable - Components automatically participate in resolution
17) Migration checklist (concrete)
For detailed step-by-step migration, see Migration — v5.0.0.
Critical breaking changes (will cause errors)
- Update BuildActionData instantiation - Replace boolean third parameter with
GBEnums.BuildType.SINGLEorGBEnums.BuildType.DRAG - Remove manual validation calls -
validate_runtime_deferred(),_validate_after_injection(), andvalidate_runtime_configuration()have been REMOVED. Delete these calls from your code.\n- [ ] Remove message resource file references - Delete any.tresfiles referencingmanipulation_messages.gdorgb_messages.gd. Configure message strings directly in ManipulationSettings and ActionLogSettings exported properties instead.\n- [ ] Updatemouse_handledtoui_mouse_handled- Property was renamed in GridTargetingSystem\n- [ ] Removedrag_multi_buildreferences - This setting no longer exists. Control drag building by adding/removing DragManager component instead. Removedrag_multi_build = truefrom all BuildingSettings.tresfiles. - Review target resolution logic - Code using
GridTargetingState.get_target()may now receive resolved targets instead of collision objects. Update logic that assumes targets are collision objects.
Required migrations
- Save any existing exported settings or resource instances to disk as
.tres/.resBEFORE UPGRADING. This prevents resources from disappearing when exported properties are consolidated into the GBCompositionContainer (or moved into the GBConfig resource) — an exported property that previously lived on a system or UI node may otherwise no longer exist after upgrade. - Upgrade assets to Godot 4.4+
- Replace direct
*.new()system instantiation by adding a GBInjectorSystem node to your gameplay scene and assigning a GBCompositionContainer resource (via the GBInjectorSystem exported property), or use a provided container template saved as a.tresresource - Update calls to
GBOwnerContext.set_owner(...)to pass a GBOwner instance - Replace direct logger instantiation with the container-provided logger
- Add target resolution metadata - For custom objects with collision shapes on child nodes, add
"root_node"metadata or Manipulatable components to ensure correct targeting - Migrate any
TileMapreferences toTileMapLayerwhere applicable
Recommended updates (backwards compatible)
- Replace direct position conversion calls on GridPositioner2D with GBPositioning2DUtils static methods
- Review visibility logic if relying on
hide_on_handledbehavior withenable_mouse_input = false
Validation
- Build and run your project - check console for any errors about missing methods/properties
- Verify dependency injection works (no manual validation calls needed)
- Test all game modes (build/move/demolish) to ensure proper functionality
- Check that indicators rotate/flip correctly with preview objects
Where to get help
- Inspect demos under
godot/demos/*for up-to-date integration examples using the composition container and injector systems. - Discord support: see the channel listed in the plugin README.