From 6cdd436caf9e2103f516442ab6e70a870d4cba04 Mon Sep 17 00:00:00 2001 From: Vaino Kauppila Date: Thu, 30 Jul 2026 11:56:27 +0300 Subject: Mount devices on the strut graph so cutting supports destroys them Implements win-condition path (c): destroy the enemy reactor by cutting its supports so it falls. Previously devices sat at fixed map coordinates, structurally immune to collapse. - BuildGraph gains MountedDevice tracking: mount_device/unmount_device, is_device_alive/get_device_hp/damage_device, nearest_device, with a break_node index-shift fix so mount references stay correct as other geometry on the same fort is destroyed. update_fire now also damages any device mounted on a burning strut. - app.cpp mounts devices onto the nearest strut (within 2 units) at both map-load and interactive placement, and after each tick's structural collapse pass, zeroes a device's HP if its mount didn't survive -- which flows through the existing win-condition/cleanup code unchanged. - tools/device_collapse_test.cpp: 15 headless tests covering collapse, partial support loss, splash/beam/fire-through-mount damage, multiple devices, index stability, and clean unmount. Verified: full test suite passes (15/15), sim_check shows zero regressions across all 3 maps. Co-Authored-By: Claude Sonnet 5 --- research/gameplay-gaps.org | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) (limited to 'research/gameplay-gaps.org') diff --git a/research/gameplay-gaps.org b/research/gameplay-gaps.org index 0d28e80..919e8b6 100644 --- a/research/gameplay-gaps.org +++ b/research/gameplay-gaps.org @@ -28,7 +28,8 @@ beam/ignite) with per-shot energy cost and firing arcs, a pre-built enemy fort 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. + HP, damaged by splash, beams and fire, and mounted on the strut graph so + cutting their supports destroys them (win condition path (c)). - *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 @@ -43,7 +44,7 @@ Since the first draft of this document we also have: * MISSING — grouped by system, each with the in-game reference -** 1. The Reactor + win/loss [MOSTLY DONE — M5] +** 1. The Reactor + win/loss [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 @@ -51,9 +52,31 @@ Win = destroy the enemy reactor by (a) direct damage, (b) fire/splash, or 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. +restarts. Path (c) now also works: devices are mounted onto the strut graph +(=BuildGraph::mount_device=, two mount-point nodes matching how struts attach) +at placement time -- both map-load devices and interactively-placed ones snap +onto the nearest strut within 2 world units. Each tick, after structural +collapse (=kill_grounded=, strut snapping) runs, any device whose mount nodes +were both destroyed has its HP zeroed, which flows through the existing +win-condition/cleanup code unchanged (it was already correct once something +actually killed the device on structural collapse -- nothing did, until now). +=src/game/build_graph.{hpp,cpp}= own the mount bookkeeping, including a +=break_node= index-shift fix so node indices stay correct after other geometry +is destroyed elsewhere on the same fort. Fire damaging devices also landed as +part of this: =update_fire= now damages any device whose mount strut is +burning, proportional to burn state. + +Verified by =tools/device_collapse_test.cpp= (15/15 passing, headless, no +SDL/Lua): tower-stands-under-gravity, reactor-destroyed-by-collapse, +reactor-falls-when-platform-cut, reactor-survives-partial-support-loss, +splash/beam/fire damage through mount struts, multiple devices on one +structure, device-index stability across unrelated breaks, and clean unmount. +=tools/sim_check.cpp= (all 3 maps, 5s soak) shows zero regressions. + +STILL MISSING: nothing for the core win-condition itself. Devices that aren't +near any strut (radius 2.0) stay unmounted and immune to structural collapse, +same as before this feature -- acceptable, since Forts devices are always +built on structure in practice. ** 2. Real resource economy [CRITICAL for the core loop] Two resources, generated by devices (all values from =devices/*.lua=): @@ -72,10 +95,9 @@ 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. +We have reactor, mine, turbine and battery, placeable with HP, now mounted on +the strut graph (see #1) so they fall when their supports are cut. Remaining +gap: most of the catalogue below is still absent. From =devices/device_list.lua=: - Resource: mine, mine2, turbine, turbine2, derrick, battery (energy store), -- cgit v1.3