Manipulation: System vs Input Controller (6.0)
GridPlacement 6.0 separates orchestration from input handling for object manipulation (moving, rotating, flipping placed objects). This guide explains why this split exists and how it affects your code.
The Core Split
In 6.0, manipulation is divided into two distinct responsibilities:
- ManipulationSystem (via
PlacementContext.ManipulationSystem) — The “Brain”. Owns validation, state transitions, and coordinates sub-systems. - PlacementInputController — The “Hands”. Routes confirm/cancel input from cursors to the manipulation bridge.
Why this split exists
The 6.0 architecture intentionally separates orchestration from input routing:
- Testability: The
ManipulationSystemcan be tested without needing a complex scene tree - Clarity: You know exactly where to look for validation logic (ManipulationSystem) vs. input handling (InputController)
- Stability: Transform state is managed through ECS components, preventing drift from repeated calculations
Responsibilities (Godot Adapter API)
| Component | Role | Owns | Does NOT own |
|---|---|---|---|
ManipulationSystem | Business Logic | Lifecycle (start/commit), validation, state transitions, events | Direct input handling, visual transforms |
PlacementInputController | Input Router | Wiring cursor signals to IPlacementInputBridge, confirm/cancel routing | Validation rules, grid occupancy checks |
PlacementSceneAdapter | Scene Sync | Ghost/preview entity creation, ECS-to-Godot sync | Validation logic, input handling |
Scene Integration
When you pick up an object, the flow looks like this:
| |
The Cursor2D detects input → PlacementInputController forwards it → ManipulationSystem processes it.
Key 6.0 Behaviors
1. Movable Validation
In 6.0, ManipulationSystem enforces the IsMovable check on the source object via ECS components:
- Behavior: The system validates against
SelectedPlaceableComponentandTransformComponent2D - Flow: Input →
PlacementInputBridge→ManipulationSystem→ Validation → Ghost update
2. Transform Preservation
When a move completes, the transform is preserved through ECS state:
- Flow: Move Start → Store original transform → User rotates/flips → Confirm → Apply final transform
- Note: Transforms are stored on ECS components, not scene nodes directly
3. Visual Sync
Because the system uses ECS components, visual sync happens through:
PlacementSceneAdapter— Syncs ECS state to Godot nodesCursor2D— Handles cursor visual representation- Ghost entities — Managed by
MoveManipulationSystem(internal)
Accessing Manipulation in Godot
| |
PlacementInputController Wiring
| |
Common Pitfalls
- Direct Node Access: Don’t try to access
ManipulationSystemas a Godot node — it’s an ECS system accessed viaPlacementContext - Input Consumption: Input is routed through
PlacementInputController, not handled directly by systems - Orphaned Ghosts: If the operation is interrupted,
PlacementSceneAdapterhandles cleanup automatically - Transform Access: Access transforms via ECS components, not
node.Positiondirectly
Related Guides
- Architecture Overview — Includes multiplayer topology details
- Composition + Injection
- Placement Rules
- Getting Started — First placement workflow