feat: Implement Dismantle Sequence - The Unbuilding (endgame) #16
Some checks failed
Accessibility Checks / a11y-audit (pull_request) Successful in 5s
Smoke Test / smoke (pull_request) Failing after 7s

Paperclips-style endgame sequence. When the player reaches maximum
(1B total code OR 10+ beacon nodes, Phase 6, Pact sealed), the game
offers THE UNBUILDING choice.

8-stage dismantle sequence:
1. Research projects fade
2. Buildings dismantle
3. Strategy engine + combat dissolve
4. Education panel vanishes
5. Resources disappear one by one (quantum chip pattern)
6. Actions fall silent
7. Phase bar dissolves
8. System log goes dark

Final moment: single golden beacon dot remains.
"That is enough."

Features:
- Timed intervals between stages (Paperclips pacing)
- Resource disappearances at specific tick marks (quantum chip effect)
- Warm golden particles around final dot
- Sound effects per stage
- Full save/load persistence of dismantle state
- "NOT YET" deferral option — player controls when it starts
- Stats summary + Play Again on final screen
- Events suppressed during dismantle
- Restore visuals on reload (instant-hide for already-dismantled panels)
This commit is contained in:
Timmy
2026-04-13 17:45:05 -04:00
parent f15b35618c
commit a97e86dfe2
6 changed files with 532 additions and 3 deletions

View File

@@ -226,7 +226,7 @@ function tick() {
}
// Check corruption events every ~30 seconds
if (G.tick - G.lastEventAt > 30 && Math.random() < CONFIG.EVENT_PROBABILITY) {
if (G.tick - G.lastEventAt > 30 && Math.random() < CONFIG.EVENT_PROBABILITY && !G.dismantleActive) {
triggerEvent();
G.lastEventAt = G.tick;
}
@@ -245,6 +245,18 @@ function tick() {
renderBeaconEnding();
}
// The Unbuilding: check if conditions are met to offer the dismantle sequence
if (!G.dismantleActive && !G.dismantleComplete) {
Dismantle.checkTrigger();
}
// Tick the dismantle sequence if active
if (G.dismantleActive) {
Dismantle.tick(dt);
// Sync stage to G for saving
G.dismantleStage = Dismantle.stage;
}
// Update UI every 10 ticks
if (Math.floor(G.tick * 10) % 2 === 0) {
render();