# AGENTS.md

Agentic principles and technical context for the `splat` repository.

## Project overview

Splat is a **physics-first city builder** for Godot 4, written entirely in C#. Created by Ewan Croft ([ewanc26](https://github.com/ewanc26), [ewancroft.uk](https://ewancroft.uk)).

Unlike traditional city builders where physics is visual decoration, in Splat the physics engine *is* the simulation. Buildings have weight and structural integrity. Traffic consists of physical objects with momentum. Infrastructure bends, erodes, and decays. The city has physical presence, and its history is written in the wear patterns of its surfaces.

Licensed under the [GNU Affero General Public License v3.0](LICENSE). Built on the [Chickensoft GodotGame](https://github.com/chickensoft-games/GodotGame) template (MIT License) with testing infrastructure, CI/CD, and code coverage configured out of the box.

### Design pillars

1. **Physics is the simulation** — not visual, not decorative. Structural, traffic, infrastructure, and environmental physics drive every system.
2. **Anti-entropy** — the city decays. Preservation is the core verb. Nothing is disposable; everything has physical memory.
3. **Emergent over scripted** — citizens, traffic, weather, and decay emerge from physics interactions, not scripted events or abstract stats.
4. **Low stakes, no optimization** — no score, no failure state, no "optimal" layout. The city exists. You tend it. Letting things decay is valid.
5. **Systems with personality** — every building develops quirks through physics interactions. The city's physics history IS its personality.
6. **Celtic/Scottish aesthetic** — Scottish Highlands landscape, traditional materials (stone, timber, turf), moon-phase physics, seasonal cycles.
7. **Simplistic low-poly visuals** — clean geometry, minimal texture work, flat-shaded faces. Physics deformation and decay provide visual complexity without detail. The aesthetic is charming, not realistic.
8. **Sync-ready by design** — all game data is structured for eventual AT Protocol publication. No sensitive data exists; cities are public artifacts. Data structures use content-addressed, timestamped formats that map naturally to AT Protocol records.

---

## Technical philosophy

1. **C# first**: all game logic is written in C#. GDScript is not used. Follow Godot C# conventions and the Godot.NET.Sdk patterns.
2. **Physics-first architecture**: every system is built on top of the physics engine. Game logic observes and reacts to physics state; it does not dictate it. If a system can be expressed through physics, it should be.
3. **Controller-first input**: gamepad is the primary input method. Keyboard/mouse is fully supported but designed second. All actions must be reachable via controller without compromise.
4. **Testable by design**: use dependency injection, signals, and scene tree abstractions to keep code testable. Prefer composition over inheritance for node relationships.
5. **Scene as data**: leverage Godot's scene system for level design, entity composition, and UI layout. Scripts define behavior; scenes define structure. Physics properties live in custom resources.
6. **Honest stubs**: unimplemented features carry a `TODO` explaining what's missing — never a silent no-op or fabricated behavior.
7. **Ownership is explicit**: Godot's node ownership system manages scene hierarchy. For C# objects, prefer `IDisposable` where cleanup is needed. Physics bodies must be freed explicitly — Godot does not garbage-collect them.

---

## Core game mechanics

### Building placement and structural physics

Buildings are `CharacterBody3D` or `StaticBody3D` nodes with custom resources defining their physical properties:

```csharp
public partial class Building : StaticBody3D
{
    [Export] public BuildingData Data { get; set; }

    public override void _Ready()
    {
        // Apply material properties to collision shape
        // Register with BuildingManager for decay tracking
        // Connect structural integrity signals
    }
}
```

**BuildingData** resource contains:
- `MaterialType` — stone, timber, turf, concrete, steel (affects weight, durability, decay rate)
- `FoundationType` — shallow, deep, floating (affects ground interaction)
- `StructuralIntegrity` — float 0–1, starts at 1.0, degrades over time and under stress
- `Mass` — calculated from volume and material density
- `MaxLoad` — how much weight the structure can bear before deformation
- `CurrentLoad` — aggregate of all children and occupants

**Structural simulation:**
- Buildings are subject to gravity, wind forces, and ground settlement
- Poorly supported structures lean (rotation applied based on torque imbalance)
- When `StructuralIntegrity` drops below thresholds, visual deformation occurs (cracks, tilting)
- At integrity = 0, the building collapses into a pile of physics debris (`RigidBody3D` fragments)
- Neighboring buildings are affected by collapse (shockwave, debris impact)

**Foundation physics:**
- Ground type affects foundation: peat bog = slow sinking, clay = frost heave, rock = stable
- Buildings on soft ground gradually settle (translate -Y over time)
- Foundation type determines how much settling is tolerated before structural damage

### Traffic simulation

Traffic is not pathfinding. Traffic is physics.

**Vehicle entities:**
- Each vehicle is a `CharacterBody3D` with mass, friction coefficient, braking distance, and acceleration curve
- Vehicles follow road nodes but are subject to physics forces (centrifugal on curves, slope gravity)
- Collision between vehicles produces real consequences: debris, blocked lanes, emergency response

**Traffic flow model:**
- Vehicles are spawned at zone edges (residential → commercial, commercial → industrial)
- They seek destinations based on zone demand (physics: demand is a force vector)
- Intersections are physics-negotiated: vehicles yield based on arrival time and visibility
- Traffic jams emerge from actual vehicle density, not abstract capacity numbers

**Pedestrian simulation:**
- Pedestrians are small physics bodies (capsule collision)
- They flow through streets like fluid, influenced by weather, time of day, and events
- Crowds have emergent behavior: panic, gathering, dispersal — all physics-driven
- Pedestrian crossings are physical zones that slow vehicle traffic

### Infrastructure systems

Infrastructure is physical, not abstract.

**Roads:**
- Road surfaces are mesh deformers with wear maps
- Vehicle traffic applies friction forces that wear road surfaces over time
- Weather (rain, frost, heat) accelerates wear
- Potholes form at high-wear intersections
- Road quality affects vehicle speed and comfort (citizen satisfaction)

**Water pipes:**
- Physical pipe objects with pressure, temperature, and age properties
- Pipes burst when pressure exceeds material tolerance
- Pipes freeze in cold snaps (water expands, pipe fractures)
- Leaks saturate ground, causing subsidence under nearby buildings
- Pipe network is visible in overlay mode

**Power lines:**
- Physical cables with catenary physics (sag under weight/load)
- High wind causes line swing and potential contact faults
- Load (building demand) affects cable temperature and sag
- Power failures cascade physically: one snapped line de-energizes everything downstream

**Sewage/drainage:**
- Gravity-fed system with physical flow simulation
- Blockages cause overflow (visible, smelly, affects nearby zones)
- Rain overwhelmed drainage → flooding (real water physics)

### Environmental physics

Weather is physics, not a mood overlay.

**Rain:**
- Particle system with physical raindrops that collide with surfaces
- Accumulates as standing water in low-elevation areas
- Erodes exposed soil and road surfaces
- Saturates ground → reduces foundation stability

**Wind:**
- Vector field with variable speed and direction
- Applies force to tall structures (lateral load)
- Affects power line swing
- Wind + rain = accelerated erosion on windward faces

**Frost/thaw:**
- Water in pipes, ground, and building cracks freezes (expansion force)
- Frost heave lifts road surfaces and foundations
- Thaw causes settling and potential structural stress
- Freeze/thaw cycle is the primary decay accelerator

**Moon phases:**
- Tidal forces affect coastal areas (water level oscillation)
- Structural stress cycles with lunar period (subtle, atmospheric)
- Full moon = peak tidal force = maximum coastal erosion
- New moon = minimum = relative calm

### Citizen simulation

Citizens are not stats. Citizens are physics-aware agents.

**Citizen entity:**
- Small physics body with navigation agent
- Has needs: shelter (building coverage), dryness (rain protection), warmth (season), mobility (road quality)
- Needs are satisfied by physical conditions, not abstract meters
- Citizens relocate when physical conditions degrade (emigration is emergent, not scripted)

**Social physics:**
- Citizens have social proximity (attraction/repulsion based on compatibility)
- Social groups form physically: citizens cluster in public spaces
- Events (markets, festivals) create physical gathering forces
- No combat, no competition — just coexistence

### Decay and preservation

The core gameplay loop is fighting entropy.

**Decay mechanics:**
- Every structure has a decay rate based on material, weather exposure, and maintenance
- Decay is visual: cracks, moss, rust, vegetation overgrowth
- Decay is physical: structural integrity decreases, foundations settle, pipes corrode
- Abandoned structures decay faster (no maintenance, no heating)

**Preservation mechanics:**
- Maintenance crews (physics entities) visit structures to repair
- Repair restores structural integrity and visual state
- Historical structures can be preserved (reduced decay rate, special materials)
- Player can choose to preserve, restore, or let nature reclaim

**History accumulation:**
- Every repair, every weather event, every collapse leaves physical marks
- Buildings develop patina over time (visual layers)
- The city's age is visible in its surfaces
- Ruins are valid end states — not failures

---

## Visual style

Splat uses a **simplistic low-poly aesthetic**. The art style is charming, not realistic.

### Core principles

- **Low-poly geometry** — buildings, vehicles, terrain, and citizens are simple meshes with flat faces. No subdivision, no smooth shading, no detail geometry.
- **Flat shading** — materials use flat-shaded faces (no Phong, no PBR). Each polygon reads as a distinct facet.
- **Minimal textures** — color palettes define materials, not texture maps. Where textures exist, they are solid-color or simple gradients.
- **Physics provides detail** — cracks, tilts, wear patterns, moss growth, and collapse debris provide visual complexity. The mesh stays simple; the state changes.
- **Charming over realistic** — a leaning cottage with a crooked chimney is charming. A photorealistic building is not the goal.

### Color palette

**Scottish Highlands:**
- Granite grays, sandstone beiges, slate blues
- Heather purples, moss greens, peat browns
- Sky blues, cloud whites, rain grays
- Sunset oranges, heather pinks (seasonal)

**UI:**
- Dark mode with soft accents
- Celtic knotwork patterns as borders (not decorative — functional separators)
- Typography: clean sans-serif, high contrast

### Building visuals

- Each building type has a distinct silhouette (cottage, tower, warehouse, hall)
- Material is conveyed through color, not texture (stone = gray, timber = brown, turf = green)
- Decay layers add visual complexity:
  - Stage 1: clean, new (flat color)
  - Stage 2: subtle discoloration (darker patches)
  - Stage 3: moss/vegetation (green edges)
  - Stage 4: cracks, tilting, missing pieces
  - Stage 5: partial collapse (visible interior)
  - Stage 6: full collapse (debris pile)

### Vehicle visuals

- Simple geometric shapes (box, cylinder, sphere)
- Color indicates function (residential = warm tones, commercial = cool tones, industrial = muted)
- Speed lines or dust trails for movement (particles, not geometry)
- Collision damage: dents, scrapes, deformation (vertex displacement)

### Terrain visuals

- Heightmap-based terrain with flat-shaded faces
- Color bands indicate ground type (rock = gray, soil = brown, grass = green, water = blue)
- Weather effects: snow accumulation (white overlay), rain darkening, frost whitening
- Erosion: terrain vertices shift over time, creating visual wear

### Weather visuals

- Rain: simple line particles falling vertically
- Wind: particle drift, flag/cloth physics on buildings
- Snow: white particles, accumulation on surfaces
- Fog: distance-based alpha fade (not volumetric)
- Moon: simple circle with phase-appropriate shading

### Performance considerations

- Low-poly meshes = fewer vertices = better physics performance
- Flat shading = no normal maps = simpler materials
- Particle systems for weather, not mesh-based effects
- LOD not needed — geometry is already minimal
- Target: 60fps on mid-range hardware with 100+ buildings

---

## Code style

- **C# conventions**: follow Microsoft C# coding conventions and Godot's C# API naming. Use PascalCase for public members, camelCase for private fields, `_PascalCase` for virtual/override methods.
- **File organization**: one class per file. Name files after their primary class (e.g., `Building.cs` contains `Building` class).
- **Namespace**: use `namespace splat;` for all project code.
- **No commented-out code**: delete dead code or move it to a test.
- **Comments are allowed and encouraged** where they aid understanding — especially next to public API declarations, non-obvious Godot patterns, physics system interactions, and `TODO` notes. Do not add noise comments that merely restate the code.
- **Atomic conventional commits**: every commit must contain exactly one logical change. Scope by module — `feat(buildings)`, `feat(traffic)`, `feat(infra)`, `fix(physics)`, `fix(decay)`, `docs(roadmap)`, etc. Never mix unrelated changes in a single commit.
- **No AI co-authors**: commits must not add a `Co-authored-by:` trailer crediting an AI agent. AI assistance is welcome, but credit for committed work goes to human authors only.
- **Physics code comments**: when modifying physics parameters, document the physical intuition behind the values (e.g., "stone density ~2400 kg/m³, typical Scottish sandstone").

---

## Development workflow

- **Build**: `dotnet build` (requires .NET SDK and Godot 4.7+ with C# support)
- **Test**: `godot --headless --run-tests --quit-on-finish` (use GoDotTest's `--quit-on-finish`, NOT Godot's `--quit`, which kills the process after the first frame and truncates async test suites). VSCode launch configs in `.vscode/launch.json` also use these flags. If a C# change isn't picked up, do a clean rebuild (`rm -rf .godot/mono && dotnet build`) first.
- **Coverage**: `./coverage.sh` to generate coverage reports and badges
- **Spellcheck**: `cspell.json` configures the Code Spell Checker for VSCode
- **Linting**: `.editorconfig` and Roslyn analyzers enforce code style
- **Blender**: required for asset pipeline (model import, material setup, mesh export)
- **Web search when stuck**: if you are unsure about a Godot C# API signature, a physics behavior, a library's usage, or any detail that would otherwise be a guess, **stop and web search it** before implementing. Verify against official Godot docs or the relevant source rather than guessing at method names, enums, or parameter shapes. Never fabricate an API — confirm it first.

### Physics testing

- Physics systems must be tested in isolation (unit tests) and integration (scene tests)
- Use `godot-test-driver` for scene-based physics verification
- Test structural integrity under controlled load conditions
- Test traffic flow with deterministic vehicle spawning
- Test decay rates against expected weather patterns

---

## Project structure

```
splat/
├── src/
│   ├── Main.cs                 # Entry point (don't edit unless customizing bootstrap)
│   ├── Main.tscn               # Bootstrap scene (debug/test handoff)
│   ├── Game.cs                 # Primary game logic
│   ├── Game.tscn               # Primary game scene
│   │
│   ├── Core/                   # Core systems
│   │   ├── GameManager.cs      # Game state, time, speed controls
│   │   ├── CameraController.cs # Pan, zoom, rotation (Godot Camera3D)
│   │   └── InputManager.cs     # Input handling, tool selection
│   │
│   ├── Physics/                # Physics systems
│   │   ├── StructuralPhysics.cs    # Building integrity, collapse, foundation
│   │   ├── TrafficPhysics.cs       # Vehicle simulation, flow, collision
│   │   ├── InfrastructurePhysics.cs # Pipe, wire, road physical simulation
│   │   ├── EnvironmentalPhysics.cs  # Weather, erosion, moon phases
│   │   └── CitizenPhysics.cs       # Pedestrian flow, social proximity
│   │
│   ├── Buildings/              # Building system
│   │   ├── Building.cs         # Building node (StaticBody3D)
│   │   ├── BuildingData.cs     # Resource: material, foundation, integrity
│   │   ├── BuildingManager.cs  # Spawning, tracking, decay scheduling
│   │   └── BuildingTypes/      # Per-type building scripts
│   │       ├── Residential.cs
│   │       ├── Commercial.cs
│   │       ├── Industrial.cs
│   │       ├── Civic.cs
│   │       └── Infrastructure.cs
│   │
│   ├── Traffic/                # Traffic system
│   │   ├── Vehicle.cs          # Vehicle node (CharacterBody3D)
│   │   ├── VehicleData.cs      # Resource: mass, friction, acceleration
│   │   ├── TrafficManager.cs   # Spawning, routing, intersection negotiation
│   │   └── Road.cs             # Road surface with wear simulation
│   │
│   ├── Infrastructure/         # Utility systems
│   │   ├── Pipe.cs             # Water/sewage pipe node
│   │   ├── PowerLine.cs        # Power cable with catenary physics
│   │   ├── Road.cs             # Road surface mesh with wear
│   │   ├── InfrastructureManager.cs # Network simulation, cascade failures
│   │   └── FloodSystem.cs      # Water accumulation and drainage
│   │
│   ├── Environment/            # Weather and terrain
│   │   ├── WeatherSystem.cs    # Rain, wind, frost/thaw simulation
│   │   ├── TerrainDeformer.cs  # Erosion, settlement, frost heave
│   │   ├── MoonPhase.cs        # Lunar cycle and tidal forces
│   │   └── SeasonManager.cs    # Seasonal cycle, temperature, daylight
│   │
│   ├── Citizens/               # Citizen simulation
│   │   ├── Citizen.cs          # Citizen node (CharacterBody3D)
│   │   ├── CitizenData.cs      # Resource: needs, social links
│   │   ├── CitizenManager.cs   # Population tracking, migration
│   │   └── SocialPhysics.cs    # Proximity-based social interaction
│   │
│   ├── UI/                     # User interface
│   │   ├── HUD.cs              # In-game overlay (time, money, population)
│   │   ├── BuildMenu.cs        # Building/infrastructure placement UI
│   │   ├── OverlayToggle.cs    # Toggle utility overlays (pipes, power, etc.)
│   │   ├── InfoPanel.cs        # Building/citizen inspection
│   │   └── SettingsMenu.cs     # Audio, display, input settings
│   │
│   ├── Data/                   # Resources and configurations
│   │   ├── materials/          # MaterialType definitions (stone, timber, etc.)
│   │   ├── buildings/          # BuildingData presets
│   │   ├── vehicles/           # VehicleData presets
│   │   ├── terrain/            # Ground type definitions
│   │   └── weather/            # Weather pattern configurations
│   │
│   └── Utils/                  # Shared utilities
│       ├── PhysicsUtils.cs     # Physics helper functions
│       ├── MathUtils.cs        # Math helpers (lerp, clamp, etc.)
│       └── FileUtils.cs        # Save/load utilities
│
├── test/                       # Test code (excluded from release builds)
│   └── src/
│       ├── Physics/
│       │   ├── StructuralPhysicsTest.cs
│       │   ├── TrafficPhysicsTest.cs
│       │   └── EnvironmentalPhysicsTest.cs
│       ├── Buildings/
│       │   └── BuildingTest.cs
│       └── Utils/
│           └── PhysicsUtilsTest.cs
│
├── addons/                     # Godot plugins
├── docs/                       # Documentation and images
└── [template files]            # From Chickensoft GodotGame template
```

---

## Asset packs

All assets are free/open-source (CC0 or free commercial use):

| Asset | Source | License | Contents |
|-------|--------|---------|----------|
| [KayKit City Builder Bits](https://kaylousberg.itch.io/kaykit-city-builder-bits) | itch.io | CC0 | 32+ city models (buildings, roads, props) |
| [KayKit Forest Nature Pack](https://kaylousberg.itch.io/kaykit-forest) | itch.io | CC0 | Trees, rocks, grass, nature assets |
| [Free Low Poly Vehicles Pack](https://rgsdev.itch.io/free-low-poly-vehicles-pack) | itch.io | CC0 | 18 vehicles (cars, trucks, bus, ambulance) |
| [Low Poly Nature Pack](https://flo-bit.itch.io/low-poly-nature-pack) | itch.io | CC0 | Pine trees, stones, bushes, clouds, mushrooms |

**Importing:**
- KayKit packs include Godot addon versions — drop into `addons/`
- Other packs: import FBX/GLTF/OBJ files via Godot's import system
- Color palettes may need adjustment to match Splat's Scottish Highlands scheme

### Plugins

| Plugin | Source | License | Purpose |
|--------|--------|---------|---------|
| [MCP4Godot](https://github.com/Smalldy/mcp4godot) | GitHub | MIT | Native MCP server for AI-assisted development |

---

## Godot specifics

- **Engine version**: Godot 4.7 (C# / Mono build required)
- **Renderer**: Mobile (GL Compatibility for broad hardware support)
- **Physics engine**: Godot Physics3D (default). Consider Jolt for performance if needed.
- **Viewport**: 720x720 base, 1280x720 window (scalable)
- **Scene naming**: PascalCase (e.g., `Game.tscn`, `Building.tscn`, `Vehicle.tscn`)
- **Node access**: use `%NodeName` for unique node references in scene tree
- **3D coordinate system**: Y-up. Buildings sit on XZ plane. Gravity is -Y.

### Physics layers

| Layer | Purpose |
|-------|---------|
| 1 | Buildings (static/character bodies) |
| 2 | Vehicles (character bodies) |
| 3 | Citizens (character bodies, small) |
| 4 | Infrastructure (pipes, wires — raycasts) |
| 5 | Terrain (static body, ground interaction) |
| 6 | Debris (rigid bodies from collapses) |
| 7 | Water (fluid simulation or area triggers) |

### Input handling

Controller is primary. Keyboard/mouse is secondary.

**Controller mapping:**
- Left stick: camera pan
- Right stick: camera rotation
- Triggers: zoom in/out
- A: confirm/place/select
- B: cancel/back
- X: demolish
- Y: open build menu
- D-pad: navigate menus, cycle tools
- Bumpers: cycle through building categories

**Keyboard/mouse:**
- WASD/arrow keys: camera pan
- Mouse: cursor-based placement, hover tooltips
- Scroll wheel: zoom
- Left click: confirm/place/select
- Right click: cancel/back
- Middle click: camera rotation
- Tab: open build menu
- Delete: demolish

**Implementation:**
- Use Godot's `InputMap` system for action definitions
- Create `InputManager.cs` to abstract input device detection
- All UI must be navigable via controller (focus management)
- Tooltips show both controller and keyboard shortcuts
- Godot's `@export` handles device-agnostic input actions

### Custom resources

All game data lives in custom Godot resources (`.tres` files):
- `BuildingData` — material, foundation, structural properties
- `VehicleData` — mass, friction, acceleration, braking
- `CitizenData` — needs, social links, movement speed
- `GroundType` — density, friction, drainage, frost susceptibility
- `WeatherPattern` — temperature, precipitation, wind, moon phase

### Data design for AT Protocol

All game data is designed to be syncable via AT Protocol. No sensitive data exists; cities are public artifacts. Sync is optional and late-stage — core game works fully offline.

**NSID namespace:** `click.croft.splat.*`

| NSID | Description | Storage |
|------|-------------|---------|
| `click.croft.splat.city` | City snapshot record — metadata, timestamps, population stats | Record fields |
| `click.croft.splat.cityBlob` | Full city data blob — terrain, building positions, infrastructure network, complete game state | Blob (up to 5MB) |
| `click.croft.splat.building` | Individual building record — type, material, integrity, position, history | Record fields |
| `click.croft.splat.buildingBlob` | Detailed building data — mesh state, decay layers, physics history | Blob (small) |
| `click.croft.splat.event` | Event log record — collapse, repair, weather event, traffic incident | Record fields |
| `click.croft.splat.citizen` | Citizen profile — anonymized movement patterns, social connections | Record fields |
| `click.croft.splat.citizenBlob` | Detailed citizen data — path history, social graph | Blob (small) |

**Blob storage approach:**
- Raw game data stored as blobs due to size constraints (city snapshots can exceed record field limits)
- Blobs referenced by CID, uploaded via `com.atproto.repo.uploadBlob`
- Max blob size: 5MB per blob (split large data across multiple blobs if needed)
- Record fields contain metadata; blob fields contain raw game state
- CID-based content addressing ensures deduplication and integrity

**Design principles:**
- All data includes `createdAt` and `updatedAt` timestamps
- No personally identifiable information (PII) — citizen data is synthetic
- City data is structured for public sharing, not private state
- Game works fully offline; sync is optional

---

## Current state

The project is freshly scaffolded from the Chickensoft GodotGame template. The `Game.cs` script contains a minimal button-press counter example. The infrastructure is ready for development:

- [x] Template setup with C# project structure
- [x] Testing framework (GoDotTest) configured
- [x] CI/CD workflows (GitHub Actions)
- [ ] Core game loop (camera, time, placement)
- [ ] Building system (placement, structural physics)
- [ ] Traffic system (vehicle physics, road interaction)
- [ ] Infrastructure systems (pipes, power, roads)
- [ ] Environmental systems (weather, erosion, moon)
- [ ] Citizen simulation (needs, movement, social)
- [ ] UI framework (HUD, build menu, overlays)
- [ ] Decay and preservation mechanics
- [ ] Save/load system
- [ ] Polish (particles, audio, visual effects)

---

## Roadmap

### Phase 1: Core mechanics (MVP)
- [ ] Camera controller (pan, zoom, rotate)
- [ ] Time system (pause, speed controls)
- [ ] Basic building placement (drag-and-drop, ghost preview)
- [ ] Structural physics (gravity, foundation, integrity)
- [ ] Simple terrain (flat ground, basic ground types)
- [ ] UI framework (HUD, build menu)

### Phase 2: Traffic and infrastructure
- [ ] Road placement and wear
- [ ] Vehicle physics (spawning, movement, collision)
- [ ] Intersection negotiation
- [ ] Basic pipe network (water supply, sewage)
- [ ] Power line network (catenary physics)

### Phase 3: Environment and decay
- [ ] Weather system (rain, wind, frost)
- [ ] Terrain erosion and settlement
- [ ] Moon phases and tidal forces
- [ ] Decay mechanics (structural, surface, infrastructure)
- [ ] Preservation mechanics (maintenance, repair)

### Phase 4: Citizens and simulation
- [ ] Citizen agents (needs, movement, social)
- [ ] Zone demand (residential, commercial, industrial)
- [ ] Emergent social dynamics
- [ ] Population migration

### Phase 5: Polish and content
- [ ] Building variety (Scottish architecture)
- [ ] Visual effects (particles, debris, weather)
- [ ] Audio (ambient, construction, weather)
- [ ] Save/load system
- [ ] Tutorial/onboarding
- [ ] Performance optimization

### Phase 6: AT Protocol integration (Rust)

AT Protocol sync is implemented in **Rust** via GDExtension (`gdext`), keeping C# focused on game logic.

**Rust dependencies:**
- `godot` crate (`godot-rust/gdext`) — GDExtension bindings for Godot 4
- `atrium` crate (`atrium-rs/atrium`) — AT Protocol client (XRPC, repo operations, identity)
- Alternative: `rsky` (`blacksky-algorithms/rsky`) — full AT Protocol support

**Rust GDExtension responsibilities:**
- Serialize game state to DAG-CBOR blobs
- Upload blobs via `com.atproto.repo.uploadBlob`
- Create/update records via `com.atproto.repo.createRecord` / `putRecord`
- Handle identity resolution and PDS authentication
- Manage blob lifecycle (referenced by CID, garbage collected when unreferenced)

**C# → Rust bridge:**
- C# game systems serialize state to JSON/binary
- Rust GDExtension receives serialized data, encodes to DAG-CBOR, uploads to PDS
- Signals or method calls bridge game events to sync triggers

- [ ] Set up Rust GDExtension crate (`splat-sync/`)
- [ ] Implement blob serialization (city snapshots, building records)
- [ ] Implement XRPC client with session management
- [ ] C# → Rust bridge (signals, method calls)
- [ ] City snapshot export (JSON → DAG-CBOR blob → AT Protocol record)
- [ ] Building record publication (individual building states)
- [ ] Event log sync (collapses, repairs, weather events)
- [ ] Citizen profile publishing (anonymized, synthetic data)
- [ ] Timeline view (city history as AT Protocol feed)
- [ ] Social features (visit other cities, compare decay patterns)
- [ ] PDS integration (self-hosted city persistence)

---

## Resources and references

- [Godot Physics documentation](https://docs.godotengine.org/en/stable/tutorials/physics/index.html)
- [Godot 3D physics tutorial](https://docs.godotengine.org/en/stable/tutorials/physics/physics_introduction.html)
- [Cities: Skylines modding docs](https://cs1.paradoxwikis.com/Modding:Index) — reference for city builder systems
- [Scottish building materials](https://www.historicenvironment.scot/advice-and-support/building-materials) — physical properties reference
- [Celtic knotwork geometry](https://en.wikipedia.org/wiki/Celtic_knot) — pattern generation reference
- [AT Protocol specification](https://atproto.com/) — data sync and social features reference
