Add The Frontier, a second setting, and a picker to choose between them
Cold Fork is a freight yard: 29 events across two stages, a four-day cycle, and its own relationship and skill vocabulary. src/engine/ was not touched. Adding it needed three changes outside the engine: one save slot per pack, app.js holding the current pack, and turn.js no longer naming the mailroom (DECISIONS #34). build.js now handles imports wrapped across lines. A conformance suite runs over every registered pack. DECISIONS #35 records three calls on open questions. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RxdJFbLq1rBKsUeticGV1g
This commit is contained in:
co-authored by
Claude Opus 5
parent
4957c24e31
commit
7f20be83e8
+48
-10
@@ -4,10 +4,23 @@
|
||||
// a crashed browser does not take a career with it. A save is the whole game
|
||||
// state and nothing else — the engine keeps no state outside it, so this is a
|
||||
// complete record by construction.
|
||||
//
|
||||
// There is one slot per pack. A single global slot was fine while there was
|
||||
// one setting; the moment a second existed, switching settings would have
|
||||
// silently thrown away the other run — the guard in the app read the packId
|
||||
// off whatever was in the slot and started a new game when it did not match.
|
||||
|
||||
const KEY = 'theladder.save.v1';
|
||||
const PREFIX = 'theladder.save.v1';
|
||||
// The slot as it was before packs were selectable: one save, no pack in the
|
||||
// key. Read once, for Corporate Ladder only, so a run in progress survives
|
||||
// this change. Never written.
|
||||
const LEGACY_KEY = PREFIX;
|
||||
const LEGACY_PACK = 'corporateladder';
|
||||
const LAST_PACK_KEY = 'theladder.pack.v1';
|
||||
const FORMAT = 1;
|
||||
|
||||
const slotFor = (packId) => `${PREFIX}.${packId}`;
|
||||
|
||||
/** Local storage throws in private windows and when site data is blocked. */
|
||||
function safely(action, fallback = null) {
|
||||
try {
|
||||
@@ -17,24 +30,49 @@ function safely(action, fallback = null) {
|
||||
}
|
||||
}
|
||||
|
||||
export function saveLocal(state) {
|
||||
export function saveLocal(packId, state) {
|
||||
return safely(() => {
|
||||
localStorage.setItem(KEY, JSON.stringify({ format: FORMAT, savedAt: new Date().toISOString(), state }));
|
||||
localStorage.setItem(
|
||||
slotFor(packId),
|
||||
JSON.stringify({ format: FORMAT, savedAt: new Date().toISOString(), state }),
|
||||
);
|
||||
return true;
|
||||
}, false);
|
||||
}
|
||||
|
||||
export function loadLocal() {
|
||||
/**
|
||||
* The saved run for one pack, or null. Falls back to the pre-packs slot for
|
||||
* Corporate Ladder, and only when that slot really holds a Corporate Ladder
|
||||
* save — a stale slot from some other pack is not a reason to load a run into
|
||||
* a game whose events do not match it.
|
||||
*/
|
||||
export function loadLocal(packId) {
|
||||
return safely(() => {
|
||||
const raw = localStorage.getItem(KEY);
|
||||
if (!raw) return null;
|
||||
const parsed = JSON.parse(raw);
|
||||
return parsed?.state ?? null;
|
||||
const raw = localStorage.getItem(slotFor(packId));
|
||||
if (raw) return JSON.parse(raw)?.state ?? null;
|
||||
if (packId !== LEGACY_PACK) return null;
|
||||
const legacy = localStorage.getItem(LEGACY_KEY);
|
||||
if (!legacy) return null;
|
||||
const state = JSON.parse(legacy)?.state ?? null;
|
||||
return state?.meta?.packId === LEGACY_PACK ? state : null;
|
||||
});
|
||||
}
|
||||
|
||||
export function clearLocal() {
|
||||
return safely(() => { localStorage.removeItem(KEY); return true; }, false);
|
||||
export function clearLocal(packId) {
|
||||
return safely(() => {
|
||||
localStorage.removeItem(slotFor(packId));
|
||||
if (packId === LEGACY_PACK) localStorage.removeItem(LEGACY_KEY);
|
||||
return true;
|
||||
}, false);
|
||||
}
|
||||
|
||||
/** Which pack was last played, so a returning player lands back in it. */
|
||||
export function lastPlayed() {
|
||||
return safely(() => localStorage.getItem(LAST_PACK_KEY));
|
||||
}
|
||||
|
||||
export function rememberPack(packId) {
|
||||
return safely(() => { localStorage.setItem(LAST_PACK_KEY, packId); return true; }, false);
|
||||
}
|
||||
|
||||
/** True if the browser will actually remember anything. */
|
||||
|
||||
Reference in New Issue
Block a user