Move save states to a browser console interface

This commit is contained in:
Ryan Lanny Jenkins 2025-06-04 20:40:05 -05:00
parent 5eda5c158b
commit 26f4a6120b
3 changed files with 565 additions and 541 deletions

59
src/store/saves.ts Normal file
View file

@ -0,0 +1,59 @@
import { GameState } from '../types'
const SAVE_SLOT_PREFIX = 'dionysian_idle_save_'
const saveGame = (slot: number, state: GameState) => {
try {
const saveData = JSON.stringify(state)
localStorage.setItem(`${SAVE_SLOT_PREFIX}${slot}`, saveData)
return true
} catch (error) {
console.error('Failed to save game:', error)
return false
}
}
const loadGame = (slot: number): GameState | null => {
try {
const saveData = localStorage.getItem(`${SAVE_SLOT_PREFIX}${slot}`)
if (!saveData) return null
return JSON.parse(saveData)
} catch (error) {
console.error('Failed to load game:', error)
return null
}
}
export const hasSaveInSlot = (slot: number): boolean => {
return !!localStorage.getItem(`${SAVE_SLOT_PREFIX}${slot}`)
}
// Create the global saves object
declare global {
interface Window {
saves: {
save: (slot: number) => void
load: (slot: number) => void
hasSave: (slot: number) => boolean
}
}
}
// Initialize the global saves object
window.saves = {
save: (slot: number) => {
const state = (window as any).gameStore?.getState()
if (state) {
saveGame(slot, state)
console.log(`Game saved to slot ${slot}`)
}
},
load: (slot: number) => {
const savedState = loadGame(slot)
if (savedState && (window as any).gameStore?.setState) {
(window as any).gameStore.setState(savedState)
console.log(`Game loaded from slot ${slot}`)
}
},
hasSave: hasSaveInSlot
}

View file

@ -109,8 +109,6 @@ export const useGameStore = create<
setActionCooldown: (cooldown: number) => void
buyItem: (itemId: string) => void
sellItem: (itemId: string) => void
saveToSlot: (slot: number) => void
loadFromSlot: (slot: number) => void
purchaseUpgrade: (upgradeId: string) => void
pray: () => void
buyEquipment: (equipmentId: string) => void
@ -118,7 +116,14 @@ export const useGameStore = create<
useEquipment: (equipmentId: string) => void
addCash: (amount: number) => void
}
>((set, get) => ({
>((set, get) => {
// Expose store methods to window for the save system
;(window as any).gameStore = {
getState: get,
setState: set
}
return {
cash: INITIAL_CASH,
inventory: INITIAL_INVENTORY,
fieldSize: INITIAL_FIELD_SIZE,
@ -503,19 +508,6 @@ export const useGameStore = create<
)
},
saveToSlot: (slot: number) => {
const state = get()
const { ...gameState } = state
saveGame(slot, gameState)
},
loadFromSlot: (slot: number) => {
const savedState = loadGame(slot)
if (savedState) {
set(savedState)
}
},
purchaseUpgrade: (upgradeId) => {
const { inventory, purchasedUpgrades } = get()
const upgrade = UPGRADES[upgradeId]
@ -674,4 +666,5 @@ export const useGameStore = create<
produce((state) => { state.cash += amount }),
)
},
}))
}
})

View file

@ -1,51 +1,23 @@
import { useEffect } from 'react'
import { hasSaveInSlot, useGameStore } from './useGameStore'
import { useGameStore } from './useGameStore'
import './saves' // Import the saves module to initialize the global saves object
export const useSaveSystem = () => {
const { saveToSlot, loadFromSlot } = useGameStore()
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === 'r' && e.ctrlKey) {
localStorage.clear()
}
const slot =
{
'1': 1,
'2': 2,
'3': 3,
'!': 1,
'@': 2,
'#': 3,
}[e.key] ?? null
if (slot !== null) {
if (e.shiftKey) {
saveToSlot(slot)
console.log(`Game saved to slot ${slot}`)
} else if (hasSaveInSlot(slot)) {
loadFromSlot(slot)
console.log(`Game loaded from slot ${slot}`)
}
}
}
window.addEventListener('keydown', handleKeyDown)
// Auto-save every 30 seconds
const interval = setInterval(() => {
saveToSlot(0)
window.saves.save(0) // Save to autosave slot
}, 30000)
console.log('Initalized save system')
console.log('Initialized save system')
return () => {
window.removeEventListener('keydown', handleKeyDown)
clearInterval(interval)
}
}, [saveToSlot, loadFromSlot])
}, [])
// When starting the game, load from the autosave slot
useEffect(() => {
loadFromSlot(0)
window.saves.load(0)
}, [])
}