GridPlacement 6.0 separates Core (pure C#, no engine dependencies) from Godot (engine-specific adapters). This gives you a clean boundary for testing, headless operation, and porting.
The Four Layers
┌─────────────────────────────────────────────────────────────────┐
│ Addon Layer (demos/addons/grid_placement/) │
│ - [GlobalClass] types the consumer wires in scenes │
│ - PlaceableDefinition, RuleSettings, IndicatorSettings │
│ - RuleCheckIndicator, TileBuildabilityIndicator │
│ - GridPlacementPlugin (EditorPlugin) │
└────────────────────────────┬────────────────────────────────────┘
│ symlinked UI/ → Godot/UI/
▼
┌─────────────────────────────────────────────────────────────────┐
│ Godot Layer (MoonBark.GridPlacement.Godot) │
│ - PlacementBootstrap (Resource) — coordinator & signal buses │
│ - PlacementRuntimeCoordinator — per-frame update loop │
│ - TileMapSyncManager — ECS → TileMap sync │
│ - PlacementProvider — tilemap/objects parent contract │
│ - PlacementInputHandler — input processing (plain C# class) │
│ - Godot Events → ECS Events bridge │
└────────────────────────────┬────────────────────────────────────┘
│ calls
▼
┌─────────────────────────────────────────────────────────────────┐
│ ECS Layer (MoonBark.GridPlacement.ECS) │
│ - GridPlacementEcsPlugin (IEcsPlugin entry point) │
│ - GridOccupancySystem, ManipulationSystem │
│ - Friflo.Engine.ECS Entity/Component │
│ - Pure C#, no Godot dependency │
└────────────────────────────┬────────────────────────────────────┘
│ uses
▼
┌─────────────────────────────────────────────────────────────────┐
│ Core Layer (MoonBark.GridPlacement.Core) │
│ - Interfaces: IPlacementCoreService, IGridOccupancy, │
│ ITargetingService, IManipulationRuntimeCatalog │
│ - Validation: PlacementRuleRegistry, IPlacementRule │
│ - Events: PlacementEventBus, ManipulationEventBus │
│ - Pure C#, no Godot dependency │
└─────────────────────────────────────────────────────────────────┘
Note: ECS types live in MoonBark.GridPlacement.ECS.csproj (a separate project from Core). The "ECS layer" is a logical grouping with its own csproj. GridPlacementEcsPlugin lives in the ECS project and implements IEcsPlugin.
Key Types by Layer
| Layer | Primary Types | Purpose |
|---|---|---|
| Godot | PlacementBootstrap (in PlacementCoordinator.cs), PlacementRuntimeCoordinator, TileMapSyncManager |
Scene wiring, input, ECS ↔ TileMap sync |
| ECS | GridPlacementEcsPlugin, GridOccupancySystem, ManipulationSystem |
Authoritative occupancy, move/demolish operations |
| Core | PlacementEventBus, ManipulationEventBus, IGridOccupancy, ITargetingService, PlacementRuleRegistry |
Business logic interfaces, validation, events |
Plugin Architecture Pattern
GridPlacement uses the IEcsPlugin pattern for ECS integration:
public sealed class GridPlacementEcsPlugin : IEcsPlugin
{
public void RegisterSystems(EcsWorld world, SystemRunner runner)
{
var group = new EcsSystemGroup("GridPlacement");
group.Add(new EcsSystemAdapter("GridOccupancy", _occupancySystem.Update));
runner.Add(group);
runner.Add(_manipulationSystem);
}
}
Godot calls plugin.Install(world) and uses ECS types directly via IGridPlacementOperations.
Multiplayer Topologies
GridPlacement supports four topologies:
| Topology | Description | Server |
|---|---|---|
| Single-player | All systems run in one process | N/A |
| Listen-server | One player is also the host | Host process |
| Dedicated server | Headless authoritative host | Dedicated process |
| Local multiplayer | Same device, multiple input sources | N/A |
The Four Seams (Listen-Server / Dedicated)
| Seam | What | Where you code |
|---|---|---|
| Catalog | All peers load same placeable assets | Lobby / loading |
| Intent | Client → Server: (placeableId, gridPos) |
RPC call |
| Authority | Only host runs placement pipeline | Guard with Multiplayer.IsServer() |
| Event Relay | Server → All: placement outcome | rpc() broadcast |
What the Plugin Provides
| Capability | Type |
|---|---|
| Authoritative occupancy | IGridOccupancy |
| Conflict detection | PlacementValidator |
| Headless loop | PlacementExecutionSystem |
| Concurrent placers | OwnerKey |
| ECS events | IEcsBackendEvents |
| Save/restore | ECS serialization |
What the Plugin Does Not Provide
- Network transport (ENet, WebSocket, Steam, etc.)
- Lobby / matchmaking
- Clock synchronization
- Lag compensation
Related Guides
- [Composition + Injection]({{% ref "composition-and-injection" %}}) — How PlacementBootstrap wires services
- [Settings Architecture]({{% ref "settings" %}}) — Configuration resource hierarchy
- [Manipulation]({{% ref "manipulation" %}}) — Move/rotate/demolish orchestration
**Last Updated: 2026-05-31