fuzzyworld

nuts / files / src / persistence.ts

persistence.ts

3.0 KB · history · blame

1const DATA_VERSION = 3
2
3const KEYS = {
4 settings: 'nuts-settings-v3',
5 snapshot: 'nuts-snapshot-v3',
6} as const
7
8// ── Settings ───────────────────────────────────────────────────────────────
9
10export interface PersistedSettings {
11 v: number
12 nutRadius: number
13 gravityMode?: string
14 vibrateEnabled?: boolean
15 vibrateItems?: boolean
16 vibrateEdges?: boolean
17 kind?: string
18 randomPool?: string[]
19 refill?: boolean
20}
21
22export function loadSettings(): PersistedSettings | null {
23 try {
24 const raw = localStorage.getItem(KEYS.settings)
25 if (!raw) return null
26 const parsed = JSON.parse(raw) as PersistedSettings
27 if (parsed.v !== DATA_VERSION) return null
28 return parsed
29 } catch {
30 return null
31 }
32}
33
34export function saveSettings(s: Omit<PersistedSettings, 'v'>): void {
35 try {
36 localStorage.setItem(KEYS.settings, JSON.stringify({ v: DATA_VERSION, ...s }))
37 } catch { /* storage full – ignore */ }
38}
39
40// ── Nut snapshot ───────────────────────────────────────────────────────────
41
42export interface NutSnapshot {
43 x: number // normalised 0..1 (relative to screen size)
44 y: number
45 angle: number
46 radius: number // absolute px
47 colorIndex: number
48 kind: 'nut' | 'gem' | 'balloon' | 'metalnut' | 'rock' | 'stressball' | 'coin'
49 gemVariant: number
50}
51
52export interface SnapshotRecord {
53 v: number
54 screenW: number
55 screenH: number
56 nuts: NutSnapshot[]
57}
58
59export function saveSnapshot(
60 nuts: Array<{ body: { position: { x: number; y: number }; angle: number }; radius: number; colorIndex: number; kind: 'nut' | 'gem' | 'balloon' | 'metalnut' | 'rock' | 'stressball' | 'coin'; gemVariant: number }>,
61 screenW: number,
62 screenH: number,
63): void {
64 try {
65 const record: SnapshotRecord = {
66 v: DATA_VERSION,
67 screenW,
68 screenH,
69 nuts: nuts.map(n => ({
70 x: n.body.position.x / screenW,
71 y: n.body.position.y / screenH,
72 angle: n.body.angle,
73 radius: n.radius,
74 colorIndex: n.colorIndex,
75 kind: n.kind,
76 gemVariant: n.gemVariant,
77 })),
78 }
79 localStorage.setItem(KEYS.snapshot, JSON.stringify(record))
80 } catch { /* storage full – ignore */ }
81}
82
83export function loadSnapshot(): SnapshotRecord | null {
84 try {
85 const raw = localStorage.getItem(KEYS.snapshot)
86 if (!raw) return null
87 const record = JSON.parse(raw) as SnapshotRecord
88 if (record.v !== DATA_VERSION) return null
89 return record
90 } catch {
91 return null
92 }
93}
94
95export function clearSnapshot(): void {
96 localStorage.removeItem(KEYS.snapshot)
97}