A game bridge is useful when your game needs to combine Grid Placement results with substantial game-owned policy: ownership, economy, construction progress, faction rules, AI tasks, or your save-domain IDs.
It is optional. A simple game can call Grid Placement directly.
Use a bridge when it improves ownership clarity
Good reasons:
- several game systems need one game-specific placement operation;
- placement success must create/update a game-domain entity;
- faction/player ownership must be attached to committed placement;
- construction/cost/progression policy belongs to the game;
- your save system maps plugin
placement_instance_idto a separate game building/entity id; - you want plugin-specific types isolated from a large simulation/domain module.
Do not create a bridge because of an arbitrary call count or file-length threshold.
Authority rule
A bridge translates between two domains; it must not create a second placement database.
game request/policy
→ game bridge/BuildingAuthority
→ Grid Placement preview/validate/commit
→ typed placement result
→ game updates game-owned domain stateGrid Placement remains authoritative for its reusable placement facts:
- target/placement validity;
- committed placement identity;
- GRID/SMOOTH occupancy;
- CELL/EDGE/FACE/socket occupancy;
- placement transform/mount/support evidence;
- placement-world restore.
Your game remains authoritative for:
- ownership/factions;
- construction/progress;
- costs/resources beyond the placement bridge contract;
- game entity/building ids;
- AI/pathfinding consequences;
- game save schema and progression.
Avoid parallel state
Do not keep a bridge-side _occupied dictionary that tries to mirror Grid Placement occupancy. If the game needs its own spatial facts for gameplay, define why that state is game-authoritative and reconcile it through stable placement identity/results rather than copying plugin internals.
Prefer game-specific operations
A bridge is most useful when it exposes game language instead of every plugin primitive.
Example shape:
class_name BuildingAuthority
extends Node
signal building_committed(building_id:int, placement_id:StringName)
signal building_rejected(reason:String)
func request_build(owner_id:int, entry_id:StringName, target)-> void:
# 1. Check game-owned permissions/cost policy.
# 2. Submit through the supported Grid Placement API.
# 3. On commit, create/update the game-owned building record.
passThe exact target/result type can differ between 2D GRID, 3D GRID mounts, and SMOOTH placement. Do not force every dimension through an invented dictionary envelope just to make the bridge look uniform.
Use providers/rules for read-only facts
If the plugin only needs to read a game fact during validation, a custom placement rule or world-facts provider is often smaller than a full bridge.
Examples:
- protected build zone;
- technology unlocked;
- 2D reserved cell;
- inventory availability.
Use a bridge when the game must coordinate a larger lifecycle around committed placement.
Save/load mapping
Keep plugin placement identity and game entity identity distinct:
placement_instance_id ↔ game building/entity idPersist that mapping in your game save/domain layer. Let Grid Placement restore placement facts; let the game restore its own fields and reconnect through the stable mapping.
Anti-patterns
Avoid:
- bypassing Grid Placement validation/occupancy from the bridge;
- re-exporting private/internal service objects as your game's public API;
- duplicating placement records in several unsynchronized dictionaries;
- putting faction/economy/construction types into the reusable addon;
- wrapping every plugin method one-for-one without adding a useful game-domain boundary.