# Save Memory and MEMCARD Domain: virtual hardware: save memory Function: normative Didactic companion: [`../learn/mental-model-save-memory-and-memcard.md`](../learn/mental-model-save-memory-and-memcard.md) ## 1 Scope This chapter defines the `game` persistence surface in PROMETEU. MEMCARD is a runtime-owned service layered on top of the runtime filesystem. Games do not get broad path-based filesystem access for saves. They use slot operations only. ## 2 Profile Contract (`game`) The v1 contract is fixed: - `32` slots per game (`slot_index: 0..31`); - each slot has up to `32KB` payload; - ownership is isolated by `app_id`; - persistence is explicit through `slot_commit`; - copy/export/import is a Hub/OS responsibility (outside game userland). ## 3 Slot Identity and Metadata Each slot has runtime-owned metadata: - `app_id` owner; - `slot_index`; - `save_uuid`; - `generation`; - `checksum`; - `payload_size`; - `state`. State values: - `0 = EMPTY` - `1 = STAGED` - `2 = COMMITTED` - `3 = CORRUPT` `generation` and `checksum` are not manually controlled by game code: - `generation` increments on successful `slot_commit`; - `checksum` is recalculated by runtime for committed payload integrity. ## 4 Host ABI Surface (v1) Canonical module: `mem` (version `1`). | Operation | Signature | | --- | --- | | `slot_count` | `mem.slot_count() -> (status:int, count:int)` | | `slot_stat` | `mem.slot_stat(slot:int) -> (status:int, state:int, used_bytes:int, generation:int, checksum:int)` | | `slot_read` | `mem.slot_read(slot:int, offset:int, max_bytes:int) -> (status:int, payload_hex:string, bytes_read:int)` | | `slot_write` | `mem.slot_write(slot:int, offset:int, payload_hex:string) -> (status:int, bytes_written:int)` | | `slot_commit` | `mem.slot_commit(slot:int) -> status:int` | | `slot_clear` | `mem.slot_clear(slot:int) -> status:int` | `status` is always the first return slot. ### 4.1 Byte transport note (v1) Current ABI transport for memcard payload is `payload_hex:string`. This is a temporary transport form until VM-owned bytes (`HeapRef`) is exposed in the host ABI path. ## 5 Operation Semantics ### `slot_count` - returns slot capacity visible to game profile (`32`); - does not depend on slot content. ### `slot_stat` - returns current state and integrity/version metadata for one slot. ### `slot_read` - reads from staged content when present, otherwise committed content; - returns empty payload with success when offset is beyond current payload end. ### `slot_write` - writes into slot staging buffer (does not persist directly); - supports offset writes; - does not allow resulting payload above `32KB`. ### `slot_commit` - persists staged payload for one slot; - commit is atomic at slot operation level (all-or-error, no silent partial success). ### `slot_clear` - clears staged content and removes committed slot payload. ## 6 Status Codes (Domain-Owned) Minimum status catalog: - `0 = OK` - `1 = EMPTY` - `2 = NOT_FOUND` - `3 = NO_SPACE` - `4 = ACCESS_DENIED` - `5 = CORRUPT` - `6 = CONFLICT` - `7 = UNAVAILABLE` - `8 = INVALID_STATE` ## 7 Fault Classification MEMCARD follows `16a`: - `Trap`: structural violations (invalid slot index, invalid call shape, invalid window value type/range); - `status`: operational domain conditions; - `Panic`: runtime invariant break only. Silent no-op is forbidden for operations with operational failure paths. ## 8 Runtime Layering and Storage Mapping MEMCARD is a domain layer over runtime FS. Runtime host mapping for v1 is namespace-isolated by `app_id`, for example: `/user/games//memcard/slot_.pmem` The exact host-side file naming is internal to runtime/host as long as ownership and isolation guarantees are preserved. ## 9 Explicit Persistence Rule PROMETEU does not auto-save slot staging data. Without `slot_commit`, writes remain staged and are not guaranteed as persisted committed state.]