Skip to content

suspendmanager: suspend unsafe machine deconstruction - #5945

Open
Alistair-Afton wants to merge 2 commits into
DFHack:developfrom
Alistair-Afton:suspendmanager-machine-collapse
Open

Alistair-Afton wants to merge 2 commits into
DFHack:developfrom
Alistair-Afton:suspendmanager-machine-collapse

Conversation

@Alistair-Afton

Copy link
Copy Markdown
Contributor

Summary

Fixes #5777.

suspendmanager now inspects DestroyBuilding jobs: if removing a machine component would leave a connected component of its machine graph without any terrain-anchored node, the job is suspended with the new reason "Would collapse machinery". Deconstructions that leave every remaining component anchored proceed normally.

  • New Reason::DANGER_OF_COLLAPSE plus a union-find pass over machine_nodest connections that checks each surviving connected component for an anchor
  • A node counts as anchored only if its entire footprint sits on non-open tiles
  • The unsuspend pass and the building-panel overlay now handle destroy jobs so the reason is visible in-game
  • Scope note: only the machine containing the destroyed building is considered; components in other machines that are already orphaned collapse on the next stability pass regardless of which removal triggers it

Machine-collapse semantics (verified in-game on 53.16)

  • world.buildings.check_machine_collapse triggers a stability pass over all machines after a building removal
  • A connected graph component survives iff it retains at least one anchored node; otherwise it collapses wholesale
  • isPowerSource() alone does not anchor: a lone waterwheel over open space collapses
  • A single anchored gear holds up arbitrarily long chains of axles/gears hanging over open space
  • Orphaned components can persist indefinitely until some removal triggers the next pass

Testing

  • New test/plugins/suspendmanager.lua case fabricates a floor-anchored gear, hanging axle, and hanging gear chain, queues destroy jobs, runs suspendmanager now, and asserts the anchor's job is suspended while the endpoint's is not
  • 7/7 tests, 21/21 checks pass in-game
  • Also verified live on a purpose-built rig: the suspended anchor job prevented the collapse and the endpoint removal proceeded normally

@Alistair-Afton

Copy link
Copy Markdown
Contributor Author

The gcc-11 leg failure is not from this change: DF's test suite reported all tests passing, then crashed at quit with free(): invalid pointer, and the same signature just failed an unrelated branch's run in the same window. Filed as #5947. Windows legs hit the known retry-timeout issue that #5943 fixes.

@Alistair-Afton
Alistair-Afton force-pushed the suspendmanager-machine-collapse branch from 1a58ccb to 3a71580 Compare September 17, 2026 21:33
Reading parameters[1]/[2] without a size check was out-of-bounds UB when
'suspendmanager set' was invoked with fewer than two arguments. It
happened to return CR_WRONG_USAGE on most toolchains, but the garbage
read could match 'preventblocking' and break argument validation
entirely (seen on the gcc-11 CI leg).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Suspend manager not deconstructing water wheels safely

1 participant