code wiki / _hdl_build / nx_gamesave.nx

nx_gamesave.nx

buildroot/runtime/_hdl_build/nx_gamesave.nx

7939 B172 linesdepth 2pulls 3 transitivereach 36 importersview sourcekind library
docsdependenciesstructsconstsfunctions

about

nx_gamesave.nx -- the SOVEREIGN SAVE/LOAD PART. nx_gamebench ranked this #1: save-load-persistence was PARTIAL and blocked 11 of the 12 benchmarked reference titles -- the highest-demand missing capability in the whole game ecosystem, found by demand-ranking rather than by eye. WHAT WAS ACTUALLY MISSING: runtime/nx_save_slot.nx already signs a combined hash over two in-memory chromatin snapshots -- but it never writes bytes to disk, never reads them back, and has no gate. A game cannot save with it. This organ is the missing half: arbitrary game state <-> a durable file. Built as a CERTIFIED COMPOSABLE PART per knowledge/registry/game_parts.tsv doctrine ("build each part to exceed ONCE, then compose forever"), so every future emitted game inherits these properties for free: 1. BIT-EXACT ROUND-TRIP -- save->load->save is byte-identical. Our stack is all-integer with no float and no hidden clock (saved_at is CALLER-SUPPLIED on purpose), so a save file is reproducible. This is the determinism exceed carried into persistence; most engines cannot claim it. 2. ATOMIC -- write to .tmp, fsync, rename. A crash mid-save can never leave a torn save file. A reader only ever observes a complete file. 3. CORRUPTION REFUSED LOUD -- a single flipped byte fails the checksum and load returns an error code. It never hands back half-valid state. (The classic "corrupt save eats an 80-hour run" bug.) 4. FUTURE-VERSION REFUSED -- a newer format is rejected rather than misparsed. 5. ADDITIVE-ONLY (rule 13) -- saving over a slot banks the previous bytes as .prev. History is not destroyed, so a bad save is always recoverable. Self-contained (imports only nx_syscalls + the pure core) so it runs on the NAS as an MCP tool. seq1151 (2026-07-30): the byte<->i64 and rolling-fold MECHANISM moved to nx_gamesave_core.nx -- the ONE definition shared with the wasm save-image surface (nx_wasm_craft). This file is the FILE surface: atomicity, .prev banking, refusal codes. Format bytes UNCHANGED (gate-proven). license_tier: ORIGINAL expect_exit: 0

dependencies 2 imports · 27 importers

nx_syscalls.nx nx_gamesave_core.nx nx_gamesave.nx nx_char_identity_gate.nx nx_coc_engine.nx nx_collide2d_gate.nx nx_drift_engine.nx nx_entity_store_gate.nx nx_frontier_engine.nx nx_game_actor_gate.nx nx_game_breed_gate.nx nx_game_companion.nx nx_gamehud_gate.nx

diagram shows first 10 each side; +0 more imports, +17 more importers in the complete lists below.

imports: nx_syscalls.nxnx_gamesave_core.nx

imported by: nx_char_identity_gate.nxnx_coc_engine.nxnx_collide2d_gate.nxnx_drift_engine.nxnx_entity_store_gate.nxnx_frontier_engine.nxnx_game_actor_gate.nxnx_game_breed_gate.nxnx_game_companion.nxnx_gamehud_gate.nxnx_gamemusic_gate.nxnx_gamesave_gate.nxnx_genome_gate.nxnx_loottable_gate.nxnx_m2d_engine.nxnx_netsync_gate.nxnx_plotgen_gate.nxnx_rpgstats_gate.nxnx_vnsprite_gate.nxnx_voxchunk.nxnx_wardrobe_state.nxnx_wardrobe_state_gate.nxnx_wire_diablo2_gate.nxnx_wire_endlesssky_gate.nxnx_wire_nethack_gate.nxnx_wire_probe.nxnx_worldsim_gate.nx

structs

none

consts

30const GS_MAGIC_1469598103: i64 = 1469598103
31const GS_MAGIC_16777619: i64 = 16777619
33const GS_FMT_VER: i64 = 1
34const GS_HDR: i64 = 48
35const GS_MAXFIELDS: i64 = 65536
38const GS_E_OPEN: i64 = 0-1
39const GS_E_SHORT: i64 = 0-2
40const GS_E_MAGIC: i64 = 0-3
41const GS_E_VERSION: i64 = 0-4
42const GS_E_FIELDS: i64 = 0-5
43const GS_E_CKSUM: i64 = 0-6
44const GS_E_CAP: i64 = 0-7
45const GS_E_WRITE: i64 = 0-8

functions

47func gw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
calls 1: sys_write
48func gn(v: i64) -> i64
57func slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
called by 1: joinsuf
59func joinsuf(base: *u8, suf: *u8) -> *u8
called by 1: gs_save calls 2: slensys_mmap
70func put64(b: *u8, off: i64, v: i64) -> i64 { return gsc_put64(b, off, v) }
called by 1: gs_save calls 1: gsc_put64
71func get64(b: *u8, off: i64) -> i64 { return gsc_get64(b, off) }
called by 1: gs_load calls 1: gsc_get64
74func gs_cksum(b: *u8, n: i64) -> i64
called by 2: gs_savegs_load calls 1: gsc_fold_bytes
77func gs_exists(p: *u8) -> i64
called by 1: gs_save calls 2: sys_openat_rdsys_close
86func gs_save(path: *u8, schema_id: i64, state: *i64, n: i64, saved_at: i64) -> i64
123func gs_load(path: *u8, out: *i64, cap: i64, meta: *i64) -> i64
153func gs_verify(path: *u8) -> i64
calls 2: sys_mmapgs_load
159func gs_errname(e: i64) -> *u8
called by 1: main