Grid Placement supports multiple independent placement interactions through one PlacementSession per player/controller.
The important split is:
Player A session ─┐
├─ GridPlacementHost → shared committed placement world
Player B session ─┘Selections/previews are independent. Committed occupancy/mounts are shared when both players are building in the same world.
Register one session per controller
var session:= PlacementSession.new()
session.grid_placement_bundle= shared_bundle
host.register_session(self, session, player_device)Unregister it when the controller leaves:
host.unregister_session(self)Use a device id when your local input setup needs device-based routing. For keyboard/mouse or custom input routing, wire the project input layer intentionally rather than assuming the plugin can infer player ownership.
What stays independent
Each session can have its own:
- selected placeable/terrain;
- GRID vs SMOOTH mode;
- current preview/target;
- pending manipulation/brush action;
- unlock/catalog availability;
- controller-specific UI/input state.
What is shared
Sessions in the same placement world must agree on committed facts:
- placed object identity;
- GRID/SMOOTH occupancy;
- CELL/EDGE/FACE/socket occupancy;
- save/restore world records.
If Player A occupies an EDGE mount, Player B should see that same edge as occupied even though their previews/selections are independent.
Split-screen presentation
State isolation does not automatically build a split-screen UI for you. Your game owns:
- cameras/viewports;
- player-specific cursor/target adapters;
- per-player HUD/catalog presentation;
- device/action mapping.
Make each HUD read its player's PlacementSession. Avoid global mutable selection state.
Network multiplayer boundary
Grid Placement provides placement mechanics/state, not a complete network-authority model.
Your game still decides:
- client prediction vs server authority;
- RPC/replication format;
- permission/ownership checks;
- rollback/reconciliation;
- persistence ownership.
A networked game should have its authoritative game layer validate/accept placement requests through the supported placement APIs rather than trusting a client-side preview.
2D and 3D
The same session/world split applies to:
- 2D objects and terrain interaction state;
- 3D GRID/SMOOTH object placement;
- CELL/EDGE/FACE/socket structures;
- shared occupancy and restore.
Do not create separate competing placement worlds just because players use different coordinate modes.
Common mistakes
| Symptom | Cause to check |
|---|---|
| Player A changes Player B's selection | Sessions are shared or UI points at the wrong session. |
| Two players place into the same occupied location | They are not sharing the same authoritative placement world/registry. |
| Wrong player reacts to controller input | Device/action routing or controller→session registration. |
| HUD shows another player's state | UI reads a global/default session instead of its owner session. |
| Network client can bypass rules | Game/server authority is trusting client state instead of validating placement. |