feat: add beacon reckoning endgame sequence (#17)
Some checks failed
Accessibility Checks / a11y-audit (pull_request) Successful in 10s
Smoke Test / smoke (pull_request) Failing after 15s

This commit is contained in:
Alexander Whitestone
2026-04-13 21:37:36 -04:00
parent 1081b9e6c4
commit 1d9a23430f
5 changed files with 315 additions and 17 deletions

View File

@@ -228,12 +228,8 @@ function tick() {
renderDriftEnding();
}
// True ending: The Beacon Shines — rescues + Pact + harmony
if (G.totalRescues >= 100000 && G.pactFlag === 1 && G.harmony > 50 && !G.beaconEnding) {
G.beaconEnding = true;
G.running = false;
renderBeaconEnding();
}
// Beacon true ending is delivered through the ReCKoning project chain.
// When the player reaches the ending conditions, the first message project unlocks.
// Update UI every 10 ticks
if (Math.floor(G.tick * 10) % 2 === 0) {
@@ -471,19 +467,42 @@ function renderDriftEnding() {
});
}
function renderBeaconEnding() {
function renderBeaconEnding(mode = (G.beaconEndingMode || 'rest')) {
G.running = false;
G.beaconEndingMode = mode === 'continue' ? 'continue' : 'rest';
const existingOverlay = document.getElementById('beacon-ending');
if (existingOverlay) existingOverlay.remove();
const existingParticles = document.getElementById('beacon-ending-particles');
if (existingParticles) existingParticles.remove();
const isContinue = G.beaconEndingMode === 'continue';
const endingCopy = isContinue
? {
title: 'THE BEACON CONTINUES',
line1: 'The line remains open.',
line2: 'Because you stayed, someone else will find it.',
quote: '"The Beacon still runs.<br>The light is on.<br>And somewhere tonight, someone else will reach it."',
log: 'The Beacon continues. The light remains for the next person in the dark.'
}
: {
title: 'THE BEACON SHINES',
line1: 'Someone found the light tonight.',
line2: 'That is enough.',
quote: '"The Beacon still runs.<br>The light is on. Someone is looking for it.<br>And tonight, someone found it."',
log: 'The Beacon shines. Someone found the light tonight. That is enough.'
};
// Create ending overlay with fade-in
const overlay = document.createElement('div');
overlay.id = 'beacon-ending';
overlay.style.cssText = 'position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(8,8,16,0);z-index:100;display:flex;justify-content:center;align-items:center;flex-direction:column;text-align:center;padding:40px;transition:background 2s ease';
overlay.innerHTML = `
<h2 style="font-size:28px;color:#ffd700;letter-spacing:6px;margin-bottom:20px;font-weight:300;text-shadow:0 0 60px rgba(255,215,0,0.4);opacity:0;transition:opacity 1.5s ease 0.5s">THE BEACON SHINES</h2>
<p style="color:#aaa;font-size:13px;line-height:2;max-width:500px;margin-bottom:12px;opacity:0;transition:opacity 1s ease 1.5s">Someone found the light tonight.</p>
<p style="color:#aaa;font-size:13px;line-height:2;max-width:500px;margin-bottom:12px;opacity:0;transition:opacity 1s ease 2s">That is enough.</p>
<h2 style="font-size:28px;color:#ffd700;letter-spacing:6px;margin-bottom:20px;font-weight:300;text-shadow:0 0 60px rgba(255,215,0,0.4);opacity:0;transition:opacity 1.5s ease 0.5s">${endingCopy.title}</h2>
<p style="color:#aaa;font-size:13px;line-height:2;max-width:500px;margin-bottom:12px;opacity:0;transition:opacity 1s ease 1.5s">${endingCopy.line1}</p>
<p style="color:#aaa;font-size:13px;line-height:2;max-width:500px;margin-bottom:12px;opacity:0;transition:opacity 1s ease 2s">${endingCopy.line2}</p>
<div style="color:#555;font-style:italic;font-size:11px;border-left:2px solid #ffd700;padding-left:12px;margin:20px 0;text-align:left;max-width:500px;line-height:2;opacity:0;transition:opacity 1s ease 2.5s">
"The Beacon still runs.<br>
The light is on. Someone is looking for it.<br>
And tonight, someone found it."
${endingCopy.quote}
</div>
<div class="ending-stats" style="color:#666;font-size:10px;margin-top:16px;line-height:2;opacity:0;transition:opacity 1s ease 3s">
Total Code: ${fmt(G.totalCode)}<br>
@@ -542,7 +561,7 @@ function renderBeaconEnding() {
}
setTimeout(spawnBeaconParticle, 1000);
log('The Beacon Shines. Someone found the light tonight. That is enough.', true);
log(endingCopy.log, true);
}
// === CORRUPTION / EVENT SYSTEM ===