# Game Save System Implementation Plan (RP2350/RP2040)

This document outlines the strategy for implementing non-volatile game save states using the onboard Flash memory.

## 1. Objectives
*   **Persistence:** Save game state so progress is kept after power-off.
*   **Multi-game Support:** Allow multiple games to have independent saves without overwriting each other.
*   **Safety:** Ensure flash writes don't interfere with program execution or interrupt handlers.
*   **Wear Leveling:** Minimize unnecessary writes to prolong flash lifespan.

## 2. Flash Memory Mapping
The RP2350 on this board has 8MB of Flash memory mapped starting at `XIP_BASE` (`0x10000000`). We will reserve the top section for data.

| Memory Range | Purpose | Size |
| :--- | :--- | :--- |
| `0x10000000 - 0x106FFFFF` | Program Code, Fonts, Assets | 7MB |
| `0x10700000 - 0x107EFFFF` | Reserved/Future | 960KB |
| `0x107F0000 - 0x107F0FFF` | **Save Registry** | 4KB (1 Sector) |
| `0x107F1000 - 0x107FFFFF` | **Game Save Slots** | 60KB (15 Slots) |

## 3. Architecture Components

### A. `PersistentStorage` Manager (`lib/persistent_storage.h`)
A singleton or static helper class that handles raw flash operations.
*   `bool save_exists(const char* game_id)`
*   `bool save_data(const char* game_id, void* data, size_t size)`
*   `bool load_data(const char* game_id, void* buffer, size_t size)`

### B. Updated `Game` Interface (`lib/game.h`)
Add methods to the base class to standardize how state is handled.
```cpp
virtual const char* get_game_id() const = 0;
virtual size_t get_save_data(void* buffer, size_t max_size) = 0;
virtual void load_save_data(const void* buffer, size_t size) = 0;
```

### C. Save Registry
To avoid collisions, the first sector (`0x107F0000`) will store a lookup table:
```cpp
struct RegistryEntry {
    char game_id[16];
    uint32_t sector_index;
    uint32_t data_size;
    uint32_t checksum;
};
```

## 4. Implementation Steps

1.  **Create `PersistentStorage`:**
    *   Implement flash sector erasing and programming using `pico/flash.h`.
    *   Include interrupt protection using `save_and_disable_interrupts()`.
2.  **Update `Game` Base Class:**
    *   Modify `lib/game.h` to include the virtual persistence methods.
3.  **Implement in Monopoly:**
    *   Create a `MonopolySaveState` struct (POD - Plain Old Data).
    *   Populate it from game variables in `get_save_data`.
4.  **Integrate with Launcher:**
    *   Modify `GameLauncher` to check for existing saves when a game is selected.
    *   Modify the main loop to trigger `save_data` at logical points (e.g., end of turn/exit).

## 5. Collision Avoidance Logic
*   When a game requests a save for the first time, the `PersistentStorage` manager scans the Registry.
*   If the `game_id` isn't found, it allocates the next available 4KB sector.
*   It writes the specific `game_id` and its assigned `sector_index` back to the Registry sector.
*   Sequential saves for that ID will always use that specific sector.

## 6. Important Notes
*   **Flash Wear:** Each sector supports ~100k erase cycles. Total lifespan depends on frequency of saves.
*   **Alignment:** Data must be programmed in multiples of `FLASH_PAGE_SIZE` (256 bytes).
*   **Recursion:** Never call flash functions from within an interrupt or callback that might be triggered during a write.
