code wiki / _hdl_build / nx_loottable_gate.nx

nx_loottable_gate.nx source

↩ module page · 211 lines · 8871 B

1// nx_loottable_gate.nx -- CERTIFICATION of nx_loottable (the LAST hard GAP on the gamebench board). 2// T1 ★EVERY TIER REACHABLE -- 100k rolls must observe every declared tier at least once. This is the 3// off-by-one killer: legendaries that can never drop. 4// T2 ★DISTRIBUTION MATCHES DECLARED WEIGHTS -- observed frequency per tier within 10% relative of expected 5// T3 DETERMINISM -- the same seed yields the identical item (tier, affixes, values) 6// T4 NO DUPLICATE AFFIXES -- across 20k items, no item carries the same affix twice 7// T5 VALUES IN RANGE -- every rolled value lies within its affix's declared [lo,hi] 8// T6 TIER DRIVES AFFIX COUNT -- higher tiers grant more affixes, exactly as the data says 9// T7 ★ANTI-VACUITY -- items genuinely VARY across seeds. A generator returning one fixed item would 10// satisfy determinism, range and no-duplicate perfectly. 11// T8 composes with nx_gamesave: a rolled item round-trips through save/load 12// license_tier: ORIGINAL expect_exit: 0 13import "nx_syscalls.nx" 14import "nx_loottable.nx" 15import "nx_gamesave.nx" 16 17func lw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 18func ln(v: i64) -> i64 { 19 if v==0 { sys_write(1,"0" as *u8,1); return 0 } 20 var m: i64=v; if m<0 { sys_write(1,"-" as *u8,1); m=0-m } 21 let t: *u8=sys_mmap(32); var k: i64=0 22 while m>0 { t[k]=(48+(m%10)) as u8; m=m/10; k=k+1 } 23 let o: *u8=sys_mmap(32); var q: i64=k-1; var i: i64=0 24 while q>=0 { o[i]=t[q]; i=i+1; q=q-1 } 25 sys_write(1,o,i); return 0 26} 27 28func main() -> i64 { 29 lw("=== nx_loottable_gate: does the loot table actually obey its own numbers? ===\n\n") 30 var pass: i64 = 0 31 var checks: i64 = 0 32 33 // ---- DATA: 5 tiers (common..legendary) and an 8-affix pool ---- 34 let NT: i64 = 5 35 let tw: *i64 = sys_mmap(NT*8) as *i64 36 let ta: *i64 = sys_mmap(NT*8) as *i64 37 tw[0]=600; tw[1]=250; tw[2]=100; tw[3]=45; tw[4]=5 // legendary = 5/1000 38 ta[0]=0; ta[1]=1; ta[2]=2; ta[3]=3; ta[4]=5 39 let NA: i64 = 8 40 let aw: *i64 = sys_mmap(NA*8) as *i64 41 let alo: *i64 = sys_mmap(NA*8) as *i64 42 let ahi: *i64 = sys_mmap(NA*8) as *i64 43 var i: i64 = 0 44 while i < NA { aw[i] = 10 + i; alo[i] = 1 + i*2; ahi[i] = 10 + i*5; i = i + 1 } 45 46 let oa: *i64 = sys_mmap(LT_MAXAFFIX*8) as *i64 47 let ov: *i64 = sys_mmap(LT_MAXAFFIX*8) as *i64 48 let on: *i64 = sys_mmap(8) as *i64 49 50 // ---------- T1 + T2 tier reachability and distribution over 100k rolls ---------- 51 let ROLLS: i64 = 100000 52 let seen: *i64 = sys_mmap(NT*8) as *i64 53 i = 0 54 while i < NT { seen[i] = 0; i = i + 1 } 55 var s: i64 = 1 56 while s <= ROLLS { 57 let t: i64 = lt_roll(s*2654435761, tw, ta, NT, aw, alo, ahi, NA, oa, ov, on) 58 if t >= 0 { seen[t] = seen[t] + 1 } 59 s = s + 1 60 } 61 checks = checks + 1 62 var unreachable: i64 = 0 63 i = 0 64 while i < NT { if seen[i]==0 { unreachable = unreachable + 1 } i = i + 1 } 65 if unreachable==0 { 66 lw("T1 GREEN every tier reachable over "); ln(ROLLS); lw(" rolls: ") 67 i = 0 68 while i < NT { ln(seen[i]); if i < NT-1 { lw("/") } i = i + 1 } 69 lw(" (legendary DID drop)\n"); pass=pass+1 70 } else { lw("T1 RED "); ln(unreachable); lw(" declared tiers NEVER rolled -- unreachable loot\n") } 71 72 checks = checks + 1 73 var totw: i64 = 0 74 i = 0 75 while i < NT { totw = totw + tw[i]; i = i + 1 } 76 var drift: i64 = 0 77 var worst: i64 = 0 78 i = 0 79 while i < NT { 80 let expect: i64 = (ROLLS * tw[i]) / totw 81 var d: i64 = seen[i] - expect 82 if d < 0 { d = 0 - d } 83 let tol: i64 = expect / 10 // 10% relative tolerance 84 if d > tol { drift = drift + 1 } 85 let relp: i64 = (d * 1000) / (expect + 1) // permil deviation 86 if relp > worst { worst = relp } 87 i = i + 1 88 } 89 if drift==0 { 90 lw("T2 GREEN distribution matches declared weights: worst tier deviates "); ln(worst) 91 lw(" permil of expected (tolerance 100)\n"); pass=pass+1 92 } else { lw("T2 RED "); ln(drift); lw(" tiers outside 10% of declared weight, worst "); ln(worst); lw(" permil\n") } 93 94 // ---------- T3 determinism ---------- 95 checks = checks + 1 96 let oa2: *i64 = sys_mmap(LT_MAXAFFIX*8) as *i64 97 let ov2: *i64 = sys_mmap(LT_MAXAFFIX*8) as *i64 98 let on2: *i64 = sys_mmap(8) as *i64 99 let t1a: i64 = lt_roll(987654321, tw, ta, NT, aw, alo, ahi, NA, oa, ov, on) 100 let t1b: i64 = lt_roll(987654321, tw, ta, NT, aw, alo, ahi, NA, oa2, ov2, on2) 101 var det: i64 = 1 102 if t1a != t1b { det = 0 } 103 if on[0] != on2[0] { det = 0 } 104 i = 0 105 while i < on[0] { if oa[i]!=oa2[i] { det=0 } if ov[i]!=ov2[i] { det=0 } i=i+1 } 106 if det==1 { 107 lw("T3 GREEN deterministic: seed 987654321 -> tier "); ln(t1a); lw(" with "); ln(on[0]) 108 lw(" affixes, identical both times\n"); pass=pass+1 109 } else { lw("T3 RED same seed produced different items\n") } 110 111 // ---------- T4 no duplicate affixes ---------- 112 checks = checks + 1 113 var dupitems: i64 = 0 114 s = 1 115 while s <= 20000 { 116 lt_roll(s*40503, tw, ta, NT, aw, alo, ahi, NA, oa, ov, on) 117 var a: i64 = 0 118 while a < on[0] { 119 var b: i64 = a + 1 120 while b < on[0] { if oa[a]==oa[b] { dupitems = dupitems + 1 } b = b + 1 } 121 a = a + 1 122 } 123 s = s + 1 124 } 125 if dupitems==0 { 126 lw("T4 GREEN no duplicate affixes across 20000 items (sampling without replacement holds)\n") 127 pass=pass+1 128 } else { lw("T4 RED "); ln(dupitems); lw(" duplicate-affix pairs found\n") } 129 130 // ---------- T5 values in range ---------- 131 checks = checks + 1 132 var oor: i64 = 0 133 s = 1 134 while s <= 20000 { 135 lt_roll(s*22695477, tw, ta, NT, aw, alo, ahi, NA, oa, ov, on) 136 var a: i64 = 0 137 while a < on[0] { 138 let id: i64 = oa[a] 139 if id < 0 { oor = oor + 1 } 140 if id >= NA { oor = oor + 1 } 141 if id >= 0 { if id < NA { 142 if ov[a] < alo[id] { oor = oor + 1 } 143 if ov[a] > ahi[id] { oor = oor + 1 } 144 } } 145 a = a + 1 146 } 147 s = s + 1 148 } 149 if oor==0 { 150 lw("T5 GREEN every affix value inside its declared [lo,hi] across 20000 items\n"); pass=pass+1 151 } else { lw("T5 RED "); ln(oor); lw(" out-of-range affix values\n") } 152 153 // ---------- T6 tier drives affix count ---------- 154 checks = checks + 1 155 var t6: i64 = 1 156 s = 1 157 while s <= 20000 { 158 let t: i64 = lt_roll(s*69069, tw, ta, NT, aw, alo, ahi, NA, oa, ov, on) 159 if t >= 0 { if on[0] != lt_affix_count(ta, t) { t6 = 0 } } 160 s = s + 1 161 } 162 if t6==1 { 163 lw("T6 GREEN affix count is exactly what the tier data declares (0/1/2/3/5 per tier)\n"); pass=pass+1 164 } else { lw("T6 RED affix count disagrees with the tier table\n") } 165 166 // ---------- T7 anti-vacuity: items actually vary ---------- 167 checks = checks + 1 168 var distinct: i64 = 0 169 let firstv: *i64 = sys_mmap(8) as *i64 170 lt_roll(11, tw, ta, NT, aw, alo, ahi, NA, oa, ov, on) 171 firstv[0] = oa[0]*1000 + ov[0] + on[0]*7 172 s = 12 173 while s <= 400 { 174 lt_roll(s, tw, ta, NT, aw, alo, ahi, NA, oa, ov, on) 175 let sig: i64 = oa[0]*1000 + ov[0] + on[0]*7 176 if sig != firstv[0] { distinct = distinct + 1 } 177 s = s + 1 178 } 179 if distinct > 100 { 180 lw("T7 GREEN anti-vacuity: "); ln(distinct) 181 lw("/389 sampled items differ from the first -- real variety, not one fixed drop\n"); pass=pass+1 182 } else { lw("T7 RED only "); ln(distinct); lw(" distinct items -- generator is near-constant\n") } 183 184 // ---------- T8 composes with nx_gamesave ---------- 185 checks = checks + 1 186 let IP: *u8 = "knowledge/nx_loottable_item.sav" as *u8 187 sys_unlinkat(IP) 188 let tier: i64 = lt_roll(20260720, tw, ta, NT, aw, alo, ahi, NA, oa, ov, on) 189 let NV: i64 = 2 + LT_MAXAFFIX*2 190 let vec: *i64 = sys_mmap(NV*8) as *i64 191 vec[0] = tier; vec[1] = on[0] 192 i = 0 193 while i < LT_MAXAFFIX { vec[2+i] = oa[i]; vec[2+LT_MAXAFFIX+i] = ov[i]; i = i + 1 } 194 let wrote: i64 = gs_save(IP, 80808, vec, NV, 1784580500) 195 let rd: *i64 = sys_mmap(NV*8) as *i64 196 let got: i64 = gs_load(IP, rd, NV, 0 as *i64) 197 var t8: i64 = 1 198 if got != NV { t8 = 0 } 199 if wrote <= 0 { t8 = 0 } 200 i = 0 201 while i < NV { if rd[i]!=vec[i] { t8=0 } i=i+1 } 202 if t8==1 { 203 lw("T8 GREEN composes with nx_gamesave: tier-"); ln(tier); lw(" item with "); ln(on[0]) 204 lw(" affixes round-tripped ("); ln(wrote); lw("B)\n"); pass=pass+1 205 } else { lw("T8 RED item did not survive save/load, rc="); ln(got); lw("\n") } 206 207 lw("\n=== nx_loottable_gate "); ln(pass); lw("/"); ln(checks) 208 if pass == checks { lw(" GREEN ===\n"); return 0 } 209 lw(" RED ===\n") 210 return 1 211}