feat: New theme + wire price adjustement

This commit is contained in:
gauvainboiche
2026-10-08 12:25:45 +02:00
parent aa9721ac2a
commit 1734487f1e
19 changed files with 348 additions and 88 deletions
+7 -8
View File
@@ -1,5 +1,6 @@
// Export / import of a save as a JSON or TXT file (or pasted text).
// Export / import of the save as a JSON or TXT file (or pasted text).
// Works on every device: download via a Blob link, import via file input or paste.
// The save is theme-independent: any export can be imported under any theme.
import { sanitizeState, serializeState } from '../engine/state.js';
@@ -7,7 +8,7 @@ const GAME_ID = 'idle-clicker';
const FORMAT = 1;
export class ImportError extends Error {
/** @param {'empty'|'invalid'|'unknown_theme'|'wrong_game'} code */
/** @param {'empty'|'invalid'|'wrong_game'} code */
constructor(code) {
super(code);
this.code = code;
@@ -15,12 +16,11 @@ export class ImportError extends Error {
}
/** The text a player downloads, copies or pastes back. */
export function buildExport(themeId, state, now = Date.now()) {
export function buildExport(state, now = Date.now()) {
return JSON.stringify(
{
game: GAME_ID,
format: FORMAT,
theme: themeId,
exportedAt: new Date(now).toISOString(),
state: JSON.parse(serializeState(state)),
},
@@ -29,8 +29,8 @@ export function buildExport(themeId, state, now = Date.now()) {
);
}
/** Validate imported text. Throws ImportError; never trusts the content. */
export function parseImport(text, ctx, knownThemeIds) {
/** Validate imported text and return a clean state. Throws ImportError; never trusts the content. */
export function parseImport(text, ctx) {
const trimmed = String(text ?? '').trim().replace(/^/, '');
if (!trimmed) throw new ImportError('empty');
@@ -41,11 +41,10 @@ export function parseImport(text, ctx, knownThemeIds) {
throw new ImportError('invalid');
}
if (data?.game !== GAME_ID || data.format !== FORMAT) throw new ImportError('wrong_game');
if (!knownThemeIds.includes(data.theme)) throw new ImportError('unknown_theme');
const state = sanitizeState(data.state, ctx);
if (!state) throw new ImportError('invalid');
return { themeId: data.theme, state };
return state;
}
export function downloadText(filename, text, mime = 'application/json') {