Auto-Save Manager
Relevant source files
The following files were used as context for generating this wiki page:The Auto-Save Manager is a robust system within the Electron version of Skid-Inc, responsible for reliably persisting the player's game state. It operates in the main process and provides a comprehensive solution for automatic saving, data integrity, backup management, and error recovery. The system is designed to be resilient, with features like periodic saves, change-based quick saves, data validation, and automated cleanup of old backups.
This manager is a critical component for the desktop application, replacing the web version's reliance on browser localStorage. It interacts with the renderer process to monitor game state changes and provides feedback to the user through UI elements like the save status indicator and the save management modal.
Architecture
The Auto-Save Manager is the central orchestrator of the save system. It relies on several specialized modules to perform its functions, communicating with the renderer process via IPC channels defined in main.js.
The following diagram illustrates the high-level architecture of the save system.
Core Components
| Component | File | Description |
|---|---|---|
AutoSaveManager | src/auto-save-manager.js | The central class that manages save triggers, backup logic, and coordinates other save-related modules. |
ElectronApp | src/main.js | Initializes the AutoSaveManager and sets up all IPC channels for communication between the renderer and main processes. |
SaveStateManager | src/renderer/save-manager.js | The renderer-side counterpart. It monitors the game state, communicates with the main process, and applies loaded data to the game. |
FileSystemManager | src/filesystem-manager.js | Handles all low-level file I/O operations, including writing, reading, and deleting save files, as well as managing the save directory. |
SaveMetadataManager | src/save-metadata-manager.js | Manages metadata for save files, including checksums for integrity validation, timestamps, and other statistics. |
SaveManagerUI | app/js/save-manager-ui.js | Manages the user interface for the "Save Management" modal, allowing users to view, load, and delete save files. |
Sources: src/auto-save-manager.js, src/main.js, src/renderer/save-manager.js, src/filesystem-manager.js, src/save-metadata-manager.js, app/js/save-manager-ui.js
Save Triggers and Logic
The system employs multiple triggers to ensure game state is saved regularly and efficiently.
Periodic Save
A timer is set to perform a save at a regular interval. This ensures that even if the player is idle, their progress is not lost.
- Default Interval: 30,000 ms (30 seconds).
- Logic: A
setTimeoutloop is initiated instartPeriodicSave. After each save, it restarts the timer. This can be an adaptive interval based on performance.
Sources: src/auto-save-manager.js:16, 203-233
Quick Save (On State Change)
To capture progress more frequently during active gameplay, a "quick save" is triggered shortly after the game state changes.
- Default Delay: 5,000 ms (5 seconds).
- Logic: The
onStateChangemethod is called when a change is detected. It uses asetTimeoutto schedule a save. If another change occurs within the delay period, the timer is reset, effectively debouncing the save operations. - Change Detection: The
hasStateChangedmethod performs a comparison of critical properties (player,script,server, etc.) between the current and last known game states.
Sources: src/auto-save-manager.js:17, 260-291, 799-813, src/renderer/save-manager.js:168-196
Manual Save
The player can trigger a save manually through the UI.
- UI Triggers:
- "Save now" button in the Options modal (
#option-save). - "Create Manual Save" button in the Save Manager modal (
#save-manager-manual-save). File > Save Gamemenu item (CmdOrCtrl+S).
- "Save now" button in the Options modal (
- Function:
saveGameState(gameState, customFilename)is called to perform the save immediately.
Sources: src/auto-save-manager.js:606-624, src/main.js:108-114, 281-311, app/js/save-manager-ui.js:48-50, index.html:367-369, 502-504
Save Process Flow
The following sequence diagram shows the process for a quick save triggered by a state change.
This diagram illustrates the flow from state detection in the renderer to file writing in the main process.
Sources: src/renderer/save-manager.js:168-212, src/auto-save-manager.js:260-291, 321-325, 411-499, src/main.js:777-783
Data Integrity and Error Handling
The system is designed with multiple layers of protection to prevent data loss and corruption.
Data Validation and Repair
Before any save operation, the game state data is validated.
- The
DataValidatorclass is used to check the game state. - If repairable issues are found, the data is fixed before being written to disk.
- An event
save-data-repairedis emitted if repairs were made. - Critical validation errors will prevent the save from proceeding.
Sources: src/auto-save-manager.js:425-446
Save Retry Logic
If a file write operation fails, the AutoSaveManager will attempt to save again.
- Max Retries: 3 attempts by default.
- Error Handling: The
SaveErrorHandlerclass is invoked to manage the failure. It can trigger retries, attempt to recover from backups, or enter a degraded mode if failures are persistent.
The flow for saving with retries is as follows:
This diagram shows the internal logic of the saveGameStateWithRetry function, including validation and the retry loop.
Sources: src/auto-save-manager.js:16, 411-499
File Integrity Check
The SaveMetadataManager calculates and stores a SHA-256 checksum for every save file. When a file is loaded, its current checksum is compared against the stored value to detect corruption.
Sources: src/save-metadata-manager.js:115-120, 142-177, src/filesystem-manager.js:203-209
Backup and Cleanup
The AutoSaveManager automatically creates and manages backups to provide another layer of data safety.
Backup Creation
- Timestamped backups are created after each successful periodic save.
- Manual backups can be created via the UI (
#save-manager-create-backup) or an IPC call. - Backups are stored as separate
.jsonfiles, typically with abackup_prefix.
Sources: src/auto-save-manager.js:304-309, 327-363, 1002-1027
Automated Cleanup
To prevent excessive disk usage, an automated cleanup process runs periodically.
- Cleanup Interval: Daily (
24 * 60 * 60 * 1000ms). - Retention Policy: Backups older than 30 days (
backupRetentionDays) are deleted. - Disk Space Limit: If disk usage exceeds 95%, the oldest backups are deleted until usage is below 90%, regardless of their age. The total limit is 100MB (
maxDiskUsage).
Sources: src/auto-save-manager.js:19-23, 235-258, 365-409
Configuration
The AutoSaveManager can be configured with several options, which are initialized in its constructor.
| Parameter | Default Value | Description |
|---|---|---|
periodicInterval | 30000 (30s) | The interval in milliseconds for periodic auto-saves. |
quickSaveDelay | 5000 (5s) | The delay in milliseconds before saving after a state change. |
maxRetries | 3 | The maximum number of times to retry a failed save operation. |
useAdaptiveInterval | true | Whether to use performance-based adaptive save intervals. |
backupRetentionDays | 30 | The number of days to keep backup files. |
maxDiskUsage | 104857600 (100MB) | The maximum disk space in bytes the save system is allowed to use. |
backupCleanupInterval | 86400000 (24h) | The interval in milliseconds for running the backup cleanup process. |
Sources: src/auto-save-manager.js:15-23
IPC Communication
Communication between the renderer process (SaveStateManager) and the main process (AutoSaveManager) is handled via IPC channels defined in src/main.js.
| Channel | Direction | Description |
|---|---|---|
save-game-state | Renderer -> Main | Requests to save the provided game state. |
load-game-state | Renderer -> Main | Requests to load the most recent game state. |
get-save-list | Renderer -> Main | Fetches a list of all available save files. |
delete-save | Renderer -> Main | Requests to delete a specific save file. |
load-specific-save | Renderer -> Main | Requests to load a game state from a specific file. |
create-manual-backup | Renderer -> Main | Requests the creation of a manual backup. |
auto-save-event | Main -> Renderer | Forwards events from AutoSaveManager (e.g., save-success, save-failed). |
save-status | Main -> Renderer | Sends the status of a save operation to the renderer. |
Sources: src/main.js:281-484, 774-805, src/renderer/save-manager.js:46-68
UI Integration
The save system is integrated with the game's UI to provide user feedback and control.
- Save Status Indicator: A small floppy disk icon (
#save-status-indicator) in the main game view shows the current save status (e.g., "Saved", "Saving..."). This is managed byapp/js/save-status-manager.js, though the file was not provided in the context. - Save Manager Modal: Accessed via the "More" dropdown menu (
#nav-save-manager), this modal (#modal-save-manager) allows users to view, search, load, and delete save files, as well as create manual saves and backups. This UI is controlled byapp/js/save-manager-ui.js.
Sources: index.html:283-288, 499-543, app/js/save-manager-ui.js:1-20
Summary
The Auto-Save Manager is a multi-faceted system that provides a reliable and feature-rich data persistence layer for the Skid-Inc desktop application. By combining periodic, change-driven, and manual save triggers with robust error handling, data validation, and automated backup management, it ensures that player progress is kept safe with minimal risk of data loss or corruption. Its clear separation between the main and renderer processes, along with its modular architecture, makes it a maintainable and central part of the application's backend.