code wiki / _hdl_build / nx_game_scaffold.nx

nx_game_scaffold.nx source

↩ module page · 73 lines · 4531 B

1// nx_game_scaffold.nx -- LIB: the SCAFFOLD that ties the universal Nishi-builder catalog (the parts SSOT) to the 2// game ecosystem, HARDWARE-RUNG-UP, each rung building on the one below, up to AUTOGENERATION. The rungs: 3// R0 catalog SSOT (nb_*) -> R1 parts (mechanic/entity/level/tilemap emitters) -> R2 COMPOSE (pick parts) 4// -> R3 VALIDATE (all parts resolve, sovereign-safe) -> R4 RUN (ng_sim_run = the deterministic runtime) 5// -> R5 RASTER (integer, NO FLOAT, packed-RGB framebuffer -> PNG, the ecosystem's sovereign visual standard) 6// -> R6 AUTOGENERATE (procedurally synthesize NEW playable levels into the catalog, each verified by the runtime). 7// This is the platformer genre rung of project-nishi-game-ecosystem-generative, sourced from the ONE universal 8// catalog. Sovereign: NO float (decimals already milli-fixed in nx_game_render), NO JS, NO 3rd-party draw -- the 9// raster is pure-Nishi integer pixels (reuses nx_shade + nx_png, the same chain the arcade/2048 rungs ship through). 10// license_tier: ORIGINAL 11import "nx_game_render.nx" 12import "nx_nishi_builder.nx" 13import "nx_shade.nx" 14import "nx_png.nx" 15import "nx_ad_serve.nx" 16import "nx_syscalls.nx" 17const K_MAGIC_1103515245: i64 = 1103515245 18const K_MAGIC_12345: i64 = 12345 19const K_MAGIC_32767: i64 = 32767 20 21// deterministic LCG (seed lives in a 1-slot box so callers thread it) -- the autogen randomness, NO clock => reproducible. 22func gs_rng(seedbox: *i64) -> i64 { var x: i64 = seedbox[0]; x = x * K_MAGIC_1103515245 + K_MAGIC_12345; seedbox[0] = x; return (x >> 16) & K_MAGIC_32767 } 23 24// integer rectangle fill into the packed-RGB framebuffer (no float) -- same primitive the arcade rung uses. 25func gs_fill(fb: *i64, w: i64, h: i64, x0: i64, y0: i64, x1: i64, y1: i64, c: i64) -> i64 { 26 var yy: i64 = y0; if yy < 0 { yy = 0 } 27 var ye: i64 = y1; if ye > h { ye = h } 28 while yy < ye { 29 var xx: i64 = x0; if xx < 0 { xx = 0 } 30 var xe: i64 = x1; if xe > w { xe = w } 31 while xx < xe { fb[yy*w + xx] = c; xx = xx + 1 } 32 yy = yy + 1 33 } 34 return 0 35} 36 37// R5 RASTER: draw a finished run's 1-D track into the framebuffer. cell 0 = hero (green); 1..coins = gold coins; 38// coins+1..coins+foes = red foes; exit cell = cyan. Pure integer, no float, no canvas-draw. Returns track width in px. 39func gs_raster(st: *i64, fb: *i64, w: i64, h: i64, cell: i64) -> i64 { 40 sh_clear(fb, w, h, sh_rgb(16, 20, 30)) 41 let coins: i64 = st[1]; let foes: i64 = st[3]; let exitx: i64 = st[5] 42 var i: i64 = 0 43 while i <= exitx { 44 let x0: i64 = i * cell 45 var col: i64 = sh_rgb(40, 46, 60) // bare track tile 46 if i >= 1 { if i <= coins { col = sh_rgb(255, 210, 70) } } // coin = gold 47 if i > coins { if i <= coins + foes { col = sh_rgb(224, 80, 58) } } // foe = red 48 if i == exitx { col = sh_rgb(60, 200, 210) } // exit = cyan 49 gs_fill(fb, w, h, x0 + 2, cell / 2, x0 + cell - 2, cell - 2, col) 50 i = i + 1 51 } 52 gs_fill(fb, w, h, 2, cell / 2, cell - 2, cell - 2, sh_rgb(90, 210, 122)) // hero = green, at the start cell 53 return (exitx + 1) * cell 54} 55 56// R6 AUTOGENERATE one level: synthesize a NEW level spec deterministically from the seed, TEACH it to the catalog 57// (grow), then RUN it through the runtime. Leaves the run in st; returns win (1). out_c/out_f get the generated 58// coin/foe counts so a caller can verify the run matches what was generated. id = "auto-<idx>". 59func gs_autogen_one(path: *u8, seedbox: *i64, idx: i64, mech: *u8, tilemap: *u8, foe: *u8, st: *i64, out_c: *i64, out_f: *i64) -> i64 { 60 let c: i64 = 5 + (gs_rng(seedbox) % 26) // 5..30 coins (non-degenerate -- build intelligence, never an empty level) 61 let f: i64 = 1 + (gs_rng(seedbox) % 8) // 1..8 foes 62 out_c[0] = c; out_f[0] = f 63 let id: *u8 = sys_mmap(32); var o: i64 = 0 64 o = as_append(id, o, "auto-" as *u8); o = ng_num(id, o, idx); id[o] = 0 as u8 65 let spec: *u8 = sys_mmap(160); var s: i64 = 0 66 s = as_append(spec, s, tilemap); spec[s] = 124 as u8; s = s + 1 67 s = as_append(spec, s, "coin*" as *u8); s = ng_num(spec, s, c); spec[s] = 124 as u8; s = s + 1 68 s = as_append(spec, s, foe); spec[s] = 42 as u8; s = s + 1; s = ng_num(spec, s, f) 69 s = as_append(spec, s, "|exit-right" as *u8); spec[s] = 0 as u8 70 nb_register(path, "game" as *u8, "level" as *u8, id, "Autogen level" as *u8, spec) 71 ng_sim_run(path, id, mech, foe, st) 72 return st[7] 73}