141 lines
3.9 KiB
Markdown
141 lines
3.9 KiB
Markdown
# Save Memory and MEMCARD
|
|
|
|
Domain: virtual hardware: save memory
|
|
Function: normative
|
|
|
|
Didactic companion: [`../learn/mental-model-save-memory-and-memcard.md`](../runtime/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<Bytes>`) 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/<app_id>/memcard/slot_<NN>.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.]
|