code wiki / _hdl_build / nx_worldsim.nx
nx_worldsim.nx
buildroot/runtime/_hdl_build/nx_worldsim.nx
about
nx_worldsim.nx -- the SOVEREIGN FACTION / ECONOMY WORLD-SIM PART. nx_gamebench gap-queue rank 1 and a hard
GAP (nothing existed): blocks 4 benchmarked titles (Cataclysm-DDA factions, Freeciv civs+diplomacy,
Endless Sky governments) AND is the keystone of the operator's north-star output Strive: Conquest --
a persistent faction/economy world sim wrapped in a VN shell.
THE INVARIANTS THIS PART EXISTS TO HOLD (each a gate tooth):
1. ★CONSERVATION. A trade moves wealth, it does not mint or burn it: total after == total before, always.
Resource leaks and duplication are the defining bug of every simulated economy -- here the transfer is
a single guarded move, so conservation is structural rather than hoped-for.
2. ★SYMMETRIC RELATIONS BY CONSTRUCTION. attitude(A,B) and attitude(B,A) are the SAME cell, so the two
can never disagree. In stores that keep both halves, one-sided updates silently desync diplomacy --
A is at war with B while B thinks they are allies.
3. ACCOUNTED PRODUCTION. Wealth entering the world each tick equals exactly the sum of what territories
produced -- growth is auditable, never arbitrary.
4. DETERMINISTIC. Same world + same tick count -> identical state. Integer-only, seeded xorshift, so a
campaign replays exactly (the determinism exceed carried into simulation).
5. BOUNDED. Relations clamp to [-1000,1000]; resources never go negative; a faction cannot trade with
itself or trade what it does not have.
State is a flat i64 arena so a whole world drops into gs_save/gs_load (nx_gamesave).
LIB ONLY -- no main() by ecosystem convention.
license_tier: ORIGINAL expect_exit: 0
dependencies 1 imports · 4 importers
imports: nx_syscalls.nx
imported by: nx_frontier_engine.nxnx_netsync.nxnx_wire_endlesssky_gate.nxnx_worldsim_gate.nx
structs
| none |
consts
| 24 | const WS_HDR: i64 = 4 // nfac, tick, rngstate, reserved |
| 25 | const WS_RELMAX: i64 = 1000 |
| 26 | const WS_RELMIN: i64 = 0-1000 |
functions
| 28 | func ws_nfac(a: *i64) -> i64 { return a[0] } |
| 29 | func ws_tickno(a: *i64) -> i64 { return a[1] } called by 1: main |
| 31 | func ws_o_res(a: *i64) -> i64 { return WS_HDR } |
| 32 | func ws_o_pop(a: *i64) -> i64 { return WS_HDR + ws_nfac(a) } |
| 33 | func ws_o_terr(a: *i64) -> i64 { return WS_HDR + 2*ws_nfac(a) } |
| 34 | func ws_o_rel(a: *i64) -> i64 { return WS_HDR + 3*ws_nfac(a) } |
| 36 | func ws_words(nfac: i64) -> i64 { return WS_HDR + 3*nfac + nfac*nfac + 8 } |
| 37 | func ws_bytes(nfac: i64) -> i64 { return ws_words(nfac) * 8 } |
| 39 | func ws_clamp(v: i64, lo: i64, hi: i64) -> i64 |
| 45 | func ws_init(a: *i64, nfac: i64, seed: i64) -> i64 |
| 64 | func ws_res(a: *i64, f: i64) -> i64 { return a[ws_o_res(a) + f] } |
| 65 | func ws_pop(a: *i64, f: i64) -> i64 { return a[ws_o_pop(a) + f] } calls 1: ws_o_pop |
| 66 | func ws_terr(a: *i64, f: i64) -> i64 { return a[ws_o_terr(a) + f] } |
| 67 | func ws_set_res(a: *i64, f: i64, v: i64) -> i64 |
| 72 | func ws_set_pop(a: *i64, f: i64, v: i64) -> i64 { a[ws_o_pop(a) + f] = ws_clamp(v,0,0x3FFFFFFF); return 1 } |
| 73 | func ws_set_terr(a: *i64, f: i64, v: i64) -> i64 { a[ws_o_terr(a) + f] = ws_clamp(v,0,0x3FFFFFFF); return 1 } |
| 77 | func ws_rel_idx(a: *i64, i: i64, j: i64) -> i64 |
| 83 | func ws_rel(a: *i64, i: i64, j: i64) -> i64 |
| 91 | func ws_adjust_rel(a: *i64, i: i64, j: i64, d: i64) -> i64 |
| 104 | func ws_trade(a: *i64, from: i64, to: i64, amount: i64) -> i64 |
| 121 | func ws_total_res(a: *i64) -> i64 |
| 128 | func ws_production(a: *i64, rate: i64) -> i64 |
| 135 | func ws_rng(a: *i64) -> i64 |
| 146 | func ws_tick(a: *i64, rate: i64) -> i64 |