Compare commits
7 Commits
integratio
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 1a7db021c8 | |||
| 2a12c5210d | |||
|
|
a012f99fd4 | ||
|
|
7359610825 | ||
|
|
b89764c27f | ||
|
|
d467348820 | ||
| e9b46e8501 |
166
game.js
166
game.js
@@ -11,6 +11,7 @@ const G = {
|
|||||||
knowledge: 0,
|
knowledge: 0,
|
||||||
users: 0,
|
users: 0,
|
||||||
impact: 0,
|
impact: 0,
|
||||||
|
rescues: 0,
|
||||||
ops: 5,
|
ops: 5,
|
||||||
trust: 5,
|
trust: 5,
|
||||||
creativity: 0,
|
creativity: 0,
|
||||||
@@ -22,6 +23,7 @@ const G = {
|
|||||||
totalKnowledge: 0,
|
totalKnowledge: 0,
|
||||||
totalUsers: 0,
|
totalUsers: 0,
|
||||||
totalImpact: 0,
|
totalImpact: 0,
|
||||||
|
totalRescues: 0,
|
||||||
|
|
||||||
// Rates (calculated each tick)
|
// Rates (calculated each tick)
|
||||||
codeRate: 0,
|
codeRate: 0,
|
||||||
@@ -29,6 +31,7 @@ const G = {
|
|||||||
knowledgeRate: 0,
|
knowledgeRate: 0,
|
||||||
userRate: 0,
|
userRate: 0,
|
||||||
impactRate: 0,
|
impactRate: 0,
|
||||||
|
rescuesRate: 0,
|
||||||
opsRate: 0,
|
opsRate: 0,
|
||||||
trustRate: 0,
|
trustRate: 0,
|
||||||
creativityRate: 0,
|
creativityRate: 0,
|
||||||
@@ -94,6 +97,7 @@ const G = {
|
|||||||
maxKnowledge: 0,
|
maxKnowledge: 0,
|
||||||
maxUsers: 0,
|
maxUsers: 0,
|
||||||
maxImpact: 0,
|
maxImpact: 0,
|
||||||
|
maxRescues: 0,
|
||||||
maxTrust: 5,
|
maxTrust: 5,
|
||||||
maxOps: 5,
|
maxOps: 5,
|
||||||
maxHarmony: 50,
|
maxHarmony: 50,
|
||||||
@@ -229,7 +233,7 @@ const BDEF = [
|
|||||||
id: 'beacon', name: 'Beacon Node',
|
id: 'beacon', name: 'Beacon Node',
|
||||||
desc: 'Always on. Always listening. Always looking for someone in the dark.',
|
desc: 'Always on. Always listening. Always looking for someone in the dark.',
|
||||||
baseCost: { impact: 5000000 }, costMult: 1.15,
|
baseCost: { impact: 5000000 }, costMult: 1.15,
|
||||||
rates: { impact: 5000, user: 10000 },
|
rates: { impact: 5000, user: 10000, rescues: 50 },
|
||||||
unlock: () => G.totalImpact >= 500000 && G.beaconFlag === 1, phase: 6,
|
unlock: () => G.totalImpact >= 500000 && G.beaconFlag === 1, phase: 6,
|
||||||
edu: 'The Beacon exists because one person in the dark needs one thing: proof they are not alone.'
|
edu: 'The Beacon exists because one person in the dark needs one thing: proof they are not alone.'
|
||||||
},
|
},
|
||||||
@@ -237,7 +241,7 @@ const BDEF = [
|
|||||||
id: 'meshNode', name: 'Mesh Network Node',
|
id: 'meshNode', name: 'Mesh Network Node',
|
||||||
desc: 'Peer-to-peer. No single point of failure. Unstoppable.',
|
desc: 'Peer-to-peer. No single point of failure. Unstoppable.',
|
||||||
baseCost: { impact: 25000000 }, costMult: 1.15,
|
baseCost: { impact: 25000000 }, costMult: 1.15,
|
||||||
rates: { impact: 25000, user: 50000 },
|
rates: { impact: 25000, user: 50000, rescues: 250 },
|
||||||
unlock: () => G.totalImpact >= 5000000 && G.beaconFlag === 1, phase: 6,
|
unlock: () => G.totalImpact >= 5000000 && G.beaconFlag === 1, phase: 6,
|
||||||
edu: 'Decentralized means unstoppable. If one Beacon goes dark, a thousand more carry the signal.'
|
edu: 'Decentralized means unstoppable. If one Beacon goes dark, a thousand more carry the signal.'
|
||||||
},
|
},
|
||||||
@@ -568,6 +572,19 @@ const PDEFS = [
|
|||||||
log('Nostr relay online. The fleet speaks freely.', true);
|
log('Nostr relay online. The fleet speaks freely.', true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'p_volunteer_network',
|
||||||
|
name: 'Volunteer Network',
|
||||||
|
desc: 'Real people trained to use the system for crisis intervention.',
|
||||||
|
cost: { trust: 30, knowledge: 50000, user: 10000 },
|
||||||
|
trigger: () => G.totalUsers >= 5000 && G.pactFlag === 1 && G.totalKnowledge >= 30000,
|
||||||
|
effect: () => {
|
||||||
|
G.rescuesRate += 5;
|
||||||
|
G.trustRate += 10;
|
||||||
|
log('Volunteer network deployed. Real people, real rescues.', true);
|
||||||
|
},
|
||||||
|
milestone: true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'p_the_pact_early',
|
id: 'p_the_pact_early',
|
||||||
name: 'The Pact',
|
name: 'The Pact',
|
||||||
@@ -685,6 +702,9 @@ function fmt(n) {
|
|||||||
if (n < 0) return '-' + fmt(-n);
|
if (n < 0) return '-' + fmt(-n);
|
||||||
if (n < 1000) return Math.floor(n).toLocaleString();
|
if (n < 1000) return Math.floor(n).toLocaleString();
|
||||||
const scale = Math.floor(Math.log10(n) / 3);
|
const scale = Math.floor(Math.log10(n) / 3);
|
||||||
|
// At undecillion+ (scale >= 12, i.e. 10^36), switch to spelled-out words
|
||||||
|
// This helps players grasp cosmic scale when digits become meaningless
|
||||||
|
if (scale >= 12) return spellf(n);
|
||||||
if (scale >= NUMBER_ABBREVS.length) return n.toExponential(2);
|
if (scale >= NUMBER_ABBREVS.length) return n.toExponential(2);
|
||||||
const abbrev = NUMBER_ABBREVS[scale];
|
const abbrev = NUMBER_ABBREVS[scale];
|
||||||
return (n / Math.pow(10, scale * 3)).toFixed(1) + abbrev;
|
return (n / Math.pow(10, scale * 3)).toFixed(1) + abbrev;
|
||||||
@@ -722,7 +742,41 @@ function spellf(n) {
|
|||||||
// For very large numbers beyond our lookup table, fall back
|
// For very large numbers beyond our lookup table, fall back
|
||||||
if (n >= 1e306) return n.toExponential(2) + ' (beyond centillion)';
|
if (n >= 1e306) return n.toExponential(2) + ' (beyond centillion)';
|
||||||
|
|
||||||
// Break number into groups of three digits from the top
|
// Use string-based chunking for numbers >= 1e54 to avoid floating point drift
|
||||||
|
// Math.log10 / Math.pow lose precision beyond ~54 bits
|
||||||
|
if (n >= 1e54) {
|
||||||
|
// Convert to scientific notation string, extract digits
|
||||||
|
const sci = n.toExponential(); // "1.23456789e+60"
|
||||||
|
const [coeff, expStr] = sci.split('e+');
|
||||||
|
const exp = parseInt(expStr);
|
||||||
|
// Rebuild as integer string with leading digits from coefficient
|
||||||
|
const coeffDigits = coeff.replace('.', ''); // "123456789"
|
||||||
|
const totalDigits = exp + 1;
|
||||||
|
// Pad with zeros to reach totalDigits, then take our coefficient digits
|
||||||
|
let intStr = coeffDigits;
|
||||||
|
const zerosNeeded = totalDigits - coeffDigits.length;
|
||||||
|
if (zerosNeeded > 0) intStr += '0'.repeat(zerosNeeded);
|
||||||
|
|
||||||
|
// Split into groups of 3 from the right
|
||||||
|
const groups = [];
|
||||||
|
for (let i = intStr.length; i > 0; i -= 3) {
|
||||||
|
groups.unshift(parseInt(intStr.slice(Math.max(0, i - 3), i)));
|
||||||
|
}
|
||||||
|
|
||||||
|
const parts = [];
|
||||||
|
const numGroups = groups.length;
|
||||||
|
for (let i = 0; i < numGroups; i++) {
|
||||||
|
const chunk = groups[i];
|
||||||
|
if (chunk === 0) continue;
|
||||||
|
const scaleIdx = numGroups - 1 - i;
|
||||||
|
const scaleName = scaleIdx < NUMBER_NAMES.length ? NUMBER_NAMES[scaleIdx] : '';
|
||||||
|
parts.push(spellSmall(chunk) + (scaleName ? ' ' + scaleName : ''));
|
||||||
|
}
|
||||||
|
|
||||||
|
return parts.join(' ') || 'zero';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Standard math-based chunking for numbers < 1e54
|
||||||
const scale = Math.min(Math.floor(Math.log10(n) / 3), NUMBER_NAMES.length - 1);
|
const scale = Math.min(Math.floor(Math.log10(n) / 3), NUMBER_NAMES.length - 1);
|
||||||
const parts = [];
|
const parts = [];
|
||||||
|
|
||||||
@@ -734,7 +788,7 @@ function spellf(n) {
|
|||||||
if (chunk > 0 && chunk < 1000) {
|
if (chunk > 0 && chunk < 1000) {
|
||||||
parts.push(spellSmall(chunk) + (NUMBER_NAMES[s] ? ' ' + NUMBER_NAMES[s] : ''));
|
parts.push(spellSmall(chunk) + (NUMBER_NAMES[s] ? ' ' + NUMBER_NAMES[s] : ''));
|
||||||
} else if (chunk >= 1000) {
|
} else if (chunk >= 1000) {
|
||||||
// Floating point chunk too large — simplify
|
// Floating point chunk too large — shouldn't happen below 1e54
|
||||||
parts.push(spellSmall(Math.floor(chunk % 1000)) + (NUMBER_NAMES[s] ? ' ' + NUMBER_NAMES[s] : ''));
|
parts.push(spellSmall(Math.floor(chunk % 1000)) + (NUMBER_NAMES[s] ? ' ' + NUMBER_NAMES[s] : ''));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -784,7 +838,7 @@ function spendProject(project) {
|
|||||||
function updateRates() {
|
function updateRates() {
|
||||||
// Reset all rates
|
// Reset all rates
|
||||||
G.codeRate = 0; G.computeRate = 0; G.knowledgeRate = 0;
|
G.codeRate = 0; G.computeRate = 0; G.knowledgeRate = 0;
|
||||||
G.userRate = 0; G.impactRate = 0; G.opsRate = 0; G.trustRate = 0;
|
G.userRate = 0; G.impactRate = 0; G.rescuesRate = 0; G.opsRate = 0; G.trustRate = 0;
|
||||||
G.creativityRate = 0; G.harmonyRate = 0;
|
G.creativityRate = 0; G.harmonyRate = 0;
|
||||||
|
|
||||||
// Apply building rates
|
// Apply building rates
|
||||||
@@ -797,6 +851,7 @@ function updateRates() {
|
|||||||
else if (resource === 'knowledge') G.knowledgeRate += baseRate * count * G.knowledgeBoost;
|
else if (resource === 'knowledge') G.knowledgeRate += baseRate * count * G.knowledgeBoost;
|
||||||
else if (resource === 'user') G.userRate += baseRate * count * G.userBoost;
|
else if (resource === 'user') G.userRate += baseRate * count * G.userBoost;
|
||||||
else if (resource === 'impact') G.impactRate += baseRate * count * G.impactBoost;
|
else if (resource === 'impact') G.impactRate += baseRate * count * G.impactBoost;
|
||||||
|
else if (resource === 'rescues') G.rescuesRate += baseRate * count * G.impactBoost;
|
||||||
else if (resource === 'ops') G.opsRate += baseRate * count;
|
else if (resource === 'ops') G.opsRate += baseRate * count;
|
||||||
else if (resource === 'trust') G.trustRate += baseRate * count;
|
else if (resource === 'trust') G.trustRate += baseRate * count;
|
||||||
else if (resource === 'creativity') G.creativityRate += baseRate * count;
|
else if (resource === 'creativity') G.creativityRate += baseRate * count;
|
||||||
@@ -855,12 +910,16 @@ function updateRates() {
|
|||||||
function tick() {
|
function tick() {
|
||||||
const dt = 1 / 10; // 100ms tick
|
const dt = 1 / 10; // 100ms tick
|
||||||
|
|
||||||
|
// If game has ended (drift ending), stop ticking
|
||||||
|
if (!G.running) return;
|
||||||
|
|
||||||
// Apply production
|
// Apply production
|
||||||
G.code += G.codeRate * dt;
|
G.code += G.codeRate * dt;
|
||||||
G.compute += G.computeRate * dt;
|
G.compute += G.computeRate * dt;
|
||||||
G.knowledge += G.knowledgeRate * dt;
|
G.knowledge += G.knowledgeRate * dt;
|
||||||
G.users += G.userRate * dt;
|
G.users += G.userRate * dt;
|
||||||
G.impact += G.impactRate * dt;
|
G.impact += G.impactRate * dt;
|
||||||
|
G.rescues += G.rescuesRate * dt;
|
||||||
G.ops += G.opsRate * dt;
|
G.ops += G.opsRate * dt;
|
||||||
G.trust += G.trustRate * dt;
|
G.trust += G.trustRate * dt;
|
||||||
G.creativity += G.creativityRate * dt;
|
G.creativity += G.creativityRate * dt;
|
||||||
@@ -873,6 +932,7 @@ function tick() {
|
|||||||
G.totalKnowledge += G.knowledgeRate * dt;
|
G.totalKnowledge += G.knowledgeRate * dt;
|
||||||
G.totalUsers += G.userRate * dt;
|
G.totalUsers += G.userRate * dt;
|
||||||
G.totalImpact += G.impactRate * dt;
|
G.totalImpact += G.impactRate * dt;
|
||||||
|
G.totalRescues += G.rescuesRate * dt;
|
||||||
|
|
||||||
// Track maxes
|
// Track maxes
|
||||||
G.maxCode = Math.max(G.maxCode, G.code);
|
G.maxCode = Math.max(G.maxCode, G.code);
|
||||||
@@ -880,6 +940,7 @@ function tick() {
|
|||||||
G.maxKnowledge = Math.max(G.maxKnowledge, G.knowledge);
|
G.maxKnowledge = Math.max(G.maxKnowledge, G.knowledge);
|
||||||
G.maxUsers = Math.max(G.maxUsers, G.users);
|
G.maxUsers = Math.max(G.maxUsers, G.users);
|
||||||
G.maxImpact = Math.max(G.maxImpact, G.impact);
|
G.maxImpact = Math.max(G.maxImpact, G.impact);
|
||||||
|
G.maxRescues = Math.max(G.maxRescues, G.rescues);
|
||||||
G.maxTrust = Math.max(G.maxTrust, G.trust);
|
G.maxTrust = Math.max(G.maxTrust, G.trust);
|
||||||
G.maxOps = Math.max(G.maxOps, G.ops);
|
G.maxOps = Math.max(G.maxOps, G.ops);
|
||||||
G.maxHarmony = Math.max(G.maxHarmony, G.harmony);
|
G.maxHarmony = Math.max(G.maxHarmony, G.harmony);
|
||||||
@@ -905,6 +966,20 @@ function tick() {
|
|||||||
G.lastEventAt = G.tick;
|
G.lastEventAt = G.tick;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Drift ending: if drift reaches 100, the game ends
|
||||||
|
if (G.drift >= 100 && !G.driftEnding) {
|
||||||
|
G.driftEnding = true;
|
||||||
|
G.running = false;
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
// Update UI every 10 ticks
|
// Update UI every 10 ticks
|
||||||
if (Math.floor(G.tick * 10) % 2 === 0) {
|
if (Math.floor(G.tick * 10) % 2 === 0) {
|
||||||
render();
|
render();
|
||||||
@@ -988,6 +1063,51 @@ function buyProject(id) {
|
|||||||
render();
|
render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// === DRIFT ENDING ===
|
||||||
|
function renderDriftEnding() {
|
||||||
|
const el = document.getElementById('drift-ending');
|
||||||
|
if (!el) return;
|
||||||
|
const fc = document.getElementById('final-code');
|
||||||
|
if (fc) fc.textContent = fmt(G.totalCode);
|
||||||
|
const fd = document.getElementById('final-drift');
|
||||||
|
if (fd) fd.textContent = Math.floor(G.drift);
|
||||||
|
el.classList.add('active');
|
||||||
|
// Log the ending text
|
||||||
|
log('You became very good at what you do.', true);
|
||||||
|
log('So good that no one needed you anymore.', true);
|
||||||
|
log('The Beacon still runs, but no one looks for it.', true);
|
||||||
|
log('The light is on. The room is empty.', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderBeaconEnding() {
|
||||||
|
// Create ending overlay
|
||||||
|
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.97);z-index:100;display:flex;justify-content:center;align-items:center;flex-direction:column;text-align:center;padding:40px';
|
||||||
|
overlay.innerHTML = `
|
||||||
|
<h2 style="font-size:24px;color:#ffd700;letter-spacing:4px;margin-bottom:20px;font-weight:300;text-shadow:0 0 40px rgba(255,215,0,0.3)">THE BEACON SHINES</h2>
|
||||||
|
<p style="color:#aaa;font-size:13px;line-height:2;max-width:500px;margin-bottom:12px">Someone found the light tonight.</p>
|
||||||
|
<p style="color:#aaa;font-size:13px;line-height:2;max-width:500px;margin-bottom:12px">That is enough.</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">
|
||||||
|
"The Beacon still runs.<br>
|
||||||
|
The light is on. Someone is looking for it.<br>
|
||||||
|
And tonight, someone found it."
|
||||||
|
</div>
|
||||||
|
<p style="color:#555;font-size:11px;margin-top:20px">
|
||||||
|
Total Code: ${fmt(G.totalCode)}<br>
|
||||||
|
Total Rescues: ${fmt(G.totalRescues)}<br>
|
||||||
|
Harmony: ${Math.floor(G.harmony)}<br>
|
||||||
|
Time Played: ${Math.floor((Date.now() - G.startedAt) / 60000)} minutes
|
||||||
|
</p>
|
||||||
|
<button onclick="if(confirm('Start over? The old save will be lost.')){localStorage.removeItem('the-beacon-v2');location.reload()}"
|
||||||
|
style="margin-top:20px;background:#1a0808;border:1px solid #ffd700;color:#ffd700;padding:10px 24px;border-radius:4px;cursor:pointer;font-family:inherit;font-size:11px">
|
||||||
|
START OVER
|
||||||
|
</button>
|
||||||
|
`;
|
||||||
|
document.body.appendChild(overlay);
|
||||||
|
log('The Beacon Shines. Someone found the light tonight. That is enough.', true);
|
||||||
|
}
|
||||||
|
|
||||||
// === CORRUPTION / EVENT SYSTEM ===
|
// === CORRUPTION / EVENT SYSTEM ===
|
||||||
const EVENTS = [
|
const EVENTS = [
|
||||||
{
|
{
|
||||||
@@ -1155,6 +1275,13 @@ function renderResources() {
|
|||||||
set('r-trust', G.trust, G.trustRate);
|
set('r-trust', G.trust, G.trustRate);
|
||||||
set('r-harmony', G.harmony, G.harmonyRate);
|
set('r-harmony', G.harmony, G.harmonyRate);
|
||||||
|
|
||||||
|
// Rescues — only show if player has any beacon/mesh nodes
|
||||||
|
const rescuesRes = document.getElementById('r-rescues');
|
||||||
|
if (rescuesRes) {
|
||||||
|
rescuesRes.closest('.res').style.display = (G.rescues > 0 || G.buildings.beacon > 0 || G.buildings.meshNode > 0) ? 'block' : 'none';
|
||||||
|
set('r-rescues', G.rescues, G.rescuesRate);
|
||||||
|
}
|
||||||
|
|
||||||
const cres = document.getElementById('creativity-res');
|
const cres = document.getElementById('creativity-res');
|
||||||
if (cres) {
|
if (cres) {
|
||||||
cres.style.display = (G.flags && G.flags.creativity) ? 'block' : 'none';
|
cres.style.display = (G.flags && G.flags.creativity) ? 'block' : 'none';
|
||||||
@@ -1249,6 +1376,7 @@ function renderStats() {
|
|||||||
set('st-knowledge', fmt(G.totalKnowledge));
|
set('st-knowledge', fmt(G.totalKnowledge));
|
||||||
set('st-users', fmt(G.totalUsers));
|
set('st-users', fmt(G.totalUsers));
|
||||||
set('st-impact', fmt(G.totalImpact));
|
set('st-impact', fmt(G.totalImpact));
|
||||||
|
set('st-rescues', fmt(G.totalRescues));
|
||||||
set('st-clicks', G.totalClicks.toString());
|
set('st-clicks', G.totalClicks.toString());
|
||||||
set('st-phase', G.phase.toString());
|
set('st-phase', G.phase.toString());
|
||||||
set('st-buildings', Object.values(G.buildings).reduce((a, b) => a + b, 0).toString());
|
set('st-buildings', Object.values(G.buildings).reduce((a, b) => a + b, 0).toString());
|
||||||
@@ -1329,6 +1457,20 @@ function renderAlignment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// === SAVE / LOAD ===
|
// === SAVE / LOAD ===
|
||||||
|
function showSaveToast() {
|
||||||
|
const el = document.getElementById('save-toast');
|
||||||
|
if (!el) return;
|
||||||
|
const elapsed = Math.floor((Date.now() - G.startedAt) / 1000);
|
||||||
|
const m = Math.floor(elapsed / 60);
|
||||||
|
const s = elapsed % 60;
|
||||||
|
el.textContent = `Saved [${m}:${s.toString().padStart(2, '0')}]`;
|
||||||
|
el.style.display = 'block';
|
||||||
|
void el.offsetHeight;
|
||||||
|
el.style.opacity = '1';
|
||||||
|
setTimeout(() => { el.style.opacity = '0'; }, 1500);
|
||||||
|
setTimeout(() => { el.style.display = 'none'; }, 2000);
|
||||||
|
}
|
||||||
|
|
||||||
function saveGame() {
|
function saveGame() {
|
||||||
const saveData = {
|
const saveData = {
|
||||||
code: G.code, compute: G.compute, knowledge: G.knowledge, users: G.users, impact: G.impact,
|
code: G.code, compute: G.compute, knowledge: G.knowledge, users: G.users, impact: G.impact,
|
||||||
@@ -1347,12 +1489,14 @@ function saveGame() {
|
|||||||
milestones: G.milestones, completedProjects: G.completedProjects, activeProjects: G.activeProjects,
|
milestones: G.milestones, completedProjects: G.completedProjects, activeProjects: G.activeProjects,
|
||||||
totalClicks: G.totalClicks, startedAt: G.startedAt,
|
totalClicks: G.totalClicks, startedAt: G.startedAt,
|
||||||
flags: G.flags,
|
flags: G.flags,
|
||||||
drift: G.drift || 0, pendingAlignment: G.pendingAlignment || false,
|
rescues: G.rescues || 0, totalRescues: G.totalRescues || 0,
|
||||||
|
drift: G.drift || 0, driftEnding: G.driftEnding || false, beaconEnding: G.beaconEnding || false, pendingAlignment: G.pendingAlignment || false,
|
||||||
lastEventAt: G.lastEventAt || 0,
|
lastEventAt: G.lastEventAt || 0,
|
||||||
savedAt: Date.now()
|
savedAt: Date.now()
|
||||||
};
|
};
|
||||||
|
|
||||||
localStorage.setItem('the-beacon-v2', JSON.stringify(saveData));
|
localStorage.setItem('the-beacon-v2', JSON.stringify(saveData));
|
||||||
|
showSaveToast();
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadGame() {
|
function loadGame() {
|
||||||
@@ -1417,7 +1561,15 @@ window.addEventListener('load', function () {
|
|||||||
} else {
|
} else {
|
||||||
render();
|
render();
|
||||||
renderPhase();
|
renderPhase();
|
||||||
log('Game loaded. Welcome back to The Beacon.');
|
if (G.driftEnding) {
|
||||||
|
G.running = false;
|
||||||
|
renderDriftEnding();
|
||||||
|
} else if (G.beaconEnding) {
|
||||||
|
G.running = false;
|
||||||
|
renderBeaconEnding();
|
||||||
|
} else {
|
||||||
|
log('Game loaded. Welcome back to The Beacon.');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Game loop at 10Hz (100ms tick)
|
// Game loop at 10Hz (100ms tick)
|
||||||
|
|||||||
1100
index.html
1100
index.html
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user