A dark, mysterious five-act ARG built around hidden archives and forgotten witnesses.
Commit 58283b6a
58283b6a8b63Merged
Fenria-Aspen <[email protected]> · 1 month ago · 1 file · +1 added
Description
Add comprehensive game state management system
Details
- Commit
- 58283b6a8b63
- Parent
- 4ed257bbb2d7
assets/js/state.jsaddedView file
1+
// Game state management system2+
3+
const GameState = {4+
// Core progression5+
currentAct: 0,6+
currentPage: 'landing',7+
completedActs: new Set(),8+
9+
// Player inventory10+
inventory: {11+
items: new Map(),12+
totalItems: 013+
},14+
15+
// Evidence collected16+
evidence: {17+
documents: new Map(),18+
audioLogs: new Map(),19+
photographs: new Map(),20+
connections: [] // Links between evidence pieces21+
},22+
23+
// Decrypted messages24+
decrypted: new Map(),25+
26+
// Puzzles solved27+
solvedPuzzles: new Set(),28+
attemptedPuzzles: new Map(), // Track wrong answers29+
30+
// Discovered locations/sections31+
unlockedSections: new Set(['landing', 'act1']),32+
discoveredSecrets: new Set(),33+
34+
// Time tracking35+
startTime: null,36+
sessionTime: 0,37+
38+
// Endings discovered39+
endingsFound: new Set(),40+
41+
// Initialize state from localStorage42+
init() {43+
const saved = localStorage.getItem('hollow-archive-state');44+
if (saved) {45+
try {46+
const data = JSON.parse(saved);47+
Object.assign(this, data);48+
this.completedActs = new Set(data.completedActs || []);49+
this.solvedPuzzles = new Set(data.solvedPuzzles || []);50+
this.unlockedSections = new Set(data.unlockedSections || ['landing', 'act1']);51+
this.discoveredSecrets = new Set(data.discoveredSecrets || []);52+
this.endingsFound = new Set(data.endingsFound || []);53+
this.inventory.items = new Map(data.inventory?.items || []);54+
this.evidence.documents = new Map(data.evidence?.documents || []);55+
this.evidence.audioLogs = new Map(data.evidence?.audioLogs || []);56+
this.evidence.photographs = new Map(data.evidence?.photographs || []);57+
this.decrypted = new Map(data.decrypted || []);58+
} catch (e) {59+
console.warn('Failed to load saved state:', e);60+
}61+
}62+
this.startTime = this.startTime || Date.now();63+
},64+
65+
// Save state to localStorage66+
save() {67+
const data = {68+
currentAct: this.currentAct,69+
currentPage: this.currentPage,70+
completedActs: Array.from(this.completedActs),71+
solvedPuzzles: Array.from(this.solvedPuzzles),72+
unlockedSections: Array.from(this.unlockedSections),73+
discoveredSecrets: Array.from(this.discoveredSecrets),74+
endingsFound: Array.from(this.endingsFound),75+
inventory: {76+
items: Array.from(this.inventory.items),77+
totalItems: this.inventory.totalItems78+
},79+
evidence: {80+
documents: Array.from(this.evidence.documents),81+
audioLogs: Array.from(this.evidence.audioLogs),82+
photographs: Array.from(this.evidence.photographs),83+
connections: this.evidence.connections84+
},85+
decrypted: Array.from(this.decrypted),86+
startTime: this.startTime87+
};88+
localStorage.setItem('hollow-archive-state', JSON.stringify(data));89+
},90+
91+
// Add item to inventory92+
addItem(id, item) {93+
this.inventory.items.set(id, {94+
...item,95+
acquiredAt: Date.now()96+
});97+
this.inventory.totalItems++;98+
this.save();99+
},100+
101+
// Add evidence102+
addEvidence(id, evidence, type = 'documents') {103+
this.evidence[type].set(id, {104+
...evidence,105+
discoveredAt: Date.now()106+
});107+
this.save();108+
},109+
110+
// Link evidence together111+
linkEvidence(id1, id2, description) {112+
this.evidence.connections.push({113+
id1, id2, description,114+
linkedAt: Date.now()115+
});116+
this.save();117+
},118+
119+
// Mark puzzle as solved120+
solvePuzzle(puzzleId) {121+
this.solvedPuzzles.add(puzzleId);122+
this.save();123+
},124+
125+
// Record wrong attempt126+
recordAttempt(puzzleId, answer) {127+
if (!this.attemptedPuzzles.has(puzzleId)) {128+
this.attemptedPuzzles.set(puzzleId, []);129+
}130+
this.attemptedPuzzles.get(puzzleId).push({131+
answer,132+
timestamp: Date.now()133+
});134+
},135+
136+
// Unlock new section137+
unlockSection(sectionId) {138+
this.unlockedSections.add(sectionId);139+
this.save();140+
},141+
142+
// Discover secret143+
discoverSecret(secretId) {144+
this.discoveredSecrets.add(secretId);145+
this.save();146+
},147+
148+
// Record ending149+
recordEnding(endingId) {150+
this.endingsFound.add(endingId);151+
this.save();152+
},153+
154+
// Get game completion percentage155+
getCompletion() {156+
const maxActs = 5;157+
const maxSecrets = 12;158+
const maxEndings = 3;159+
const totalMax = maxActs + maxSecrets + maxEndings;160+
161+
const currentTotal = this.completedActs.size + this.discoveredSecrets.size + this.endingsFound.size;162+
return Math.round((currentTotal / totalMax) * 100);163+
},164+
165+
// Reset game166+
reset() {167+
if (confirm('Reset all progress? This cannot be undone.')) {168+
localStorage.removeItem('hollow-archive-state');169+
location.reload();170+
}171+
}172+
};173+
174+
// Initialize on load175+
document.addEventListener('DOMContentLoaded', () => {176+
GameState.init();177+
});