Grid Placement 6.0 supports 3D object placement on GridMap in two coordinate modes:
- GRID — cell- and mount-aligned placement for structures and other grid-aligned objects.
- SMOOTH — free world-space placement with optional world-space sockets.
3D terrain editing/painting remains outside the supported public addon contract.
Choose the placement mode first
Use GRID for floors, walls, fences, windows, modular structures, or anything else that must align to cells or structural mounts.
Use SMOOTH for clutter, organic props, furniture, or object-to-object joins that should not be tied to GridMap cells.
See Grid vs Smooth Placement for the detailed tradeoff.
GRID placement lifecycle
A normal GRID placement follows this path:
- Select a
ScenePlacementEntry. - Target a
GridMapcell or mount. - Show the placement preview and validation feedback.
- Rotate yaw when the entry allows it.
- Confirm placement.
- Record occupancy, mount data, transform, and stable placement identity.
- Move, remove, save, or restore the object through the same placement world.
Preview and commit use the same placement result. If the world changes before confirmation, the final validation result decides whether placement succeeds.
CELL, EDGE, FACE, CORNER, and TOP
PlacementSnapProfile3D.SnapMode controls where a GRID entry attaches.
| Mode | Meaning | Typical use |
|---|---|---|
CELL |
Occupies a GridMap cell or footprint |
floor, foundation, crate |
EDGE |
Occupies a canonical edge between neighboring cells | wall, fence panel, door frame |
FACE |
Mounts to a supported provider face | window, shutter, wall decoration |
CORNER |
Occupies a canonical XZ grid intersection | structural corner post |
TOP |
Occupies the top of a host EDGE, or the cell-centered ridge | roof plane, gable, ridge cap |
EDGE/FACE occupancy is canonical from either neighboring cell, so the same physical edge cannot be double-booked by addressing it from the other side. TOP wall-tops use that same canonical EDGE key in a separate occupancy table, so a wall and its roof coexist. Ridge uses edge (0, 0, 0) and requires opposite roof tops on the cell.
CORNER uses the shared grid intersection. A CORNER entry needs two perpendicular hosts at that intersection. Their saved yaw directions must differ by an odd number of quarter turns, so one host runs along X and the other along Z. One host or two parallel hosts is invalid.
Cursor picking for EDGE, FACE, and TOP
PlacementInputHandler3D turns a cursor over a cell into the mount the ghost should show. It keeps the picked wall line steady against cursor tremor, mounts an aimed wall face on its own slot, hosts a room's boundary wall on the floored side, continues an existing same-family run, and resolves an occupied slot to the piece already standing there so replacements preview in place. TOP picks hold the chosen roof slope or ridge the same way.
Configure it once with the GridMap, the ObjectPlacementService3D, and optionally the GridPositioner3D whose physics hit it prefers. Each frame, pass the cell and the cursor's point on the cell's surface plane (Vector3.INF when there is no usable ray):
var handler:= PlacementInputHandler3D.new()
handler.configure(grid_map, object_service, positioner)
var mount:= handler.resolve_edge_mount(cell, plane_hit)# [mount_cell, edge]
object_service.update_preview_edge(mount[0], mount[1])Input events, rotate keys, and the commit stay in your game code. Set wall_axis_lock (or call toggle_wall_axis) from your rotate keys, and call reset() when a gesture is cancelled or the cursor leaves the grid. The 3D demo uses it this way.
FACE providers
A provider must explicitly expose mountable faces. The consumer's snap profile must accept the provider family. FACE save data preserves the provider, mount identity, and orientation so restore can rebuild the same relationship.
Preview object vs mount indicator
The placement preview (sometimes called the ghost) shows where the object will be placed.
The indicator shows what is being validated:
- CELL — the evaluated cell or footprint support;
- EDGE — the claimed edge at its structural height;
- FACE — the provider face;
- CORNER — the claimed grid intersection;
- TOP — the host EDGE or cell-centered ridge.
Both come from the same placement result. An elevated mount should therefore be highlighted at its actual height instead of pointing at unrelated ground below it.
Use the shipped 3D demo as the reference for floor → CELL wall → FACE-mounted piece placement and for House Corner placement at wall intersections.
Optional blocked patterns
Color-only previews remain the default. In the 3D demo, enable Blocked preview stripes to add diagonal bands to the invalid-color tint. Valid previews keep their normal tint. Turn it off to return to flat colors.
For your own integration, set ObjectPlacementSettings3D.blocked_feedback to BlockedFeedback.STRIPES (or FLAT_COLOR). The same settings resource controls GRID ghosts, mount/footprint indicators, and host-owned SMOOTH ghosts. You can assign blocked_pattern_texture to replace the built-in grayscale pattern; the invalid color still tints it. Standalone SMOOTH services use attachment_settings for this resource.
Patterns follow the existing validity result, including when valid and invalid colors are identical. They do not change placement rules. Keep text feedback for failure reasons and check contrast against your own scenes.
Snap families
PlacementSnapProfile3D lets entries describe what they provide and what they can attach to.
| Field | Purpose |
|---|---|
family |
Category published by the placed object. |
snaps_with |
Provider families this entry may attach to. |
attachment_requirement |
INHERIT (default, uses the settings default), OPTIONAL (free placement), or REQUIRED (must satisfy the mount's normal compatible-attachment rule). |
corner_host_topology |
CORNER-only: INHERIT (default), ANY_ONE (one compatible host), or TWO_ORTHOGONAL (strict two-host contract). |
edge_dressing |
EDGE-only: DEFAULT keeps along-edge yaw for symmetric pieces; OUTWARD and INWARD orient asymmetric pieces' dressed (+Z) face away from or toward the host side. |
edge_outward_facing |
Legacy compatibility alias. When edge_dressing remains DEFAULT, true resolves to OUTWARD. |
require_edge_span_floor_support |
EDGE-only, default false. When enabled, every host-side tile touched by the authored EDGE span must publish the floor family. |
The consumer decides what it accepts. You can keep names broad (wall, floor) or use project-specific families without changing plugin code.
Attachment strictness is one shared policy across CELL/EDGE/FACE/CORNER/TOP and SMOOTH socket consumption: mount identity (where the piece sits) never changes with the policy — only whether a compatible provider must be present. The legacy require_adjacent_snap boolean is deprecated but still resolves identically (false → OPTIONAL, true → REQUIRED); set attachment_requirement explicitly on new profiles.
Setting up a placeable 3D object
A basic GRID placeable needs three pieces of setup:
- Packed scene — the object scene used when placement commits. Use the shipped
demos/3d/objects/scenes as component-layout references. ScenePlacementEntry— points to the packed scene and defines its placement data.- Catalog registration — add the entry to the
PlacementCatalogused by the session so it can be selected.
For the ScenePlacementEntry, configure the fields that apply to the object:
footprint_3d— occupied cells for each yaw step;snap_profile_3d—family,snaps_with,attachment_requirement, andsnap_mode;seam_bounds_3d— only when the snap profile enablesseam_close_to_partnerand the asset needs mesh-aware seam closure.
Choose the mount mode from the object's actual placement behavior: CELL for cell/footprint pieces, EDGE for edge panels, FACE for provider-mounted pieces, CORNER for intersection posts, and TOP for roof planes, gables, or ridge caps.
The shipped demo provides copyable references in demos/3d/placement/placeables/*.tres, demos/3d/config/3d_catalog.tres, and demos/3d/demo_3d.tscn. When adapting one, replace the scene and update its footprint, snap profile, and seam bounds for your own asset instead of only swapping the mesh.
In the demo, selecting an entry shows the preview and mount-aware indicator. You can then rotate, place, move, demolish, save, and restore the committed object through the normal placement workflow.
Footprints and rotation
ScenePlacementEntry.footprint_3d defines the CELL GRID footprint. CELL occupancy and support validation apply to the complete rotated footprint. EDGE pieces instead use footprint_3d_world for their span; set require_edge_span_floor_support only on structural entries that must have floor under every host-side tile they cover.
GRID structures use discrete yaw rotation. Structural pieces remain world-up by default; terrain slope does not automatically tilt walls or foundations.
Ground, slope, and partial support
GRID placement can validate the support below a footprint. Different placeables can use different support rules.
Typical controls include:
- maximum allowed ground slope;
- support, height, and planarity tolerance;
- minimum support coverage;
- optional center or edge support requirements;
- stricter physics-required support when the project needs it.
For example, a small prop can allow some overhang while a building foundation requires stronger coverage. Configure that policy on the relevant entry instead of weakening support rules globally.
See 3D Surface & Slope Support.
Fences and modular structures
GRID CELL/EDGE/FACE/CORNER/TOP is the supported path for cell-aligned modular structures.
A structure can combine:
- CELL floor/foundation pieces;
- EDGE walls/fences/door pieces;
- walls meeting at 90-degree EDGE corners;
- FACE-mounted pieces such as windows/shutters;
- CORNER-mounted structural posts where the kit uses them;
- TOP-mounted roof planes, gables, and a cell-centered ridge;
- removal and re-placement;
- save → clear → restore → continue.
TOP occupancy is keyed by the host EDGE (separate table), so a wall and its roof can coexist. Ridge uses edge (0,0,0) and requires opposite roof tops. Snap-family names still do not create a new mount type.
The shipped 3D demo's modular house kit uses these placement paths for its floor deck, walls, door, shuttered windows, and corner posts.
Sized pieces and wall runs
Piece sizes are authored, not resized at runtime: there are no scale handles. To offer a longer wall, ship a bigger catalog variant (the demo kit has 1 m, 2x1, and 2x2 wall entries) and let players chain runs with the EDGE line drag, which mounts one panel per authored span width along the dragged run.
EDGE mounting also validates spans: collinear penetration and true pass-through crossings are rejected, while end-to-end joins, 90-degree corners, and T-junctions remain legal. Same-anchor replacement is unaffected. Span size comes from the entry's footprint_3d_world (x = span along the edge, z = thickness across it), positioned at the measured mesh. Structural entries can set require_edge_span_floor_support to require floor under every host-side tile touched by that span; empty-yard fences and wall chaining remain anchor-only unless they opt in.
Line and rectangle fills
ObjectFillSpan3D turns one drag between two grid cells into the pieces a LINE, RECTANGLE_FILL, or RECTANGLE_OUTLINE brush places, and commits them through ObjectPlacementService3D in order. CELL entries place one piece per span cell; EDGE entries mount one piece per authored span width and keep the pressed wall's rotation along the run. Your game supplies the cursor: set the drag corners, the pressed EDGE mount if any, and optional cursor_edge / cursor_mount callables for drags with no direction.
var fill:= ObjectFillSpan3D.new(service)
fill.brush_shape= PlacementEnums.ObjectTool.RECTANGLE_FILL
fill.start_cell= press_cell
fill.end_cell= hover_cell
fill.max_cells= 64
var cells:= fill.cells()# empty when the drag exceeds max_cells
var verdicts:= fill.cell_verdicts(fill.cells_3d(cells))# preview, in commit order
var result:= fill.commit(cells)# on release
print("placed%d of%d" % [result.committed, result.attempted])cell_verdicts judges each anchor the way the commit will, so a 2x2 piece dragged in a line previews the anchors its own footprint covers as blocked. For EDGE entries, preview_edges(cells) tints the service's span ghosts. The 3D demo drives its fill drags through this class.
Roofs and gables
TOP is the supported roof and gable mount in the 6.2.0 contract. Roof and gable entries attach to a host EDGE, while the ridge is cell-centered and requires the opposite roof tops described above.
Do not use an arbitrary snap-family name to imply a new mount type.
SMOOTH world-space sockets
SMOOTH can optionally publish and consume world-space sockets for joins that should not use GRID CELL/EDGE/FACE/CORNER/TOP keys.
Common socket roles include ends, perimeter points, faces, and upward points. A consumer still uses family and snaps_with to choose compatible providers.
The default SMOOTH behavior remains free placement. Socket snapping is opt-in through the entry/profile configuration.
GRID mounts and SMOOTH sockets use different occupancy identities:
- GRID mounts use canonical cell, edge, face, corner, or TOP keys.
- SMOOTH sockets use provider identity plus world-space socket identity.
See Smooth Placement.
Validation failures
A 3D placement can reject for reasons such as:
- missing or invalid active entry;
- occupied footprint or mount;
- unhosted or occupied corner intersection;
- incompatible snap family or provider;
- missing required ground or support;
- slope/support policy failure;
- collision or overlap conflict;
- missing physics evidence when a physics-required policy is selected.
Use the report-producing placement APIs when your UI or game needs typed failure information. Keep surface/support failures distinct from occupancy failures so the player receives the correct feedback.
Persistence
Supported 3D placements keep stable placement identity plus the transform, occupancy, and mount data needed to restore the same world state. GRID, SMOOTH, CELL/EDGE/FACE/CORNER/TOP mounts, sockets, and shared occupancy are restored together.
See Save and Load.
Supported boundaries
- 3D object placement: supported.
- GRID + SMOOTH: supported.
- Generic GRID roof/top mount: supported as SnapMode.TOP (wall-top and ridge). SMOOTH
UPsockets remain the free-placement path. - CELL / EDGE / FACE / CORNER / TOP structure workflows: supported.
- Configurable GRID slope/support validation: supported.
- Automatic structural GRID pitch/roll to follow terrain: not supported by default.
- 3D terrain editing/painting: supported (paint/erase, LINE/rectangle brushes, game-authored rule evaluation;
FLOOD_FILLnot supported in 3D).