code wiki / _hdl_build / nx_creature_battle_gate.nx
nx_creature_battle_gate.nx source
↩ module page · 84 lines · 6138 B
1// nx_creature_battle_gate.nx -- RUNS real battles on nx_creature_battle and asserts the mechanics are REAL, then
2// prints the actual transcript. Proves: a battle runs to a faint+winner; the type chart is ACTUALLY consulted
3// (super-effective deals >2x a not-very-effective hit); the damage formula scales with move power; it is
4// DATA-DRIVEN/MODDABLE (change ONE type field in the data -> the WINNER FLIPS, same creatures otherwise); and it
5// is DETERMINISTIC (same seed -> identical transcript). HONEST: this proves a battle CORE only -- NOT an s-class
6// game (no overworld/capture/party/trainer-AI/netcode/sprites/UI/content). license_tier: ORIGINAL expect_exit: 0
7import "nx_creature_battle.nx"
8import "nx_ad_serve.nx"
9import "nx_syscalls.nx"
10import "nx_gate_verdict.nx"
11
12func 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 }
13func 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 }
14func eqb(a: *u8, b: *u8) -> i64 { var i: i64 = 0; while a[i] != (0 as u8) { if a[i] != b[i] { return 0 } i = i + 1 } if b[i] != (0 as u8) { return 0 } return 1 }
15
16func mk_ember(c: *i64) -> i64 { cb_set(c, 1, 25, 90, 65, 50, 70, "Embercat" as *u8); cb_addmove(c, 1, 40, 100); cb_addmove(c, 0, 40, 100); cb_addmove(c, 0, 60, 95); return 0 }
17func mk_aqua(c: *i64, typ: i64) -> i64 { cb_set(c, typ, 25, 100, 58, 55, 50, "Aquapup" as *u8); cb_addmove(c, 2, 40, 100); cb_addmove(c, 0, 40, 100); return 0 }
18func mk_dummy(c: *i64, typ: i64) -> i64 { cb_set(c, typ, 25, 200, 50, 55, 40, "Dummy" as *u8); return 0 }
19
20func main(argc: i64, argv: *i64) -> i64 {
21 g_p("=== nx_creature_battle_gate (REAL battle core; honest slice of a Pixelmon backend, NOT an s-class game) ===\n" as *u8)
22 let A: *i64 = sys_mmap(8*24) as *i64; let B: *i64 = sys_mmap(8*24) as *i64
23 let buf: *u8 = sys_mmap(8192); let buf2: *u8 = sys_mmap(8192)
24 var pass: i64 = 0; var tot: i64 = 0
25
26 // T1 a real battle runs to a winner
27 mk_ember(A); mk_aqua(B, 2)
28 let w1: i64 = cb_battle(A, B, 7, buf)
29 g_p(buf)
30 tot = tot + 1; var ok1: i64 = 1
31 if w1 < 0 { ok1 = 0 }
32 if A[3] > 0 { if B[3] > 0 { ok1 = 0 } } // exactly one fainted (hp 0)
33 if ok1 == 1 { pass = pass + 1; g_p("PASS T1 a real battle ran to a faint + winner (transcript above)\n" as *u8) } else { g_p("FAIL T1\n" as *u8) }
34
35 // T2 type chart is ACTUALLY consulted: Fire->Grass (super) deals > 2x Fire->Water (not very), same variance roll
36 mk_ember(A)
37 let gd: *i64 = sys_mmap(8*24) as *i64; mk_dummy(gd, 3) // Grass
38 let wd: *i64 = sys_mmap(8*24) as *i64; mk_dummy(wd, 2) // Water
39 let s1: *i64 = sys_mmap(16) as *i64; s1[0] = 5
40 let s2: *i64 = sys_mmap(16) as *i64; s2[0] = 5
41 let dg: i64 = cb_damage(A, gd, 1, 40, s1)
42 let dw: i64 = cb_damage(A, wd, 1, 40, s2)
43 tot = tot + 1
44 if dg > dw * 2 { pass = pass + 1; g_p("PASS T2 type chart real: Fire->Grass dmg=" as *u8); g_i(dg); g_p(" > 2x Fire->Water dmg=" as *u8); g_i(dw); g_p("\n" as *u8) } else { g_p("FAIL T2 dg=" as *u8); g_i(dg); g_p(" dw=" as *u8); g_i(dw); g_p("\n" as *u8) }
45
46 // T3 damage formula scales with move power (Normal move on a Normal dummy -> 1x both, no STAB)
47 let nd: *i64 = sys_mmap(8*24) as *i64; mk_dummy(nd, 0)
48 let s3: *i64 = sys_mmap(16) as *i64; s3[0] = 9
49 let s4: *i64 = sys_mmap(16) as *i64; s4[0] = 9
50 let d40: i64 = cb_damage(A, nd, 0, 40, s3)
51 let d80: i64 = cb_damage(A, nd, 0, 80, s4)
52 tot = tot + 1
53 if d80 > d40 { pass = pass + 1; g_p("PASS T3 formula real: power 80 dmg=" as *u8); g_i(d80); g_p(" > power 40 dmg=" as *u8); g_i(d40); g_p("\n" as *u8) } else { g_p("FAIL T3\n" as *u8) }
54
55 // T4 DATA-DRIVEN / MODDABLE: change ONLY Aquapup's type (Water -> Grass) -> the WINNER FLIPS
56 mk_ember(A); mk_aqua(B, 2); let wWater: i64 = cb_battle(A, B, 7, buf)
57 mk_ember(A); mk_aqua(B, 3); let wGrass: i64 = cb_battle(A, B, 7, buf2)
58 tot = tot + 1
59 if wWater != wGrass { pass = pass + 1; g_p("PASS T4 moddable (data-driven): flip Aquapup type Water->Grass -> winner flips (" as *u8); if wWater==1 { g_p("Aquapup" as *u8) } else { g_p("Embercat" as *u8) } g_p(" -> " as *u8); if wGrass==1 { g_p("Aquapup" as *u8) } else { g_p("Embercat" as *u8) } g_p("); no logic hardcoded to a creature\n" as *u8) } else { g_p("FAIL T4 winner unchanged\n" as *u8) }
60
61 // T5 DETERMINISM: same seed -> identical transcript
62 mk_ember(A); mk_aqua(B, 2); cb_battle(A, B, 7, buf)
63 mk_ember(A); mk_aqua(B, 2); cb_battle(A, B, 7, buf2)
64 tot = tot + 1
65 if eqb(buf, buf2) == 1 { pass = pass + 1; g_p("PASS T5 determinism: same seed -> byte-identical transcript\n" as *u8) } else { g_p("FAIL T5\n" as *u8) }
66
67 // T6 sovereign transcript + honest scope
68 sys_mkdir("knowledge/staging/game" as *u8, 0x1ed)
69 let fd: i64 = sys_openat_wr("knowledge/staging/game/battle.txt" as *u8, 420); if fd >= 0 { var bl: i64=0; while buf[bl]!=(0 as u8){bl=bl+1} sys_write(fd, buf, bl); sys_close(fd) }
70 var bl2: i64 = 0; while buf[bl2] != (0 as u8) { bl2 = bl2 + 1 }
71 tot = tot + 1
72 if as_has_thirdparty_js(buf, bl2) == 0 { pass = pass + 1; g_p("PASS T6 sovereign: transcript is plain text, 0 third-party -> knowledge/staging/game/battle.txt\n" as *u8) } else { g_p("FAIL T6\n" as *u8) }
73
74 g_p("nx_creature_battle_gate pass=" as *u8); g_i(pass); g_p("/" as *u8); g_i(tot)
75 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
76 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
77 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
78 let ctr__dry: *i64 = gv_ctr()
79 ctr__dry[0] = pass
80 ctr__dry[1] = tot
81 let rc__dry: i64 = gv_verdict("CREATURE-BATTLE-GATE" as *u8, ctr__dry, "a REAL, moddable, deterministic battle CORE -- one honest slice; NOT an s-class game)" as *u8)
82 sys_exit(rc__dry)
83 return rc__dry
84}