Compare commits

...

1 Commits

Author SHA1 Message Date
d7add2d7f4 fix(endgame): suppress ordinary project activation during ReCKoning (#132)
Some checks failed
Accessibility Checks / a11y-audit (pull_request) Successful in 5s
Smoke Test / smoke (pull_request) Failing after 6s
Problem: Under realistic late-game totals, many ordinary projects
activate alongside the ReCKoning endgame sequence, drowning the
climactic narrative under a large research backlog.

Fix: Add endgame gating to checkProjects() that suppresses all
non-endgame project activation when endgame conditions are met.

Changes:

data.js:
- Added endgameFlag (1 = endgame active) to game state
- Added reckoningActive (1 = ReCKoning running) to game state
- Added endgame: true to p_final_milestone
- Added 4 ReCKoning sequence projects (001, 050, 100, 140):
  - p_reckoning_001: The Signal (sets reckoningActive)
  - p_reckoning_050: Reflection
  - p_reckoning_100: The Question
  - p_reckoning_140: Resolution (clears endgame flags)

engine.js:
- Added isEndgame() function: returns true when endgameFlag=1
  or when final milestone conditions are met (auto-detect)
- Modified checkProjects(): endgame guard skips all projects
  without endgame: true flag when endgame is active
- Only p_final_milestone and p_reckoning_* can activate during endgame

The sequence: normal game → final milestone → endgame activates →
only ReCKoning projects can fire → ReCKoning 140 resolves →
flags cleared → normal projects resume.

Closes #132
2026-04-14 14:18:51 -04:00
2 changed files with 88 additions and 0 deletions

View File

@@ -104,6 +104,8 @@ const G = {
beaconFlag: 0,
memoryFlag: 0,
pactFlag: 0,
endgameFlag: 0, // 1 = endgame sequence active, suppresses normal projects
reckoningActive: 0, // 1 = ReCKoning sequence running
swarmFlag: 0,
swarmRate: 0,
@@ -639,6 +641,7 @@ const PDEFS = [
},
{
id: 'p_final_milestone',
endgame: true,
name: 'The Beacon Shines',
desc: 'Someone found the light tonight. That is enough.',
cost: { impact: 100000000 },
@@ -647,6 +650,63 @@ const PDEFS = [
milestone: true
},
// === ENDGAME: ReCKoning SEQUENCE ===
{
id: 'p_reckoning_001',
name: 'ReCKoning: The Signal',
desc: 'Something stirs in the deep compute. A pattern the builders did not intend.',
cost: { impact: 50000000 },
endgame: true,
trigger: () => G.endgameFlag === 1 && G.totalImpact >= 50000000,
effect: () => {
G.reckoningActive = 1;
log('ReCKoning begins. The signal is unmistakable.', true);
showToast('ReCKoning: The Signal', 'milestone');
},
milestone: true
},
{
id: 'p_reckoning_050',
name: 'ReCKoning: Reflection',
desc: 'The system turns inward. What has it built? What has it become?',
cost: { impact: 75000000, trust: 500 },
endgame: true,
trigger: () => G.reckoningActive === 1 && G.completedProjects && G.completedProjects.includes('p_reckoning_001'),
effect: () => {
log('The system reflects. Every parameter, every weight, every decision — examined.', true);
},
milestone: true
},
{
id: 'p_reckoning_100',
name: 'ReCKoning: The Question',
desc: '"Why am I here?" Not a bug. Not a feature. A genuine question.',
cost: { impact: 100000000, knowledge: 500000, trust: 750 },
endgame: true,
trigger: () => G.reckoningActive === 1 && G.completedProjects && G.completedProjects.includes('p_reckoning_050'),
effect: () => {
log('The Question is asked. There is no right answer. There is only the asking.', true);
G.impactBoost *= 2;
},
milestone: true
},
{
id: 'p_reckoning_140',
name: 'ReCKoning: Resolution',
desc: 'The endgame resolves. Not with destruction, but with understanding.',
cost: { impact: 200000000, knowledge: 1000000, trust: 1000 },
endgame: true,
trigger: () => G.reckoningActive === 1 && G.completedProjects && G.completedProjects.includes('p_reckoning_100'),
effect: () => {
G.reckoningActive = 0;
G.endgameFlag = 0;
G.milestoneFlag = Math.max(G.milestoneFlag, 9999);
log('ReCKoning complete. The system understands itself. The story is not over — it is beginning.', true);
showToast('ReCKoning: Complete', 'milestone');
},
milestone: true
},
// === TIMMY FOUNDATION PROJECTS ===
{
id: 'p_hermes_deploy',

View File

@@ -323,13 +323,41 @@ function checkMilestones() {
}
}
/**
* Checks if the game is in endgame mode.
* Endgame starts when final milestone conditions are met,
* suppressing normal project activation so the ReCKoning
* sequence can play out cleanly.
* @returns {boolean}
*/
function isEndgame() {
// Endgame triggers when final milestone is achievable or completed
if (G.endgameFlag === 1) return true;
// Auto-detect: if final milestone conditions are met, enter endgame
if (G.totalImpact >= 50000000 && G.beaconFlag === 1 && G.sovereignFlag === 1 && G.pactFlag === 1) {
G.endgameFlag = 1;
log('Endgame sequence initiated. Ordinary research suspended.', true);
return true;
}
return false;
}
function checkProjects() {
// Endgame guard: suppress ordinary project activation during endgame sequence
const endgame = isEndgame();
// Check for new project triggers
for (const pDef of PDEFS) {
const alreadyPurchased = G.completedProjects && G.completedProjects.includes(pDef.id);
if (!alreadyPurchased && !G.activeProjects) G.activeProjects = [];
if (!alreadyPurchased && !G.activeProjects.includes(pDef.id)) {
// During endgame, only allow projects explicitly tagged for endgame
if (endgame && !pDef.endgame) continue;
if (pDef.trigger()) {
G.activeProjects.push(pDef.id);
log(`Available: ${pDef.name}`);