code wiki / _hdl_build / nx_game_scaffold_gate.nx
nx_game_scaffold_gate.nx source
↩ module page · 114 lines · 7442 B
1// nx_game_scaffold_gate.nx -- GATE: the hardware-rung-up SCAFFOLD, catalog -> ... -> AUTOGENERATION. Seed a temp
2// catalog, then assert each rung: COMPOSE+RUN a level from catalog parts; RASTER it to an integer (no-float)
3// packed-RGB framebuffer + PNG (gold coins / red foes / green hero / cyan exit pixels present); AUTOGENERATE 5
4// NEW playable levels into the catalog (all win, counts VARY = real generation, non-degenerate); DETERMINISM
5// (same seed -> identical levels); INTEGRITY neg-control (autogen grows ONLY what it made -- a non-generated id
6// is absent); SOVEREIGNTY (generated specs are nb_template_safe; detector fires on a planted tag). PNG ->
7// knowledge/staging/game/platformer_1-1.png. license_tier: ORIGINAL
8import "nx_game_scaffold.nx"
9import "nx_game_render.nx"
10import "nx_nishi_builder.nx"
11import "nx_shade.nx"
12import "nx_png.nx"
13import "nx_ad_serve.nx"
14import "nx_syscalls.nx"
15
16const SG_PATH: *u8 = "/tmp/nishi_game_scaffold_gate.tsv"
17
18func g_p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
19func g_i(v: i64) -> i64 { let t: *u8 = sys_mmap(24); var m: i64 = v; var k: i64 = 0; if m == 0 { t[0]=48 as u8; k=1 } while m>0 { t[k]=(48+(m%10)) as u8; m=m/10; k=k+1 } let o: *u8=sys_mmap(24); var w: i64=0; var q: i64=k-1; while q>=0 { o[w]=t[q]; w=w+1; q=q-1 } sys_write(1,o,w); return 0 }
20
21func main(argc: i64, argv: *i64) -> i64 {
22 g_p("=== nx_game_scaffold_gate (hardware-rung-up: catalog -> run -> raster -> AUTOGENERATE) ===\n" as *u8)
23 let fd: i64 = sys_openat_wr(SG_PATH, 420); if fd >= 0 { sys_close(fd) }
24 nb_register(SG_PATH, "game" as *u8, "tilemap" as *u8, "overworld" as *u8, "Overworld" as *u8, "32x32|grass,dirt,water,stone|autotile" as *u8)
25 nb_register(SG_PATH, "game" as *u8, "mechanic" as *u8, "platform-jump" as *u8, "Platform jump" as *u8, "impulse=12|gravity=0.6|coyote=80|jumpbuffer=120" as *u8)
26 nb_register(SG_PATH, "game" as *u8, "entity" as *u8, "patroller" as *u8, "Patrol enemy" as *u8, "hp=3|speed=2|ai=patrol|drop=coin" as *u8)
27 nb_register(SG_PATH, "game" as *u8, "level" as *u8, "1-1" as *u8, "First level" as *u8, "overworld|coin*12|patroller*3|exit-right" as *u8)
28
29 let st: *i64 = sys_mmap(512) as *i64
30 var pass: i64 = 0; var tot: i64 = 0
31
32 // R2+R4 COMPOSE + RUN
33 ng_sim_run(SG_PATH, "1-1" as *u8, "platform-jump" as *u8, "patroller" as *u8, st)
34 tot = tot + 1; var ok1: i64 = 1
35 if st[7] != 1 { ok1 = 0 }
36 if st[1] != 12 { ok1 = 0 }
37 if st[3] != 3 { ok1 = 0 }
38 if st[14] != 1 { ok1 = 0 }
39 if st[5] != 16 { ok1 = 0 }
40 if ok1 == 1 { pass = pass + 1; g_p("PASS R2/R4 compose+run: 1-1 composed from catalog parts plays (12 coins, 3 foes, exit_x=16, WIN)\n" as *u8) } else { g_p("FAIL R2/R4\n" as *u8) }
41
42 // R5 RASTER -> integer framebuffer + PNG
43 let CELL: i64 = 20; let W: i64 = (st[5] + 1) * CELL; let H: i64 = 28
44 let fb: *i64 = sys_mmap(8 * 340 * 28) as *i64
45 gs_raster(st, fb, W, H, CELL)
46 sys_mkdir("knowledge/staging/game" as *u8, 0x1ed)
47 write_png(fb, W, H, "knowledge/staging/game/platformer_1-1.png" as *u8)
48 let cy: i64 = 14
49 let pHero: i64 = fb[cy * W + 10]
50 let pCoin: i64 = fb[cy * W + (1 * CELL + 10)]
51 let pFoe: i64 = fb[cy * W + ((st[1] + 1) * CELL + 10)]
52 let pExit: i64 = fb[cy * W + (st[5] * CELL + 10)]
53 tot = tot + 1; var ok2: i64 = 1
54 if sh_g(pHero) <= sh_r(pHero) { ok2 = 0 }
55 if sh_g(pHero) <= sh_b(pHero) { ok2 = 0 }
56 if sh_r(pCoin) <= 200 { ok2 = 0 }
57 if sh_b(pCoin) >= 120 { ok2 = 0 }
58 if sh_r(pFoe) <= sh_g(pFoe) { ok2 = 0 }
59 if sh_r(pFoe) <= sh_b(pFoe) { ok2 = 0 }
60 if sh_b(pExit) <= 150 { ok2 = 0 }
61 if sh_r(pExit) >= 120 { ok2 = 0 }
62 if ok2 == 1 { pass = pass + 1; g_p("PASS R5 raster: integer no-float framebuffer -> PNG (green hero, gold coins, red foes, cyan exit)\n" as *u8) } else { g_p("FAIL R5 raster pixels\n" as *u8) }
63
64 // R6 AUTOGENERATE 5 new playable levels
65 let coins: *i64 = sys_mmap(64) as *i64; let foes: *i64 = sys_mmap(64) as *i64
66 let cbox: *i64 = sys_mmap(16) as *i64; let fbox: *i64 = sys_mmap(16) as *i64
67 let seed: *i64 = sys_mmap(16) as *i64; seed[0] = 12345
68 var wins: i64 = 0; var cmin: i64 = 999; var cmax: i64 = 0
69 var idx: i64 = 1
70 while idx <= 5 {
71 let win: i64 = gs_autogen_one(SG_PATH, seed, idx, "platform-jump" as *u8, "overworld" as *u8, "patroller" as *u8, st, cbox, fbox)
72 coins[idx-1] = cbox[0]; foes[idx-1] = fbox[0]
73 if win == 1 { if st[2] == cbox[0] { if st[4] == fbox[0] { wins = wins + 1 } } }
74 if cbox[0] < cmin { cmin = cbox[0] }
75 if cbox[0] > cmax { cmax = cbox[0] }
76 g_p(" autogen auto-" as *u8); g_i(idx); g_p(": coins=" as *u8); g_i(cbox[0]); g_p(" foes=" as *u8); g_i(fbox[0]); g_p(" -> " as *u8); if win == 1 { g_p("WIN\n" as *u8) } else { g_p("REFUSED\n" as *u8) }
77 idx = idx + 1
78 }
79 tot = tot + 1; var ok3: i64 = 1
80 if wins != 5 { ok3 = 0 }
81 if cmax <= cmin { ok3 = 0 } // counts VARY -> real generation, not a constant clone
82 if ok3 == 1 { pass = pass + 1; g_p("PASS R6 autogenerate: 5 NEW playable levels taught to the catalog, all WIN, counts vary (real generation)\n" as *u8) } else { g_p("FAIL R6 wins=" as *u8); g_i(wins); g_p(" cmin=" as *u8); g_i(cmin); g_p(" cmax=" as *u8); g_i(cmax); g_p("\n" as *u8) }
83
84 // R6b DETERMINISM: same seed -> identical generated levels
85 let coins2: *i64 = sys_mmap(64) as *i64
86 seed[0] = 12345
87 idx = 1
88 while idx <= 5 { gs_autogen_one(SG_PATH, seed, idx, "platform-jump" as *u8, "overworld" as *u8, "patroller" as *u8, st, cbox, fbox); coins2[idx-1] = cbox[0]; idx = idx + 1 }
89 tot = tot + 1; var ok4: i64 = 1
90 var di: i64 = 0
91 while di < 5 { if coins2[di] != coins[di] { ok4 = 0 } di = di + 1 }
92 if ok4 == 1 { pass = pass + 1; g_p("PASS R6b determinism: same seed -> byte-identical levels (reproducible autogen, idempotent re-teach)\n" as *u8) } else { g_p("FAIL R6b\n" as *u8) }
93
94 // R6c INTEGRITY (negative control): autogen grows ONLY what it made -- a non-generated id is ABSENT
95 tot = tot + 1; var ok5: i64 = 1
96 if nb_present(SG_PATH, "game" as *u8, "level" as *u8, "auto-1" as *u8) != 1 { ok5 = 0 }
97 if nb_present(SG_PATH, "game" as *u8, "level" as *u8, "auto-99" as *u8) != 0 { ok5 = 0 }
98 var ci: i64 = 0
99 while ci < 5 { if coins[ci] < 5 { ok5 = 0 } if coins[ci] > 30 { ok5 = 0 } ci = ci + 1 } // non-degenerate range
100 if ok5 == 1 { pass = pass + 1; g_p("PASS R6c integrity: autogen grew ONLY auto-1..5 (auto-99 absent); every level non-degenerate (5..30 coins)\n" as *u8) } else { g_p("FAIL R6c\n" as *u8) }
101
102 // SOVEREIGNTY
103 tot = tot + 1; var ok6: i64 = 1
104 let atpl: *u8 = sys_mmap(256)
105 if nb_lookup(SG_PATH, "game" as *u8, "level" as *u8, "auto-1" as *u8, atpl) == 1 { if nb_template_safe(atpl) != 1 { ok6 = 0 } } else { ok6 = 0 }
106 if nb_template_safe("<script>x</script>" as *u8) != 0 { ok6 = 0 }
107 if as_has_thirdparty_js("<img src='//x'>" as *u8, 15) != 1 { ok6 = 0 }
108 if ok6 == 1 { pass = pass + 1; g_p("PASS S sovereignty: generated specs are sovereign-safe; <script/src= detector fires on a planted tag\n" as *u8) } else { g_p("FAIL S\n" as *u8) }
109
110 g_p("nx_game_scaffold_gate pass=" as *u8); g_i(pass); g_p("/" as *u8); g_i(tot)
111 if pass == tot { g_p(" verdict=GREEN (catalog scaffolds games hardware-rung-up to AUTOGENERATION)\n" as *u8); return 0 }
112 g_p(" verdict=RED\n" as *u8)
113 return 1
114}