Targeting answers where the player is pointing. Validation answers whether the requested action is allowed. Keep those responsibilities separate.
2D GRID targeting
The standard 2D path uses:
GridPositioner2D— resolves/snaps the currentTileMapLayercell.TargetingShapeCast2D— detects targetable placed objects for manipulation/highlight workflows.- active session targeting state — exposes the resolved target/context to placement services.
Typical flow:
input/cursor
→ GridPositioner2D resolves target cell
→ optional TargetingShapeCast2D resolves target object
→ preview/placement/manipulation reads that target
→ validation decides whether the action is allowed3D GRID targeting
GridPositioner3D resolves the 3D target from the camera/world into the GridMap placement surface.
Depending on the selected entry/workflow, the target can become:
- a CELL target;
- an EDGE target and normal;
- a FACE/provider target;
- the base GRID target used by footprint/support validation.
The 3D target is only the requested location/mount. CELL/EDGE/FACE occupancy, provider compatibility, slope/support, and collision still run through validation before commit.
See 3D Object Placement.
SMOOTH targeting
SMOOTH placement uses a world-space cursor/ray target rather than a lattice cell. The placement service may then adjust/validate that target through:
- footprint occupancy;
- optional ground/support ray;
- optional world-space socket snap;
- environment/physics checks.
The final preview transform should match the transform that will be committed if validation still passes.
2D collision targeting
For TargetingShapeCast2D, Godot collision setup must match:
- target object collision layer = what layer the object belongs to;
- shapecast collision mask = which layers the targeting query sees;
collide_with_areas/collide_with_bodiesmust match the target physics type.
If move/demolish cannot find an object, inspect this before changing placement rules.
Prefer one clear targetable root/physics owner. Putting the same targeting layer on several nested nodes can make object resolution ambiguous.
Game-owned world facts are not targeting
A 2D PlacementWorldFactsProvider2D can say that the current cell is blocked/reserved, but it does not choose the target cell. The positioner chooses the cell; the provider/rule contributes validation facts about it.
Likewise, 3D support/slope evidence does not choose which GRID cell/edge/face the player targeted. It decides whether the target is supportable.
UI and input
Godot Control nodes can consume pointer input before placement receives it. Non-interactive HUD containers should normally use a mouse-filter mode that allows gameplay targeting input through.
For multiple controllers, route each player's input/target adapters to the correct PlacementSession; do not store one global cursor/selection for all players.
Debug checklist
If targeting is wrong:
- Confirm the active session/controller is the one receiving the input.
- Confirm the correct level surface (
TileMapLayer/GridMap) is connected. - Confirm the relevant positioner/camera/raycast is active.
- For object targeting, check collision layers/masks and body/area flags.
- Temporarily hide HUD controls to rule out input capture.
- Compare the resolved target with the preview transform.
- Only after the target is correct, debug placement validity/support/rules.