From cd0c08dc7ce754473178ad3f32f7740a1dddc1eb Mon Sep 17 00:00:00 2001 From: Vaino Kauppila Date: Thu, 2 Jul 2026 22:58:25 +0300 Subject: Initial import: LibreForts (M0-M5 in progress) Open-source Forts clone: custom C++20 engine + data-driven (Lua) 2D physics artillery RTS. - Building: node/strut graph on a stiff mass-spring solver (canon Forts model), triangulation rigidity, axial + 30-degree angle-stress breaking, cascading collapse, fire (DoT + spread), ground destroys debris. - Weapons (M4): cannon (ballistic) + laser (beam/ignite) with select-and-aim-in- arc UX; splash / beam damage; bg-brace passthrough. - Devices + economy (M5): reactors + win/loss + restart, mines/turbines/battery, metal deposits, storage caps, per-shot energy cost. - Data-driven via Lua/sol2 with a layered mod loader; enemy-fort scenario mod. - Renderer: SDL3 + textures + ImGui dev UI. stb_image + ImGui vendored. - Assets: CC0 placeholders only; real game art loaded at runtime from the user's own install via forts: paths (bring-your-own; nothing copyrighted committed). See README.md / CLAUDE.md and research/ + requirements/ for detail. --- requirements/milestones.org | 186 ++++++++++++++++++++++++ requirements/v0.1-core.org | 338 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 524 insertions(+) create mode 100644 requirements/milestones.org create mode 100644 requirements/v0.1-core.org (limited to 'requirements') diff --git a/requirements/milestones.org b/requirements/milestones.org new file mode 100644 index 0000000..9aa5a5a --- /dev/null +++ b/requirements/milestones.org @@ -0,0 +1,186 @@ +#+TITLE: Forts Clone v0.1 -- Milestones +#+AUTHOR: Forts Clone Project +#+DATE: 2025-06-19 +#+OPTIONS: toc:3 num:t + +* Overview + +v0.1 is split into 7 milestones. Each milestone delivers something you can +run and test. Milestones are sequential -- each builds on the previous. + +* M0: Scaffolding & Build Environment [DONE] +SCHEDULED: <2025-06-19> +CLOSED: <2025-06-19> + +Goal: Container builds, SDL3 window opens, clears to a color. + +- [X] Containerfile with all dependencies pre-built +- [X] meson.build at project root, compiles and links SDL3 + Box2D + all deps +- [X] =src/main.cpp= -- SDL3 creates a window, clears to dark blue-gray +- [X] Camera: 2D orthographic, pan (arrows/middle-drag), zoom (scroll) +- [X] Input system: polling keyboard/mouse state +- [X] Podman build + run workflow + +Notes: +- Pivoted from bgfx to SDL3 renderer for M0. bgfx init fails silently on this + system (EGL-only Linux backend, GLX removed upstream). SDL3 OpenGL renderer + works perfectly. Revisit bgfx later in the project. +- Header collision: -I/usr/local/include/bx caused sys/types.h to find + bx/endian.h instead of glibc endian.h. Fixed by using single + -I/usr/local/include with qualified includes. + +* M1: Rendering & Physics Foundations [DONE] +SCHEDULED: <2025-06-19> +CLOSED: <2025-06-19> + +Goal: See physics bodies rendered as colored rectangles against terrain. + +- [X] Box2D v3 integration -- world, gravity, fixed timestep at 60Hz +- [X] Static terrain body (ground plane + platform) +- [X] Dynamic bodies falling and landing (proof of physics->render) +- [X] SDL3 sprite rendering (colored quads, world-to-screen transform) +- [X] Fixed-timestep accumulator pattern (physics at 60Hz, render at display rate) +- [X] Camera pan/zoom with proper defaults (zoom 10, centered on action) + +Notes: +- Box2D v3.0.0 has broken CMake (FetchContent pulls GLFW unconditionally). + Built from v3.1.1 directly (gcc -c src/*.c + ar rcs). +- b2ShapeDef.friction moved to b2ShapeDef.material.friction in v3. +- b2Rot is { float c, s; } (cos/sin), angle via std::atan2(rot.s, rot.c). + +* ARCHITECTURE NOTE: Building physics is a mass-spring system (the canon Forts model) + +The locked stack specified Box2D (weld/distance joints, b2DestructionListener) +for the building structure. Instead the building system is a custom *stiff +damped mass-spring solver* (=src/game/build_graph.*=) — the same model the +shipped game uses (see =research/forts-data-reference.org=). It maps directly +onto Forts' node/edge graph and onto its data. + +- Node = point mass with velocity; foundation nodes are pinned at the ground. +- Strut = a damped Hookean spring (F = k.dx + c.v), per-material stiffness. + Integrated semi-implicit with OVERSAMPLES (14) substeps for stiff-spring + stability (Forts uses the same oversampling). +- Rigidity is GEOMETRIC (triangulation); a lone strut is a free-hinging pin + joint. It SNAPS on (a) axial deformation past per-material MaxCompression/ + MaxExpansion, or (b) the 30-degree angle-stress rule for un-triangulated + struts — both taken from the shipped game's constants. +- Box2D is retained (=src/engine/physics.*=) but idle; foundation for M4 + projectiles / terrain collision. + +Consequence: multiplayer determinism now rests on our own solver, not Box2D's +cross-platform guarantees (revisit before netcode work). + +* LUA / MODDING: materials are now data-driven (sol2) [DONE for materials] + +Lua (sol2 3.5) is up. Materials are no longer hard-coded — they load at startup +from =data/materials.lua= via =load_materials()= (=src/game/data.*=), into a +runtime =BuildGraph::materials= vector. The layered loader works: + +1. =ScriptEngine= (=src/engine/script.*=) wraps a sol2 state, runs files with + errors caught (a bad mod can't crash the game). +2. Base =data/materials.lua= defines the global =Materials= array + helpers + (=FindMaterial=, =IndexOfMaterial=). +3. Every mod under =data/mods//= with a =materials.lua= is applied on top + in (Priority, name) order; mods mutate the shared =Materials= table. + (=data/mods/example-recolour-wood/= ships as a live demo.) + +Runtime data path is relative to CWD (run from the repo root). NEXT for Lua: +extend the same loader to weapons/devices/projectiles tables (lands with M4), +and a mod-selection step instead of "apply everything in data/mods/". + +* M2: Building System [MOSTLY DONE] + +Goal: Click to place struts on the map. They have physics, connect into a +graph, and form structures. + +- [X] Build mode: number keys 1-3 select material (wood / bg-brace / rope) +- [X] Strut placed as a mass-spring node/edge + colored quad, stress-tinted + (red under compression, blue under tension) +- [X] Anchored building only: a drag must START from an existing node or the + ground (foundation) — no growing structure out of thin air +- [X] Click-drag single strut; endpoints snap onto existing nodes +- [X] Drag-build (extrude): sweep an edge into a box with node-merging and an + auto diagonal brace; free (non-perpendicular) drag angle +- [X] Build-grace radial timer on un-triangulated struts (temporary rigid hold) +- [X] Building costs: placing a piece deducts metal + energy +- [X] Simple HUD: resource bars + current-material indicator +- [ ] Resource system: Metal (mines on deposits) + Energy (wind turbines) + -- DEFERRED to M5 (needs the reactor / game-loop context). For now metal + and energy are fixed starting pools that only deplete. + +* M3: Structural Destruction [MOSTLY DONE] + (swapped with weapons -- destruction goes hand-in-hand with M2 building) + +Goal: Overloaded structures snap and collapse; debris that falls is destroyed. +This is the purely-structural half of Forts destruction (no weapons yet). + +- [X] Axial failure: deformation past per-material MaxCompression/MaxExpansion + (wood +/-10%, asymmetric per material) — canon, read straight off the + spring length (not a reconstructed force) +- [X] Angle-stress failure: an un-triangulated strut snaps once it rotates past + ~30 deg from its built angle (Forts' rule; replaces the old dangle timer) +- [X] Cascading collapse: a snapped support redistributes load and overloads + neighbours, which snap in turn (emergent, not a scripted event) +- [X] Ground destroys falling debris: any non-foundation node that sinks below + the ground surface is removed (+ explosion puff), taking its edges with it +- [X] Disconnection -> fall -> destroy: a chunk that loses its path to a + foundation simply falls under gravity and dies on the ground +- [X] Materials: wood, background bracing, ropes (tension-only) +- [ ] Per-strut HP pool (separate from stress) -- belongs with M4 weapon damage +- [ ] Fire (damage-over-time, strut-to-strut spread) -- M4 + +* M4: Weapons & Damage + (swapped with destruction) + +Goal: Place and fire all three weapons. They feed the M3 graph via two damage +models (per-strut HP and radius splash) plus fire. + +- [ ] Per-strut HP pool, depleted by weapon hits (independent of stress) +- [ ] Cannon: click-drag angle/power, Box2D ballistic projectile, splash + damage with linear radius falloff, knockback impulse, ~25% fire chance +- [ ] Laser: click-drag beam; stops at wood, passes bg-brace/ropes; 100% ignite +- [ ] Flak: auto-target incoming shells within an arc; hitscan/fast projectile +- [ ] Direct vs splash delivery: foreground struts block direct fire; + background bracing is passed through by direct hits but takes splash + fire +- [ ] Fire system: ignition flag, damage-over-time, spread along the graph, + burns background bracing faster (the counter to the bg-brace trick) + +* M5: Reactor, Resources & Game Loop + +Goal: There's a reactor to destroy, and a real economy to build it with. + +- [ ] Reactor entity -- large block, HP bar +- [ ] Player reactor on left, dummy reactor on right +- [ ] Reactor takes damage from direct hits, fire, falling/collision +- [ ] Win condition: destroy reactor HP OR disconnect it from its foundation + (collapse) -- two distinct victory paths +- [ ] Resource system (deferred from M2): mines on metal deposits, wind + turbines for energy, generation rates, "can't build when broke" +- [ ] Win/lose condition + restart (R key) + +* M6: Dummy Fort & Map + +Goal: The dummy fort on the right is a hand-crafted target. The map has metal +deposits and a complete layout. + +- [ ] Dummy fort pre-built structure (reactor, wood walls, bg-brace, ropes) +- [ ] Map layout: terrain with metal deposits on both sides +- [ ] Player starting area: reactor + small starter shell + nearby deposits +- [ ] Visual polish: distinct colors for materials, simple sky backdrop + +* M7: Polish & Controls + +Goal: Everything feels good. Controls are responsive. Visuals are clear. + +- [ ] Repair tool: right-click damaged piece, pay resources to restore HP +- [ ] Recycle: shift+click to remove piece, recover partial resources +- [X] Camera feel: pan (arrows / middle-drag), scroll zoom (basic; edge-scroll TBD) +- [ ] Visual feedback: damage states, fire glow +- [X] Build UX: ghost/extrusion previews, hover highlights, build-grace timers +- [ ] Edge cases: zero resources enforcement, etc. + +* Dependency Graph + +#+begin_src text +M0 -- M1 -- M2 -- M3 -- M4 -- M5 -- M6 -- M7 +#+end_src diff --git a/requirements/v0.1-core.org b/requirements/v0.1-core.org new file mode 100644 index 0000000..ce3d99c --- /dev/null +++ b/requirements/v0.1-core.org @@ -0,0 +1,338 @@ +#+TITLE: Forts Clone v0.1 — Core Requirements +#+AUTHOR: Forts Clone Project +#+DATE: 2025-06-19 +#+OPTIONS: toc:3 num:t + +* Purpose + +v0.1 exists to prove the core loop: build a fort, place weapons, and destroy +an enemy reactor through physics-based structural damage. No multiplayer. +No AI. No commanders. Just the fundamental building↔physics↔destruction +feedback loop working end-to-end. + +* Resources + +Two resources only. No tech tree — everything is available from the start. + +** Metal +- Gathered via Mines placed on metal deposits in the terrain +- Deposits are fixed nodes on the map — a mine on a deposit produces metal at + a constant rate +- Metal is consumed when placing building pieces and weapons +- If you run out of metal, you cannot build + +** Energy +- Generated by Wind Turbines placed on your fort +- Turbine output scales with: + - Height above terrain (higher = more energy) + - Lack of obstruction around the turbine (clear air = more energy) +- Energy is consumed when placing building pieces and weapons +- If you run out of energy, you cannot build + +* Building Materials + +** Wood (Normal Bracing) +- Primary structural building material +- Opaque: projectiles CANNOT pass through it +- Guns cannot shoot through wood bracing — it blocks line of fire for both + the player and hypothetically for enemies +- Has HP — takes damage from cannon shells, lasers, and fire +- Flammable: can be set on fire by laser or cannon (chance-based) +- When HP reaches zero, the piece is destroyed +- When a load-bearing piece is destroyed, connected pieces may collapse + (Box2D joint destruction → cascade) +- Costs: metal + energy (exact values TBD during implementation) +- Appears as a solid plank/beam visually + +** Background Bracing +- Structural building material — provides support just like wood +- Translucent/façade: structures behind it are visually hidden from the + opponent (in v0.1, this is mostly cosmetic since there is no opponent) +- Projectiles pass THROUGH background bracing — it does NOT block shots +- Guns CAN shoot through background bracing (it doesn't block line of fire) +- Has HP — takes damage from cannon shells and lasers +- Flammable: fire-spreading weapons (laser, cannon) set fire to it +- When HP reaches zero, the piece is destroyed +- When destroyed, any structures it was hiding become visible +- Costs: metal + energy (likely cheaper than wood since it doesn't block + projectiles — TBD) +- Appears as a visually distinct, lighter/more transparent plank + +** Ropes +- Tension element connecting two points +- Provides structural stability — keeps structures from tipping over +- Does NOT block projectiles (they pass through ropes) +- Has HP (low compared to wood) +- Vulnerable to: fire (can burn through), cannon splash damage +- If a rope is destroyed, the structure it was stabilizing may collapse + (tension is released → connected bodies may fall) +- Implemented via Box2D =b2DistanceJoint= +- Costs: metal + energy (cheap per segment — ropes are primarily for + structural engineering, not defense) +- Appears as a thin line/cable visually + +** Material Property Summary + +| Property | Wood Bracing | Background Bracing | Ropes | +|-----------------------+--------------+-------------------+-------------| +| Blocks projectiles | ✅ Yes | ❌ No | ❌ No | +| Blocks line of fire | ✅ Yes | ❌ No | ❌ No | +| Provides structure | ✅ Yes | ✅ Yes | ✅ Tension | +| Flammable | ✅ Yes | ✅ Yes | ✅ Yes | +| HP (relative) | High | Medium | Low | +| Hides structures | ❌ No | ✅ Yes | ❌ No | + +* Weapons + +** Cannon (Artillery) +- Type: arcing projectile (affected by gravity) +- Aiming: player sets angle and power, fires on click +- Projectile: cannon shell with ballistic trajectory + - Travels in an arc (Box2D body under gravity) + - On impact: deals damage in a small splash radius + - Knockback: applies force to bodies near impact point + - Structural damage: can break joints near impact +- Chance to set fire: ~20-30% chance on impact to ignite the struck piece + (fire then spreads to connected flammable materials) +- Firing rate: slow (e.g., 1 round per 2-3 seconds) +- Good against: structures, wooden walls +- Counter: Flak gun can shoot down cannon shells in flight +- Costs: metal + energy to build the cannon device on your fort + +** Flak Gun +- Type: point-defense, hitscan or very fast projectile +- Aiming: automatic or manual? (TBD — auto-targeting incoming projectiles in + a cone/radius, or player aims at incoming shells) +- Purpose: shoots down incoming cannon shells before they impact +- Cannot damage buildings (or does very little building damage) +- Firing rate: moderate/high (needs to be able to intercept cannon shells) +- Placement matters: must have line of sight to incoming projectiles + (cannot shoot through wood bracing, CAN shoot through background bracing + and ropes) +- Costs: metal + energy to build + +** Laser +- Type: Line-of-Sight beam weapon +- Aiming: player draws a line from the laser turret to target point +- The beam traces through: + - Empty space: passes freely + - Background bracing: passes through (doesn't block) + - Ropes: passes through + - Wood bracing: blocked — beam stops at first wood piece hit +- Damage: low continuous damage to whatever piece it hits (or low damage + per tick while beam is active) +- Fire starter: 100% chance to set the struck piece on fire (if flammable) + — this is the laser's primary purpose +- Beam duration: fires for a short burst (e.g., 0.5-1 second) then goes on + cooldown +- Cannot penetrate normal wood — the beam stops at the first wood surface +- Good against: starting fires in enemy structures, burning through ropes + and background bracing, igniting key support pieces +- Costs: metal + energy to build + +** Weapon Summary + +| Weapon | Damage | Fire? | Blocks Projectiles? | Penetrates Bg. Bracing? | +|----------+--------+-------+---------------------+--------------------------| +| Cannon | High | ~25% | Flak can intercept | Yes (arcing shot) | +| Flak Gun | Low | No | N/A (defensive) | Yes (hitscan within arc) | +| Laser | Low | 100% | N/A (stops at wood) | Yes (beam passes through)| + +* Reactor + +- The win/loss condition for both the player and the dummy fort +- A large, relatively fragile device placed at the core of each fort +- Has HP — when HP reaches zero, that side loses +- Can be damaged by: + - Direct cannon shell hits + - Fire reaching the reactor (spread from burning connected pieces) + - Falling/collision damage if the reactor's supports are destroyed and + it falls +- Player's reactor starts at a fixed position on the left side of the map +- Dummy reactor starts at a fixed position on the right side of the map +- Visually distinct — glows, pulses, or is marked clearly +- Costs: free (starts pre-placed on the map) + +* Fire System + +- Fire starts when: + - Laser hits a flammable piece (100% ignition chance) + - Cannon shell impacts a flammable piece (~20-30% ignition chance) +- Once ignited, a piece burns: + - Takes damage over time (HP decreases per tick) + - Fire spreads to adjacent connected flammable pieces (via Box2D joint + graph — check neighboring bodies) + - Burning pieces produce visual fire particles and smoke + - Ropes burn faster than wood (lower HP, fire kills them quickly) +- Fire does NOT spread through empty space — only along joint connections + between flammable bodies +- A piece destroyed by fire releases its joints, potentially causing + structural collapse +- Fire can reach and damage the reactor if connected through flammable + structure +- Extinguish? Not in v0.1 — once something is burning, it burns until + destroyed. (Future: repair tool extinguishes fire.) + +* Physics + +- Box2D v3 simulation at fixed timestep (60Hz) +- Every building piece (wood, background bracing) is a =b2Body= (dynamic) +- Terrain/map geometry is =b2Body= (static) +- Joints: + - Weld joints connect adjacent building pieces (rigid attachment) + - Distance joints represent ropes (maintain fixed distance between two + anchor points) +- Gravity: standard downward gravity (~9.8 m/s² in world units) +- Projectiles: dynamic =b2Body= with initial velocity, affected by gravity +- Impact forces: cannon shells apply =b2Body::ApplyLinearImpulse= to nearby + bodies on detonation +- Joint breaking: when a body is destroyed (HP reaches zero), its attached + joints are destroyed → connected bodies may fall +- =b2DestructionListener= triggers game-side logic (spawn debris particles, + mark connected bodies for stability check, fire spread check) +- Structural collapse emerges naturally from the physics — if enough + supports are destroyed, structures fall + +* Map + +** Layout +- 2D side-view +- Fixed-size playfield (e.g., 200m wide × 100m tall in world units) +- Left side: player's starting area + - Player reactor pre-placed at a fixed position + - Small starter structure around the reactor (a few wood planks forming + a basic shell) + - 2-3 metal deposits near the player's side +- Right side: dummy enemy fort + - Dummy reactor pre-placed at a fixed position + - Pre-built fort structure around the reactor (wood bracing walls, some + background bracing panels hiding the reactor, a few rope supports) + - Intended as a target to shoot at — the dummy has enough structure to + demonstrate the physics/destruction/fire systems + - 2-3 metal deposits near the enemy side +- Terrain: simple ground plane with some unevenness/hills +- Metal deposits: visible ore nodes embedded in terrain + +** Visual Style +- Simple, functional — colored rectangles/sprites for building pieces +- Distinct colors for: wood (brown), background bracing (lighter brown/ + beige, semi-transparent), ropes (dark line), metal deposits (gray/silver), + reactor (glowing red/orange) +- Sky/gradient background (simple) +- This is v0.1 — programmer art is fine. Aesthetics can wait. + +* Game Mode: Target Practice (v0.1) + +** Setup +- Single player on the left side +- Dummy fort on the right side (pre-built, no AI, no player controlling it) +- The dummy does NOT: build, shoot back, repair, or take any action +- The dummy fort is a static structure — it just sits there + +** Player Actions +- Build: place wood, background bracing, and ropes on your fort + - Drag to place beams/planks (TBD: exact building UX) + - Click points to connect ropes +- Place weapons: build cannon, flak gun, and laser on your fort + - Weapons are placed like building pieces but have an aim direction +- Aim & Fire: + - Cannon: click and drag to set angle/power, release to fire + - Laser: click and drag to draw beam path, fires along line + - Flak gun: active passively? Or player aims at incoming shells? + (TBD — simplest v0.1 approach: flak automatically shoots at cannon + shells within its arc/range) +- Manage resources: build mines on deposits, build wind turbines for energy +- Repair: damaged structures can be repaired for a resource cost + (TBD: repair tool or automatic?) + +** Win Condition +- Destroy the dummy reactor + - Reduce its HP to zero via direct hits, fire, or structural collapse + +** Lose Condition +- Your own reactor is destroyed + - In v0.1 with no enemy AI, this can only happen if you damage your own + reactor (unlikely) or your fort collapses onto it (possible if built + poorly) + +** No Win/Lose Condition (Stretch) +- The game simply continues — there's no victory screen yet. When a reactor + dies, it explodes/dissolves visually. Press R to restart. + +* Camera & Controls + +** Camera +- 2D orthographic projection via bgfx +- Camera pans with mouse (drag middle-mouse or scroll to edge) +- Zoom with scroll wheel (zoom in/out to see details or full battlefield) +- Default view: centered on the map, showing both forts + +** Controls (Mouse + Keyboard) +| Action | Input | +|-------------------+------------------------------| +| Pan camera | Middle-mouse drag or arrow keys | +| Zoom | Scroll wheel | +| Select build mode | Number keys (1=wood, 2=bg.brace, 3=rope, 4=cannon, 5=flak, 6=laser) | +| Place piece | Click (in build mode) | +| Cancel build | Right-click or Escape | +| Aim weapon | Click (in weapon mode) | +| Fire weapon | Release after aim, or click | +| Repair | Right-click on damaged piece | +| Recycle/delete | Shift+click on piece | +| Restart | R key | + +* What is Explicitly OUT of Scope for v0.1 + +- Multiplayer (no networking needed) +- AI opponents (dummy fort is entirely passive) +- Commanders +- Tech tree +- Damage types beyond fire + kinetic (no EMP, no shields) +- Particle effects beyond basic fire/smoke +- Sound (can be added but not required — focus on gameplay) +- UI beyond basic resource counters and build mode indicators +- Save/load +- Replays +- Mod loading (Lua infrastructure can be in engine but no mods to load yet) +- Menu system (just drop into the game on launch) +- Win/loss screens (reactor explodes, press R to restart) + +* Development Priorities (Build Order) + +1. Windowing + rendering (SDL3 + bgfx — get a triangle on screen) +2. 2D sprite batcher on bgfx (colored quads for building pieces) +3. Box2D world + basic bodies (static terrain, dynamic plank) +4. Build mode: click to place a plank (creates Box2D body + renders sprite) +5. Resource system (mines, turbines, metal/energy counters) +6. Multiple connected pieces (weld joints, structural integrity) +7. Ropes (distance joints, tension visualization) +8. Cannon + projectile physics (spawn shell, ballistic arc, impact) +9. Flak gun (shoot down cannon shells) +10. Laser (line trace, fire ignition) +11. Fire system (HP-over-time, spread along joints, visual feedback) +12. Reactor + win/loss check +13. Dummy fort (pre-built target structure on the right side) +14. Camera (pan, zoom) +15. Repair + recycle +16. Polish pass (visual clarity, controls feel, edge cases) + +* Open Design Questions (Resolve During Implementation) + +- [ ] Building UX: drag-to-place beams? Click start + end points? Grid snap + or freeform? +- [ ] Cannon aiming: click on your cannon + click target point? Or angle/ + power slider? +- [ ] Flak gun behavior: fully automatic within an arc? Or player manually + targets incoming shells? +- [ ] Laser duration: continuous beam while holding click? Or fixed-duration + burst? +- [ ] Resource rates: how much metal per mine per second? How much energy per + turbine? (Tune during playtesting) +- [ ] Piece HP values: how many cannon hits to destroy wood? Background + bracing? Ropes? +- [ ] Building piece sizes: fixed sizes (1m, 2m, 4m beams)? Or freeform drag? +- [ ] Does fire spread upward preferentially? (Heat rises — fire climbing up + a structure is more dangerous than fire going down) +- [ ] Can you build pieces that intersect? Or is placement blocked by existing + bodies? +- [ ] Repair cost: proportional to missing HP? Flat cost? -- cgit v1.3