# Save/Load Architecture Workshop Brief **Goal:** Design the save/load system — serialization strategy, versioning, migration, and relationship to tier serialization. **Ticket:** #354 (epic) **Priority:** MEDIUM — must resolve before vertical slice **Participants:** Tyre (architecture lead), Dudley (implementation), Troblum (evaluation), Qatux (docs), Si (tickets) **Source:** Architecture Review Audit 2026-02-11, Tyre R-08 ## Context Save/load is not addressed in any existing decision document or ticket. Both audit reviewers flagged this as a gap that must be resolved before the vertical slice. The audit consensus recommends a **custom SaveState struct** over bevy_reflect, with versioning and migration. Troblum notes this creates a third data model alongside ECS components and ObserverSnapshot — every NPC component change requires updating 3 places. D-026 defines tier serialization for State-saved NPCs (~1-2KB per frozen entity). The save/load system must interoperate with this — a full save includes all tiers, while tier serialization handles individual NPC state-save/restore during gameplay. ## Key Questions to Resolve ### Serialization Strategy 1. Custom `SaveState` struct vs bevy_reflect vs hybrid? (Audit recommends custom) 2. What is serialized? (All ECS components? Only authoritative state? Derived state rebuilt on load?) 3. What format? (bincode for speed, MessagePack for debuggability, JSON for human-readability?) 4. How large is a typical save? (15 NPCs x 1-2KB + map state + knowledge graphs + game clock) ### Versioning 5. What version scheme? (Semantic? Monotonic integer?) 6. How are migrations handled? (Forward-only? Rollback support?) 7. What triggers a version bump? (Any component change? Only breaking changes?) 8. How is backwards compatibility tested? ### Tier Integration 9. How does full-save serialization relate to tier serialization (#96)? 10. State-saved NPCs are already serialized blobs — does save/load wrap these directly? 11. Active-tier NPCs need full component serialization — same format as State-saved, or different? 12. How does the knowledge graph serialize? (Per-entity? Separate table?) ### Architecture 13. Where does save logic live? (bevy_ecs system? Separate module outside the schedule?) 14. How is save triggered? (Manual save, autosave, checkpoint?) 15. What about save corruption? (Checksums? Atomic writes? Backup previous save?) 16. Quick save vs named saves — different mechanisms or same with different metadata? ### Client-Side 17. Does the client need save/load awareness? (Save menu, load screen, save file browser) 18. How does save/load interact with the IPC bridge? (Pause simulation, serialize, resume?) 19. Are save files portable across platforms? (Q-007 implications) ## Input Documents | Document | What to read | Why | |----------|-------------|-----| | `decisions/architecture.md` | D-010, D-020, D-026 | Architecture constraints, tier system | | `server/src/npc/mod.rs` | NPC component model | What needs serializing | | `server/src/simulation/tier.rs` | Tier system stub | Existing serialization infrastructure | | `server/src/simulation/rng.rs` | SimRng (ChaCha20 seed) | RNG state must be saved for determinism | | `server/src/simulation/time.rs` | SimulationTime | Game clock state | | `server/Cargo.toml` | serde, rmp-serde dependencies | Available serialization tools | ## Expected Outputs 1. **Decision: D-0XX — Save/Load Architecture** — Strategy, format, versioning scheme 2. **SaveState schema:** Rust struct definitions with serde derives 3. **Migration strategy:** How version N saves load in version N+1 4. **Integration spec:** How save/load interacts with tier serialization 5. **Tickets:** Implementation tasks (server save system, client save UI, save format tests) ## Workshop Format Two rounds: - **Round 1:** Each participant analyzes from their domain (Tyre: architecture, Dudley: implementation, Troblum: risk and alternatives) - **Round 2:** Cross-review, resolve trade-offs, finalize schema