diff options
| -rw-r--r-- | CLAUDE.md | 36 | ||||
| -rw-r--r-- | requirements/milestones.org | 79 | ||||
| -rw-r--r-- | research/gameplay-gaps.org | 88 |
3 files changed, 145 insertions, 58 deletions
@@ -153,12 +153,17 @@ See `requirements/milestones.org` for the live checklist. Roughly: - **M0–M3 done:** scaffolding, rendering/physics, building system, structural destruction (stress/collapse/fire). -- **M4 in progress:** cannon (ballistic) + laser (beam/fire) with the Forts - select-a-weapon-and-aim-in-its-arc UX. Missing: mortar, flak/point-defence, - machinegun/sniper (hitscan), guided missiles, EMP, per-shot recoil. -- **M5 in progress:** reactors + win/loss + restart (R), real resource economy +- **M4 mostly done:** per-strut HP, cannon (ballistic) + laser (beam/fire) with + the Forts select-a-weapon-and-aim-in-its-arc UX, direct-vs-splash delivery, + fire + spread. Missing: mortar, flak/point-defence, machinegun/sniper + (hitscan), guided missiles, EMP, per-shot recoil, metal-per-shot. +- **M5 mostly done:** reactors + win/loss + restart (R), real resource economy (mines on deposits, turbines by height, storage caps, firing costs energy), - device framework + placement. + device framework + placement. Two gaps: fire does **not** damage devices, and + devices are not mounted on the strut graph, so the "cut its supports and the + reactor falls" victory path does not exist. +- **M6 partial:** enemy fort (`data/mods/enemy-fort/`) + deposits both sides; + terrain is still a flat half-plane and there is no sky backdrop. - **Not started / later:** repair & recycle (M7), armour/door/shield materials, tech tree + upgrades, commanders, real map/terrain, AI, netcode. @@ -177,6 +182,27 @@ consult it before deciding what to build; don't guess from vibes. - **Build before you claim done** (compile in the container) and validate any Lua you touched with a standalone `lua` run. Be honest about what you couldn't verify (the GUI can't run headless here). +- **Keep the status docs in sync — same commit as the change.** When you land, + extend or remove a feature, update all three in the commit that changes the + behaviour, not later: + 1. `requirements/milestones.org` — tick the boxes you actually delivered, and + fix any item whose *description* no longer matches what was built. + 2. `research/gameplay-gaps.org` — the "What we HAVE" baseline, the affected + `**` section, the roadmap table, and the "smallest next steps" queue. + 3. `CLAUDE.md` §6 — the milestone summary, plus §2/§3/§4 if the architecture, + the physics model or the data schema moved. + + Rules that make this worth doing: + - **Verify against the code, not memory.** Grep for the thing before ticking + it. These docs drove a real prioritisation error once: every M4/M5 box sat + unchecked and the gaps doc still claimed "we have ZERO devices" long after + reactors, mines, turbines, the economy and win/loss had shipped. + - **Record the gap, not just the win.** Half-done is `[~]` plus a one-line + note on exactly what is missing (e.g. M5's reactor exists, but nothing + mounts it on the strut graph, so there is no collapse-victory path). A + `[X]` that hides a caveat is worse than an unticked box. + - §6 tells everyone to consult `gameplay-gaps.org` before choosing work, + not to guess from vibes. That holds only while the doc is true. - **Don't commit game assets** (§5), `builddir/`, or `imgui.ini`. - Match surrounding code style; keep the engine/game split; prefer data (Lua) over hard-coded constants. diff --git a/requirements/milestones.org b/requirements/milestones.org index 9aa5a5a..3aeb4a9 100644 --- a/requirements/milestones.org +++ b/requirements/milestones.org @@ -25,6 +25,11 @@ 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. +- Follow-up: no source file =#include=s bgfx, SoLoud, ENet or EnTT, so + =meson.build= now treats them as OPTIONAL (linked only if a source build has + put them in /usr/local) and falls back to system packages otherwise. That is + what makes a native (non-container) build possible -- see README. Promote each + back to a required dependency when it is actually wired up. - 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 <bx/...> includes. @@ -104,9 +109,9 @@ graph, and form structures. - [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. +- [X] Resource system: Metal (mines on deposits) + Energy (wind turbines) + -- was deferred to M5 and DELIVERED there (generation, storage caps, + build + firing costs). * M3: Structural Destruction [MOSTLY DONE] (swapped with weapons -- destruction goes hand-in-hand with M2 building) @@ -126,47 +131,64 @@ This is the purely-structural half of Forts destruction (no weapons yet). - [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 +- [X] Per-strut HP pool (separate from stress) -- delivered in M4 +- [X] Fire (damage-over-time, strut-to-strut spread) -- delivered in M4 -* M4: Weapons & Damage +* M4: Weapons & Damage [MOSTLY DONE] (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 +- [X] Per-strut HP pool, depleted by weapon hits (independent of stress) +- [X] Cannon: ballistic projectile, splash damage with linear radius falloff, + knockback impulse, ~25% fire chance, per-shot energy cost. + NOTE: the UX is Forts' select-a-weapon-and-aim-within-its-arc, not the + click-drag angle/power originally sketched here. The projectile uses our + own integrator; Box2D is still idle. +- [X] Laser: 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; +- [X] 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, +- [X] 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 +Still missing from the vanilla roster / mechanics (see gameplay-gaps.org #5, #8): +mortar, flak + point-defence, machinegun/sniper (hitscan), guided swarm +missiles, EMP, and per-shot RECOIL on the firing structure (we apply knockback +to targets only). + +* M5: Reactor, Resources & Game Loop [MOSTLY DONE] 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) +- [X] Reactor entity -- large block, HP bar (a device with =is_core=) +- [X] Player reactor on left, enemy reactor on right (via the enemy-fort mod) +- [~] Reactor takes damage from direct hits, fire, falling/collision + -- splash and beam damage hit devices; FIRE does not damage devices, and + devices are not attached to the strut graph, so they never fall. +- [~] Win condition: destroy reactor HP OR disconnect it from its foundation + (collapse) -- only the HP path exists. The round ends when a team has no + surviving =is_core= device. The collapse path needs devices mounted on + the graph (see M6 / gameplay-gaps.org #3). +- [X] Resource system (deferred from M2): mines on metal deposits, wind + turbines for energy, generation rates, storage caps, build/fire costs +- [X] Win/lose condition + restart (R key) -* M6: Dummy Fort & Map +* M6: Dummy Fort & Map [PARTIAL] 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 +- [X] Dummy fort pre-built structure -- =data/mods/enemy-fort/= builds a + triangulated fort at x=25..29 with the enemy reactor inside. Wood only; + no bg-brace or ropes in it yet. +- [~] Map layout: metal deposits on both sides exist (=data/map.lua=), but the + terrain is still a flat half-plane, not a real heightmap. +- [~] Player starting area: player reactor + nearby deposits on the left; there + is no pre-built starter shell. +- [~] Visual polish: materials are visually distinct and can load real Forts art + (see CLAUDE.md section 5); no sky backdrop is drawn yet. * M7: Polish & Controls @@ -175,7 +197,10 @@ 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 +- [~] Visual feedback: fire glow done (burning struts flicker orange); no + per-damage-state art yet. Forts ships damage-state textures + (=materials/wood_panel_damaged_1..3.tga=, =bracing-d1/d2=, =armor-d1/d2=) + that a =texture_forts=-style field could pick up. - [X] Build UX: ghost/extrusion previews, hover highlights, build-grace timers - [ ] Edge cases: zero resources enforcement, etc. diff --git a/research/gameplay-gaps.org b/research/gameplay-gaps.org index 4974ef6..c6d1b17 100644 --- a/research/gameplay-gaps.org +++ b/research/gameplay-gaps.org @@ -17,20 +17,38 @@ constants.lua) cross-checked against community docs: * What we HAVE (baseline) +Re-verified against the code on <2026-07-18>. Keep this section honest: it is +what the rest of the document is measured against. + Building (wood / bg-brace / rope), mass-spring structural sim with stress + axial/angle breaking + cascading collapse, ground destroys debris, fire -(DoT + spread), HP, two weapons (cannon = ballistic, laser = beam/ignite), -a static enemy fort, Lua-data + mods, a dev UI. Resources are a placeholder -(depleting pools, no generation). +(DoT + spread), per-strut HP, two weapons (cannon = ballistic, laser = +beam/ignite) with per-shot energy cost and firing arcs, a pre-built enemy fort +(=data/mods/enemy-fort/=), Lua-data + mods, a dev UI. + +Since the first draft of this document we also have: +- *Devices*: reactor (=is_core=), mine, wind turbine, battery -- placeable, with + HP, damaged by splash and beams. +- *A real economy*: mines on metal deposits, turbines scaling with height, + storage caps, and metal/energy actually spent on building and firing. +- *A game loop*: win/lose when a team loses its last =is_core= device, plus + restart on R. +- *Bring-your-own Forts art*: =texture_forts= paths load real sprites from the + player's own install, falling back to the CC0 placeholders. * MISSING — grouped by system, each with the in-game reference -** 1. The Reactor + win/loss [CRITICAL — this is the actual game] +** 1. The Reactor + win/loss [MOSTLY DONE — M5] The core the whole game is about. =devices/reactor.lua=: HitPoints 100 (fragile), and it is ALSO a generator (EnergyProductionRate 100, MetalProductionRate 5). Win = destroy the enemy reactor by (a) direct damage, (b) fire/splash, or -(c) cutting its supports so it falls. We have no reactor, no win/loss, no restart. --> our M5. +(c) cutting its supports so it falls. + +DONE: the reactor exists as an =is_core= device that also generates, takes +splash and beam damage, and ends the round when a team has none left; R +restarts. STILL MISSING: fire does not damage devices, and path (c) does not +exist -- devices sit at fixed coordinates rather than being mounted on the strut +graph, so cutting the supports under a reactor never drops it. ** 2. Real resource economy [CRITICAL for the core loop] Two resources, generated by devices (all values from =devices/*.lua=): @@ -43,9 +61,17 @@ Two resources, generated by devices (all values from =devices/*.lua=): Resources are capped, not infinite pools. - *Costs*: building pieces, weapons, devices, AND FIRING all cost metal/energy (cannon EnergyFireCost 2000, MetalFireCost 50). Repair costs too. -We have placeholder pools only. -> deferred to our M5. +DONE in M5: mines on deposits, turbines scaling with height, battery storage +caps, and metal/energy spent on both building and firing. STILL MISSING: the +upgraded variants (mine2, turbine2), the derrick and the metal store, and +repair costs (see #7). + +** 3. Devices [PARTIAL — we now have 4 of them] +We have reactor, mine, turbine and battery, placeable with HP. Two structural +gaps remain: devices are NOT mounted on the strut graph (they sit at fixed +coordinates, so they cannot fall when their supports are cut -- see #1), and +most of the catalogue below is still absent. -** 3. Devices (whole category — we have ZERO) From =devices/device_list.lua=: - Resource: mine, mine2, turbine, turbine2, derrick, battery (energy store), store (metal store), reactor, minireactor. @@ -89,7 +115,8 @@ Doors and shields are real tactical mechanics (open to shoot, shield vs lasers). ** 8. Weapon aiming/firing details we simplified - Cannon/weapons cost energy+metal PER SHOT (EnergyFireCost) — firing is - resource-limited, not just reload-limited. + resource-limited, not just reload-limited. DONE for energy (=energy_cost= per + weapon); the per-shot METAL cost is still missing. - Recoil/kickback pushes the fort (we apply knockback to targets only, not recoil to the firing structure — Forts Recoil 600000, KickbackMean 40). - Spotters: sniper reveals targets and guides swarm missiles. @@ -115,29 +142,38 @@ replays (trivial with deterministic lockstep), sandbox. All post-v0.1. Mapping the above onto the (already-reordered) milestones: -| Gap | Milestone | Notes | +| Gap | Milestone | Status / notes | |---------------------------------------+-----------+--------------------------------| -| Reactor + win/loss + restart | M5 | the actual objective | -| Resource economy (mine/turbine/store) | M5 | deposits, generation, caps | -| Repair + Recycle | M7 | resource-cost actions | -| Devices framework (mount on struts) | M5/M6 | reactor is the first device | +| Reactor + win/loss + restart | M5 | DONE; no collapse-win path | +| Resource economy (mine/turbine/store) | M5 | DONE (no mine2/turbine2/store) | +| Per-shot energy cost | M4 | DONE (metal-per-shot missing) | +| Devices framework (mount on struts) | M5/M6 | not mounted on strut graph | | Armour + Door + Shield materials | M4/M7 | data-driven, small each | +| Firing recoil on the shooter | M4 | small, faithful, not started | | More weapons (mortar/flak/mg/missile) | M4 | point-defence + guided are new | -| Per-shot energy cost + recoil | M4 | small, faithful | +| Repair + Recycle | M7 | resource-cost actions | | Tech tree + Upgrades | post-v0.1 | big; build-order strategy | | Commanders/Factions | post-v0.1 | defines identity, large | -| Map deposits / terrain / foundations | M6 | needs a real map format | +| Map deposits / terrain / foundations | M6 | deposits done; terrain flat | | AI / campaign / multiplayer | post-v1 | out of scope | * Smallest high-value next steps (concrete) -1. *Reactor as a device + win/loss* (M5 kickoff): a mountable block with HP that, - at 0 HP or when disconnected from a foundation, ends the round. Gives the game - an actual goal to shoot for. (We already destroy struts and detect - foundation-connectivity, so both victory paths are within reach.) -2. *Real resources*: mines on deposits (+metal, -energy), turbines (+energy by - height), storage caps, and make building/firing actually spend them. -3. *Armour + Door materials*: data-only additions to the Lua material table - (armour = high HP/stiff/heavy; door = toggles blocking) — cheap, high value. -4. *Per-shot energy cost + firing recoil* on the cannon/laser — a few lines, - makes combat feel like Forts. +Items 1 and 2 of the original list (reactor + win/loss, real resources) are DONE; +what follows is the refreshed queue. + +1. *Armour material*: data-only addition to =data/materials.lua= (Forts armour is + HP 400, +25% stiffness, 2x mass). The material system already has every field + it needs, and =materials/armor.tga= is a TGA, so =texture_forts= picks up the + real sprite for free. Cheapest real gameplay depth available. +2. *Firing recoil*: apply an impulse to the FIRING structure, not just the target + (Forts Recoil 600000, KickbackMean 40). The knockback machinery already + exists; this is a few lines and makes combat feel like Forts. +3. *Mount devices on the strut graph*: attach devices to nodes so cutting the + supports drops them. Unlocks the second victory path in #1 and makes reactors + killable by collapse, which is a signature Forts moment. +4. *Door material*: toggles =blocks_projectiles= so you can open to shoot and + close to tank. Needs a small mechanic, not just data. +5. *Mortar or flak*: the next weapons. Flak brings a genuinely new mechanic + (point-defence intercepting incoming shells); mortar is a high-arc, + high-building-damage counterpart to the cannon. |
