code wiki / _hdl_build / nx_plotgen.nx
nx_plotgen.nx
buildroot/runtime/_hdl_build/nx_plotgen.nx
about
nx_plotgen.nx -- the SOVEREIGN PLOT GENERATOR. nx_gamebench hard GAP: nx_story_vm EXECUTES authored story
graphs but NOTHING GENERATED them, and the operator named "our own plot generator" explicitly. Feeds the
Monster Girl Island / Strive: Conquest north-star outputs.
Emits a graph in the EXACT format nx_story_vm already consumes (ch_target / ch_req / ch_set / node_is_end,
SV_NCH choices per node) -- so generated plots run on the existing VM with no adapter. Generation and
execution stay separate organs; this one only writes DATA.
★THE BUG THIS KILLS -- the UNWINNABLE QUEST. Procedural narrative's defining failure is emitting a story
whose ending is gated behind a flag no reachable path can set: the player needs a key that does not exist.
Here solvability is STRUCTURAL, not tested-for afterwards:
- a MAIN SPINE 0 -> 1 -> ... -> ending is laid down first, and its advance choice is ALWAYS choice 0
with NO flag requirement, so the spine is unconditionally walkable;
- every spine node RAISES a flag bit as you pass it;
- a gated branch at spine node k may only REQUIRE bits raised by spine nodes STRICTLY BEFORE k.
Therefore walking the spine always satisfies every gate it meets and always reaches an ending -- the
generator cannot emit an unwinnable plot, and the gate proves it by actually WALKING the graph via
sv_choose rather than by inspecting it.
Also: deterministic (same seed -> same plot, so a story is reproducible from its seed alone) and varied
(different seeds -> materially different plots, not one template with names swapped).
LIB ONLY -- no main() by ecosystem convention.
license_tier: ORIGINAL expect_exit: 0
dependencies 2 imports · 3 importers
imports: nx_syscalls.nxnx_story_vm.nx
imported by: nx_coc_engine.nxnx_plotgen_gate.nxnx_wire_endlesssky_gate.nx
structs
| none |
consts
| 27 | const PG_MAXFLAGBIT: i64 = 24 // flag bits we allocate to spine progress |
functions
| 29 | func pg_rng(st: *i64) -> i64 called by 1: pg_gen |
| 38 | func pg_bit(i: i64) -> i64 { var v: i64=1; var k: i64=0; while k<i { v=v*2; k=k+1 } return v } called by 1: pg_gen |
| 42 | func pg_gen(ch_target: *i64, ch_req: *i64, ch_set: *i64, is_end: *i64, |
| 100 | func pg_walk(ch_target: *i64, ch_req: *i64, ch_set: *i64, is_end: *i64, n: i64, maxsteps: i64) -> i64 |