This is the shortest supported path from a fresh install to one successful placement. Follow the steps in order; each one builds on the previous.
Requirements: Grid Placement 6.1.0, Godot 4.5.x minimum, GDScript.
We'll build the beginner path with 2D TileMapLayer object placement because it has the fewest moving parts. 3D GridMap GRID/SMOOTH placement works the same way; once the setup below makes sense, switch to 3D Object Placement.
Read in this order
If you are new, read these four guides first and ignore the rest until you need them:
- This guide — install, wire one session, place the first object.
- Placement Workflow — preview → validate → commit → manipulate/demolish.
- Choosing Terrain vs Objects — decide between 2D terrain cells and placeable scene objects.
- Surface & Brush Reference — support matrix and 2D brush semantics.
Everything after that is on-demand reference. The guide navigation on the documentation site lists them all.
Learn from the demos
Five reference demos ship with the addon and are the fastest way to see a working setup. Open one, run it, then compare its scene tree and resources with your own.
| Demo | Scene | Good first look at |
|---|---|---|
| Top-down 2D | res://demos/top_down/demo_top_down.tscn |
The minimal 2D loop: session, level context, positioner, catalog UI. Start here. |
| Isometric 2D | res://demos/isometric/ |
Isometric targeting and Building-profile tools. |
| Platformer 2D | res://demos/platformer/ |
Side-view placement. |
| Hex 2D | res://demos/hex/ |
Hex-grid placement. |
| 3D GridMap | res://demos/3d/ |
GRID/SMOOTH object placement, mounts, sockets. |
The shipped set is listed in res://demos/demo_manifest.json.
1. Install
- Copy
addons/grid_placementinto your project. - Copy
templates/grid_placement_templatesif you want the starter scenes/UI. - Enable Grid Placement in Project Settings → Plugins.
- Run Project → Tools → Grid Placement / Setup Default Input Actions.
- Restart the editor.
Confirm the placement actions appear in Project Settings → Input Map.
2. Understand the minimum runtime
Five pieces cooperate at runtime. You don't need to understand how they work inside — just know which piece does which job:
| Piece | What it does for you |
|---|---|
GridPlacementHost |
Owns placement input/dispatch and composes the active placement services. This is the canonical 6.0 runtime host. |
PlacementSession |
A resource that remembers what this player has selected, where they're aiming, and their placement settings. |
PlacementLevelContext |
Tells the plugin which surface to snap to and where placed objects should go. |
PlacementOwner |
Says who is doing the placing (your player or controller). |
GridPositioner2D |
Tracks which grid cell the player is pointing at and self-registers its assigned session with the nearest host. |
Author one GridPlacementHost per scene. The controller configures it with the session, registers the session, and calls host.bind_scene_consumers(root, session) so UI and previews receive their dependencies.
PlacementInjectorSystem still exists as a compatibility path for older/template integrations, but new 6.0 setups should use GridPlacementHost directly.
Two vocabulary notes that prevent confusion later: the resource describing a placeable object is a ScenePlacementEntry (the 5.x class literally named Placeable was renamed), while "placeable" remains the everyday noun for the catalog thing. See Architecture Overview for the full entry/placeable/manipulation glossary.
3. Build the minimal scene
This is the smallest scene that supports 2D placement. The node names below are just suggestions — what matters is the node types and the script/resource assignments.
Main (Node)
├─ Systems (Node)
│ └─ GridPlacementHost (Node + GridPlacementHost script)
├─ Level (Node2D + PlacementLevelContext script)
│ ├─ GroundMap (TileMapLayer — your grid surface)
│ └─ PlacedObjects (Node2D — placed objects end up here)
├─ Player (CharacterBody2D + PlacementOwner script, owner_root = Player)
│ └─ GridPositioner2D (instance grid_positioner_stack.tscn, session = your_session.tres)
└─ UI (CanvasLayer)
└─ PlaceableSelectionUI (instance placeable_selection_ui.tscn)Now connect them in the Inspector, top to bottom:
| # | On node | Set field | To |
|---|---|---|---|
| 1 | GridPlacementHost |
grid_placement_bundle |
Your GridPlacementBundle. Use the same bundle referenced by your session. |
| 2 | Level (PlacementLevelContext) |
target_map |
Your GroundMap TileMapLayer. This is the grid the plugin snaps to. |
| 3 | Level (PlacementLevelContext) |
objects_parent |
Your PlacedObjects Node2D. Placed objects end up here — never on the map itself. |
| 4 | Player (PlacementOwner) |
owner_root |
The Player node itself. |
| 5 | GridPositioner2D |
session |
Your PlacementSession resource. At runtime the positioner configures from this session and registers it with the nearest GridPlacementHost. |
Starter pieces you can instance or duplicate instead of building from scratch:
- Positioner stack:
res://templates/grid_placement_templates/grid_positioner/grid_positioner_stack.tscn - Targeting defaults:
res://templates/grid_placement_templates/resources/top_down/targeting_settings.tres(or theisometric//platformer/sibling) - Validation defaults:
default_collisions_check_rule.tres,default_within_tilemap_bounds_rule.tresintemplates/grid_placement_templates/resources/
4. Create the session resource
Create one PlacementSession resource (right-click in the FileSystem dock → New Resource… → PlacementSession) and fill its four slots:
| Slot | Holds | Beginner advice |
|---|---|---|
bundle |
The placement bundle (services/composition). | Duplicate a demo bundle first (e.g. demos/top_down/config/td_placement_bundle.tres) or a template bundle (templates/grid_placement_templates/resources/top_down/td_placement_bundle.tres). |
settings |
Targeting/building/save settings. | Duplicate the demo settings next to the bundle you copied. |
actions |
Input actions the session listens to. | Leave the defaults installed by step 1 until placement works. |
catalog |
Which entries the player can place. | Empty at first — section 5 adds your first entry. |
Assign this resource to GridPositioner2D.session, and use the same placement bundle on the host. The positioner self-registers that session with the nearest GridPlacementHost at runtime. One session per independent player; do not share a session between players that need separate selection or targeting state.
5. Create one placeable
Create a simple object scene (anything visible, e.g. a Sprite2D), then a ScenePlacementEntry resource that points at it (FileSystem dock → New Resource… → ScenePlacementEntry).
For your first object, fill in only these:
packed_scene— your object scene. Required.display_name— the name players see in the selection UI.profiles— leave empty for now. Add aPlacementProfilelater, only if the object needs category, tool, or rule behavior.- Skip custom rules until basic placement works.
Then add the entry to the session's catalog so it shows up in the selection UI.
If you use collision-based validation, set collision layers/masks deliberately on both the object and the targeting shape cast — mismatched masks fail silently, and this is the most common "nothing happens" cause.
Author the object scene around its placement origin
Keep the packed scene root as the placement origin; do not move the root to compensate for grid alignment. For centered multi-cell artwork, cell_anchor_mode may need a different seat on X and Y depending on whether each cell span is odd or even.
See 2D Object Scene Setup for the canonical root/sprite/collision contract, the cell-anchor table (including 256×96 on a 32px grid), intentional child offsets, and directional sprite authoring.
6. Select and place it
Use the shipped selection UI — PlaceableSelectionUI, the component under
addons/grid_placement/ui/placeable/ (placeable_selection_ui.gd plus its
placeable_view and shared selection-logic helpers). A ready-made starter
scene is at
templates/grid_placement_templates/ui/placement_selection/placeable_selection_ui.tscn.
Use it — or your own UI — to pick the entry.
When everything is wired correctly, your first placement looks like this:
- The entry becomes active after you select it.
- The preview follows the grid cell under your cursor.
- The preview shows whether the spot is valid or blocked.
- Clicking confirm places one object under
objects_parent. - No errors appear in the Output panel.
If the preview works but the object never appears, read the placement failure report before changing any code. The usual causes are a missing context node, an occupied cell, a rule, or collision masks.
7. Check these settings first when it does not work
Most first-run failures are settings problems, not code problems. Check these in order:
- Input actions — installed via Project → Tools (section 1, step 4) and visible in the Input Map.
- Session wiring —
GridPositioner2D.sessionis assigned, and the positioner can find the nearestGridPlacementHostat runtime. - Host bundle —
GridPlacementHost.grid_placement_bundlematches the bundle used by the session. - Level context —
target_mapandobjects_parentare both assigned, and they point at different nodes. - Owner —
owner_rootpoints at your player/controller root. - Indicator vs tile size — if the cursor graphic doesn't match your tiles, adjust the indicator's visuals — never the placement coordinates.
- UI overlap — a
Controlcovering the screen swallows clicks meant for placement. Keep HUD panels out of the play area while testing. - Collision masks — targeting, validation, and the object's own body must all agree on layers/masks.
See Troubleshooting before building a workaround.
8. Add features one at a time
After one object works, add only the one feature you need next:
- 2D terrain painting: start with
SINGLE, then try LINE/rectangle/flood brushes. - Object LINE placement: turn it on through the entry/profile that should support it.
- Manipulation: let players move/rotate/flip/demolish placed objects.
- Persistence: save the world → restore it → keep building.
- Custom rules/world facts: connect your game's own placement restrictions.
- Multiple sessions: split-screen/multiplayer/controller-specific state.
- 3D GRID: cell-aligned structures and CELL/EDGE/FACE/CORNER/TOP mounts.
- 3D SMOOTH: free placement anywhere in the world, with optional sockets.
- 3D slope/support: control which slopes 3D structures may sit on.
Resist adding everything just because it's there — each feature is easier to debug on its own.
2D terrain vs 3D terrain
Terrain painting covers 2D TileMapLayer and 3D GridMap (single cells plus LINE/rectangle brushes; FLOOD_FILL stays 2D-only). See 3D Terrain Painting. 3D slope/support settings validate where objects may sit; they do not modify terrain.
Common first-run failures
If placement does nothing at all, run down this list — one of these is almost always the reason:
- Plugin not enabled in Project Settings.
- Default input actions not installed (section 1, step 4).
GridPositioner2D.sessionnot assigned or not registered with aGridPlacementHost.GridPlacementHost.grid_placement_bundlemissing or mismatched.PlacementLevelContext.target_maporobjects_parentmissing.PlacementOwner.owner_rootmissing.- Positioner not connected to the active interaction.
- A UI
Controlis eating the clicks meant for placement. - Collision layers/masks don't match between targeting and validation.
See Troubleshooting before building a workaround.
Next guides
Read these in order; stop when your game works: