code wiki / _hdl_build / nx_wire_diablo2_gate.nx
nx_wire_diablo2_gate.nx source
↩ module page · 1160 lines · 47674 B
1// nx_wire_diablo2_gate.nx -- TITLE WIRING #2: Open Diablo II (ARPG). An actual playable hack-and-slash
2// loop built ONLY from certified parts: procgen act maps seed monster packs (nx_entity_store), every kill
3// grants XP (nx_rpgstats) and rolls LOOT (nx_loottable) whose affixes EQUIP as stat modifiers
4// (rs_apply_mods -- order-independent by construction), the act theme renders through nx_gamemusic, and
5// the whole game state round-trips through nx_gamesave with the GX-9 transparency test.
6//
7// CAPS EXERCISED (bit = nx_gamebench capability index; the measured mask is payload[0] of the artifact):
8// bit 10 loot-item-tables bit 9 rpg-stats-progression bit 3 procgen-world
9// bit 6 entity-component-sim bit 16 audio-sfx-music bit 15 save-load-persistence
10// bit 18 ui-menus-hud (nx_gamehud: every DROP's equip-or-keep decision goes THROUGH a modal menu --
11// item 0 carries the tier policy, the RETURNED id drives the equip mutation; HUD binds live
12// hp/lvl/act/kills/tier per round, render-chain deterministic across replays)
13// NOT exercised (title requires, loop does not prove): bit 7 pathfinding, bit 0 render-2d,
14// bit 17 input-realtime -- the board must down-score these for this title.
15//
16// FLAGSHIP (mutation target): the kill->loot wiring. Skipping the roll must drive the loot tooth RED
17// (no tiers observed) while the game still plays to a win (anti-vacuity stays GREEN).
18//
19// DIALECT: no `else if`, no `||`, no multiline `else` -- those DESYNC the nx_cc parser (found by the
20// NetHack wiring; minimal repro nx_wire_probe.nx aux2). Plain ifs + flag vars only.
21// license_tier: ORIGINAL expect_exit: 0
22import "nx_syscalls.nx"
23import "nx_gamesave.nx"
24import "nx_rpgstats.nx"
25import "nx_entity_store.nx"
26import "nx_loottable.nx"
27import "nx_gamemusic.nx"
28import "nx_audio_wav.nx"
29import "nx_gamehud.nx"
30import "nx_game_raster.nx"
31import "nx_frame_sanity.nx"
32import "nx_wire_harness.nx"
33import "nx_gate_verdict.nx"
34import "nx_pathfind.nx"
35import "nx_input_abstract.nx"
36import "nx_trimesh.nx"
37import "nx_objload.nx"
38
39// ---- world shape (data at the top, rule 11) ----
40const D2_W: i64 = 20
41const D2_H: i64 = 10
42const D2_ACTS: i64 = 3
43const D2_NMON: i64 = 8
44const D2_CAP: i64 = 12
45const D2_NCOMP: i64 = 3 // 0=hp 1=xp_reward 2=packed pos
46const D2_CARVE: i64 = 90
47const D2_MAXT: i64 = 400
48// rpg tuning
49const D2_XB: i64 = 20
50const D2_XQ: i64 = 10
51const D2_HPB: i64 = 20
52const D2_HPC: i64 = 2
53const D2_HPL: i64 = 4
54const D2_CON: i64 = 12
55const D2_BDMG: i64 = 8 // base weapon damage before mods
56const D2_STRIKERS: i64 = 2 // how many monsters strike back per round
57// loot table (DATA)
58const D2_NTIER: i64 = 4 // normal / magic / rare / unique
59const D2_NAFF: i64 = 5 // +dmg / +dmg% / +hp / +hp% / +armor
60// save shape
61const D2_HDRN: i64 = 56 // 2026-08-23: grew 48 -> 56 for the wiring-drain fields
62const D2_NSV: i64 = 93 // 56 hdr + 1 n + 12*3 monsters
63const D2_SCHEMA: i64 = 7338 // schema BUMPED with the header growth (old 7308 saves refuse cleanly)
64const D2_ART_SCHEMA: i64 = 7318
65// transparency window (full run wins ~turn 60-90; window must sit fully before the win)
66const D2_T1W: i64 = 22
67const D2_T2W: i64 = 46
68// game arena offsets (i64 words)
69const DG_O_GRID: i64 = 64 // 200 cells
70const DG_O_CARVE: i64 = 272 // 208
71const DG_O_ENT: i64 = 480 // en_words(12,3)=4+60+36+8=108 pad 112
72const DG_O_HUD: i64 = 640 // nx_gamehud arena (GH_WORDS=64) APPENDED; UI transient, out of the save
73// 2026-08-23: pf_astar work arrays (transient, never serialized). 200 grid cells -> 208-word
74// spacing per array, same sizing rule the NetHack wire uses (288 cells -> 296 words).
75const DG_O_PG: i64 = 704
76const DG_O_PF2: i64 = 912
77const DG_O_PCAME: i64 = 1120
78const DG_O_POPEN: i64 = 1328
79const DG_O_PCLOSED: i64 = 1536
80const DG_O_PPATH: i64 = 1744
81const DG_WORDS: i64 = 1952
82const D2_HUDINK: i64 = 50 // min ink px for a non-vacuous HUD frame (T10 guard)
83// header fields
84const D_WS: i64 = 0
85const D_ACT: i64 = 1
86const D_TURN: i64 = 2
87const D_XP: i64 = 3
88const D_LVL: i64 = 4
89const D_HP: i64 = 5
90const D_KILLS: i64 = 6
91const D_DROPS: i64 = 7
92const D_T0: i64 = 8
93const D_T1: i64 = 9
94const D_T2: i64 = 10
95const D_T3: i64 = 11
96const D_WIN: i64 = 12
97const D_SPAWNED: i64 = 13
98const D_EQUIPS: i64 = 14
99const D_GENRNG: i64 = 15
100const D_DUPAFF: i64 = 16 // duplicate-affix violations observed (must stay 0)
101const D_AFFBAD: i64 = 17 // affix value out of declared range (must stay 0)
102const D_WT: i64 = 18 // equipped weapon tier (-1 none)
103const D_WNA: i64 = 19 // weapon affix count
104const D_WPAIR: i64 = 20 // 6 pairs (affix,val) -> 20..31
105const D_AT: i64 = 32
106const D_ANA: i64 = 33
107const D_APAIR: i64 = 34 // 34..45
108const D_ORDCHK: i64 = 46 // multi-mod drops where fwd/rev order equality was verified
109const D_ORDBAD: i64 = 47 // order-dependence violations observed (must stay 0)
110// 2026-08-23 WIRING-QUEUE DRAIN fields (header grew 48 -> 56; serialize/restore/ck carry them
111// automatically because all three iterate 0..D2_HDRN)
112const D_PX: i64 = 48 // player x (click-to-move position, pf_astar-driven)
113const D_PY: i64 = 49 // player y
114const D_PSTEPS: i64 = 50 // A* steps actually walked
115const D_PATHBAD: i64 = 51 // path violations observed in-loop (must stay 0)
116const D_INEV: i64 = 52 // confirm edges consumed through the F1102 input part
117const D_WALKS: i64 = 53 // click-to-move approaches issued
118const D_INSCRIPT: i64 = 54 // 1 = input script armed; 0 = control run (nothing can equip)
119const D_RES55: i64 = 55 // reserved
120
121func ww(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
122func wn(v: i64) -> i64 {
123 if v==0 { sys_write(1,"0" as *u8,1); return 0 }
124 var m: i64=v; if m<0 { sys_write(1,"-" as *u8,1); m=0-m }
125 let t: *u8=sys_mmap(32); var k: i64=0
126 while m>0 { t[k]=(48+(m%10)) as u8; m=m/10; k=k+1 }
127 let o: *u8=sys_mmap(32); var q: i64=k-1; var i: i64=0
128 while q>=0 { o[i]=t[q]; i=i+1; q=q-1 }
129 sys_write(1,o,i); return 0
130}
131func dbit(i: i64) -> i64 { var v: i64=1; var k: i64=0; while k<i { v=v*2; k=k+1 } return v }
132func drng(d: *i64) -> i64 {
133 var x: i64 = d[D_GENRNG]
134 x = x ^ (x << 13)
135 x = x ^ (x >> 7)
136 x = x ^ (x << 17)
137 d[D_GENRNG] = x
138 if x < 0 { return 0 - x }
139 return x
140}
141func dckv(ck: i64, v0: i64) -> i64 {
142 var v: i64 = v0
143 if v<0 { v = (0-v)*2+1 } else { v = v*2 }
144 return (ck*131 + v) & 0x7FFFFFFFFFFFFFFF
145}
146// loot tables as DATA (rule 11): weights per-mille-ish, affix ranges
147func d2_tables(tw: *i64, ta: *i64, aw: *i64, alo: *i64, ahi: *i64) -> i64 {
148 tw[0]=600; tw[1]=300; tw[2]=80; tw[3]=20
149 ta[0]=0; ta[1]=1; ta[2]=2; ta[3]=3
150 aw[0]=30; aw[1]=25; aw[2]=20; aw[3]=15; aw[4]=10
151 alo[0]=2; ahi[0]=9 // +dmg
152 alo[1]=5; ahi[1]=20 // +dmg%
153 alo[2]=5; ahi[2]=25 // +hp
154 alo[3]=4; ahi[3]=15 // +hp%
155 alo[4]=1; ahi[4]=8 // +armor
156 return 0
157}
158// ---- act map: PURE function of (ws, act); carve + pack spawn (positions drive loot seeds) ----
159func d2_genact(d: *i64) -> i64 {
160 d[D_GENRNG] = d[D_WS]*1000 + d[D_ACT]*7919
161 if d[D_GENRNG]==0 { d[D_GENRNG]=1 }
162 let grid: *i64 = (d as i64 + DG_O_GRID*8) as *i64
163 let carve: *i64 = (d as i64 + DG_O_CARVE*8) as *i64
164 var i: i64=0
165 while i<D2_W*D2_H { grid[i]=1; i=i+1 }
166 var cx: i64=1
167 var cy: i64=1
168 grid[cy*D2_W+cx]=0
169 carve[0]=cy*D2_W+cx
170 var nc: i64=1
171 var steps: i64=0
172 while steps<D2_CARVE {
173 let dd: i64 = drng(d)%4
174 var tx: i64=cx
175 var ty: i64=cy
176 if dd==0 { tx=cx+1 }
177 if dd==1 { tx=cx-1 }
178 if dd==2 { ty=cy+1 }
179 if dd==3 { ty=cy-1 }
180 if tx>=1 { if tx<=D2_W-2 { if ty>=1 { if ty<=D2_H-2 {
181 cx=tx; cy=ty
182 if grid[cy*D2_W+cx]==1 { grid[cy*D2_W+cx]=0; carve[nc]=cy*D2_W+cx; nc=nc+1 }
183 } } } }
184 steps=steps+1
185 }
186 let a: *i64 = (d as i64 + DG_O_ENT*8) as *i64
187 en_init(a, D2_CAP, D2_NCOMP)
188 let act: i64 = d[D_ACT]
189 var m: i64=0
190 while m<D2_NMON {
191 var placed: i64=0
192 var guard: i64=0
193 while placed==0 {
194 guard=guard+1
195 if guard>200 { placed=1 }
196 let pick: i64 = 1 + (drng(d) % (nc-1))
197 let cell: i64 = carve[pick]
198 var clash: i64=0
199 var k: i64=0
200 while k<en_count(a) {
201 let h: i64 = en_nth(a,k)
202 let op: i64 = en_get(a,h,2)
203 if op==cell { clash=1 }
204 k=k+1
205 }
206 if clash==0 { if placed==0 {
207 let h2: i64 = en_spawn(a)
208 if h2!=EN_NULL {
209 let mhp: i64 = 20 + act*10
210 en_set(a,h2,0,mhp)
211 let mxp: i64 = 20*act
212 en_set(a,h2,1,mxp)
213 en_set(a,h2,2,cell)
214 d[D_SPAWNED]=d[D_SPAWNED]+1
215 placed=1
216 }
217 } }
218 }
219 m=m+1
220 }
221 // 2026-08-23: the player enters every act at the carve origin -- the click-to-move walk
222 // (pf_astar, bit 7) starts here; the drunkard's-walk carve guarantees every monster cell
223 // is floor-connected to this origin by construction.
224 d[D_PX]=1
225 d[D_PY]=1
226 return nc
227}
228func d2_new(d: *i64, ws: i64) -> i64 {
229 var i: i64=0
230 while i<D2_HDRN { d[i]=0; i=i+1 }
231 d[D_WS]=ws
232 d[D_ACT]=1
233 d[D_LVL]=1
234 d[D_WT]=0-1
235 d[D_AT]=0-1
236 let hp0: i64 = rs_derived_hp(D2_CON, 1, D2_HPB, D2_HPC, D2_HPL)
237 d[D_HP]=hp0
238 d[D_INSCRIPT]=1
239 d2_genact(d)
240 let hud: *i64 = (d as i64 + DG_O_HUD*8) as *i64
241 gh_init(hud, 5)
242 return 0
243}
244// build the weapon-damage mod list from equipped weapon pairs (affix 0 -> +dmg, 1 -> +dmg%)
245func d2_wmods(d: *i64, mods: *i64) -> i64 {
246 var n: i64=0
247 var i: i64=0
248 while i<d[D_WNA] {
249 let af: i64 = d[D_WPAIR + i*2]
250 let vl: i64 = d[D_WPAIR + i*2 + 1]
251 if af==0 { mods[n*2]=0; mods[n*2+1]=vl; n=n+1 }
252 if af==1 { mods[n*2]=1; mods[n*2+1]=vl; n=n+1 }
253 i=i+1
254 }
255 return n
256}
257// armor-hp mod list from equipped armor pairs (affix 2 -> +hp, 3 -> +hp%)
258func d2_amods(d: *i64, mods: *i64) -> i64 {
259 var n: i64=0
260 var i: i64=0
261 while i<d[D_ANA] {
262 let af: i64 = d[D_APAIR + i*2]
263 let vl: i64 = d[D_APAIR + i*2 + 1]
264 if af==2 { mods[n*2]=0; mods[n*2+1]=vl; n=n+1 }
265 if af==3 { mods[n*2]=1; mods[n*2+1]=vl; n=n+1 }
266 i=i+1
267 }
268 return n
269}
270func d2_maxhp(d: *i64) -> i64 {
271 let base: i64 = rs_derived_hp(D2_CON, d[D_LVL], D2_HPB, D2_HPC, D2_HPL)
272 let am: *i64 = sys_mmap(16*8) as *i64
273 let an: i64 = d2_amods(d, am)
274 return rs_apply_mods(base, am, an)
275}
276// one combat round. returns handle of a monster KILLED this round (0 none).
277func d2_tick(d: *i64) -> i64 {
278 if d[D_WIN]==1 { return 0 }
279 let a: *i64 = (d as i64 + DG_O_ENT*8) as *i64
280 var killed: i64=0
281 if en_count(a)==0 {
282 // act cleared
283 if d[D_ACT]>=D2_ACTS { d[D_WIN]=1 }
284 if d[D_WIN]==0 {
285 d[D_ACT]=d[D_ACT]+1
286 d2_genact(d)
287 let mh: i64 = d2_maxhp(d)
288 d[D_HP]=mh
289 }
290 d[D_TURN]=d[D_TURN]+1
291 return 0
292 }
293 // target = alive monster NEAREST the act entrance (1,1), tie -> lowest dense index
294 var best: i64=0
295 var bestd: i64=999999
296 var k: i64=0
297 while k<en_count(a) {
298 let h: i64 = en_nth(a,k)
299 let pos: i64 = en_get(a,h,2)
300 let mx: i64 = pos % D2_W
301 let my: i64 = pos / D2_W
302 var dx: i64 = mx-1
303 if dx<0 { dx=0-dx }
304 var dy: i64 = my-1
305 if dy<0 { dy=0-dy }
306 let dist: i64 = dx+dy
307 if dist<bestd { bestd=dist; best=h }
308 k=k+1
309 }
310 // ---- CLICK-TO-MOVE THROUGH THE CERTIFIED PART (bit 7, 2026-08-23): the player WALKS to the
311 // chosen target via pf_astar on the live act grid, arriving adjacent, before any strike lands.
312 // Every step is validated IN-LOOP (4-adjacency + floor); any violation increments D_PATHBAD,
313 // which the pathfind tooth requires to be ZERO across the whole campaign.
314 let wgrid: *i64 = (d as i64 + DG_O_GRID*8) as *i64
315 let tpos2: i64 = en_get(a,best,2)
316 let ptx: i64 = tpos2 % D2_W
317 let pty: i64 = tpos2 / D2_W
318 var pdx: i64 = d[D_PX]-ptx
319 if pdx<0 { pdx=0-pdx }
320 var pdy: i64 = d[D_PY]-pty
321 if pdy<0 { pdy=0-pdy }
322 if pdx+pdy>1 {
323 let wpg: *i64 = (d as i64 + DG_O_PG*8) as *i64
324 let wpf: *i64 = (d as i64 + DG_O_PF2*8) as *i64
325 let wpc: *i64 = (d as i64 + DG_O_PCAME*8) as *i64
326 let wpo: *i64 = (d as i64 + DG_O_POPEN*8) as *i64
327 let wpz: *i64 = (d as i64 + DG_O_PCLOSED*8) as *i64
328 let wpp: *i64 = (d as i64 + DG_O_PPATH*8) as *i64
329 let plen: i64 = pf_astar(wgrid, D2_W, D2_H, d[D_PX], d[D_PY], ptx, pty, wpg, wpf, wpc, wpo, wpz, wpp)
330 if plen>=1 {
331 var pi: i64=1
332 while pi<=plen {
333 let c0: i64 = wpp[pi-1]
334 let c1: i64 = wpp[pi]
335 let x0: i64 = c0 % D2_W
336 let y0: i64 = c0 / D2_W
337 let x1: i64 = c1 % D2_W
338 let y1: i64 = c1 / D2_W
339 var ad: i64 = x1-x0
340 if ad<0 { ad=0-ad }
341 var ad2: i64 = y1-y0
342 if ad2<0 { ad2=0-ad2 }
343 if ad+ad2!=1 { d[D_PATHBAD]=d[D_PATHBAD]+1 }
344 if wgrid[c1]!=0 { d[D_PATHBAD]=d[D_PATHBAD]+1 }
345 pi=pi+1
346 }
347 let stopc: i64 = wpp[plen-1]
348 d[D_PX]=stopc % D2_W
349 d[D_PY]=stopc / D2_W
350 d[D_PSTEPS]=d[D_PSTEPS]+(plen-1)
351 d[D_WALKS]=d[D_WALKS]+1
352 }
353 if plen<1 { d[D_PATHBAD]=d[D_PATHBAD]+1 }
354 }
355 // player strikes: damage through the ORDER-INDEPENDENT modifier pipeline
356 let wm: *i64 = sys_mmap(16*8) as *i64
357 let wn2: i64 = d2_wmods(d, wm)
358 let dmg: i64 = rs_apply_mods(D2_BDMG + d[D_LVL], wm, wn2)
359 let thp: i64 = en_get(a,best,0) - dmg
360 if thp>0 { en_set(a,best,0,thp) }
361 if thp<=0 {
362 let reward: i64 = en_get(a,best,1)
363 let mpos: i64 = en_get(a,best,2)
364 en_destroy(a,best)
365 killed=best
366 d[D_KILLS]=d[D_KILLS]+1
367 d[D_XP]=d[D_XP]+reward
368 let nl: i64 = rs_level_for_xp(d[D_XP], D2_XB, D2_XQ)
369 if nl>d[D_LVL] {
370 d[D_LVL]=nl
371 let mh2: i64 = d2_maxhp(d)
372 d[D_HP]=mh2
373 }
374 // ---- THE LOOT WIRING (flagship): every kill rolls an item; position feeds the seed ----
375 let tw: *i64 = sys_mmap(8*8) as *i64
376 let ta: *i64 = sys_mmap(8*8) as *i64
377 let aw: *i64 = sys_mmap(8*8) as *i64
378 let alo: *i64 = sys_mmap(8*8) as *i64
379 let ahi: *i64 = sys_mmap(8*8) as *i64
380 d2_tables(tw,ta,aw,alo,ahi)
381 let oaff: *i64 = sys_mmap(8*8) as *i64
382 let oval: *i64 = sys_mmap(8*8) as *i64
383 let onum: *i64 = sys_mmap(8) as *i64
384 let seed: i64 = d[D_WS]*1000003 + d[D_KILLS]*8009 + mpos*127
385 let tier: i64 = lt_roll(seed, tw, ta, D2_NTIER, aw, alo, ahi, D2_NAFF, oaff, oval, onum)
386 if tier>=0 {
387 d[D_DROPS]=d[D_DROPS]+1
388 if tier==0 { d[D_T0]=d[D_T0]+1 }
389 if tier==1 { d[D_T1]=d[D_T1]+1 }
390 if tier==2 { d[D_T2]=d[D_T2]+1 }
391 if tier==3 { d[D_T3]=d[D_T3]+1 }
392 // audit the item: no duplicate affixes, values in declared range (counters, checked by teeth)
393 let got: i64 = onum[0]
394 var x: i64=0
395 while x<got {
396 var y: i64=x+1
397 while y<got {
398 if oaff[x]==oaff[y] { d[D_DUPAFF]=d[D_DUPAFF]+1 }
399 y=y+1
400 }
401 let av: i64 = oval[x]
402 let ai: i64 = oaff[x]
403 if av<alo[ai] { d[D_AFFBAD]=d[D_AFFBAD]+1 }
404 if av>ahi[ai] { d[D_AFFBAD]=d[D_AFFBAD]+1 }
405 x=x+1
406 }
407 // order-independence audit ON THE DROP: map every affix to a stat mod (dmg OR hp pool),
408 // and whenever an item carries 2+ mods, prove fwd-apply == rev-apply right here in the loop.
409 let am2: *i64 = sys_mmap(16*8) as *i64
410 var an2: i64=0
411 var q2: i64=0
412 while q2<got {
413 let af2: i64 = oaff[q2]
414 let vl2: i64 = oval[q2]
415 if af2==0 { am2[an2*2]=0; am2[an2*2+1]=vl2; an2=an2+1 }
416 if af2==1 { am2[an2*2]=1; am2[an2*2+1]=vl2; an2=an2+1 }
417 if af2==2 { am2[an2*2]=0; am2[an2*2+1]=vl2; an2=an2+1 }
418 if af2==3 { am2[an2*2]=1; am2[an2*2+1]=vl2; an2=an2+1 }
419 q2=q2+1
420 }
421 if an2>=2 {
422 let fw2: i64 = rs_apply_mods(100, am2, an2)
423 let rv2: *i64 = sys_mmap(16*8) as *i64
424 var r2: i64=0
425 while r2<an2 {
426 rv2[r2*2] = am2[(an2-1-r2)*2]
427 rv2[r2*2+1] = am2[(an2-1-r2)*2+1]
428 r2=r2+1
429 }
430 let rw2: i64 = rs_apply_mods(100, rv2, an2)
431 d[D_ORDCHK]=d[D_ORDCHK]+1
432 if fw2!=rw2 { d[D_ORDBAD]=d[D_ORDBAD]+1 }
433 }
434 // equip policy THROUGH THE MENU (bit 18): even drops weapons, odd armor; higher tier
435 // replaces. The policy rides menu ORDER (item 0 = the policy action: equip when strictly
436 // higher tier, else keep) and the RETURNED id drives the mutation -- causal, and the full
437 // wrap on every drop exercises gh_menu_move's ring arithmetic. Decisions unchanged
438 // => every banked checksum must hold (the golden-ck acceptance for this wire).
439 let slot: i64 = d[D_DROPS]%2
440 let hud: *i64 = (d as i64 + DG_O_HUD*8) as *i64
441 var curt: i64 = d[D_AT]
442 if slot==0 { curt = d[D_WT] }
443 var pol: i64 = 2
444 if tier>curt { pol = 1 }
445 var alt: i64 = 1
446 if pol==1 { alt = 2 }
447 // ---- CONFIRM THROUGH THE CERTIFIED INPUT PART (bit 17, F1102, 2026-08-23): the menu
448 // decision is only reached when a REAL pressed EDGE of the confirm action arrives via
449 // ia_bind/ia_key/ia_frame. Per-drop the arena is fresh and the press is scripted, so
450 // save/load transparency and determinism hold by construction; a control run with the
451 // script DISABLED (D_INSCRIPT=0) can never equip -- input is CAUSAL, not decoration.
452 var dec: i64 = 2
453 if d[D_INSCRIPT]==1 {
454 let iap: *i64 = sys_mmap(ia_words()*8) as *i64
455 ia_init(iap)
456 ia_bind(iap, 65, IA_A)
457 ia_key(iap, 65, 1)
458 let edges: i64 = ia_frame(iap)
459 if (edges/IA_A)%2==1 {
460 d[D_INEV]=d[D_INEV]+1
461 dec = wh_menu_pick2(hud, pol, tier, alt, curt) // MIGRATED to nx_wire_harness
462 }
463 }
464 if dec==1 { if slot==0 {
465 d[D_WT]=tier
466 d[D_WNA]=got
467 var w2: i64=0
468 while w2<6 { d[D_WPAIR+w2*2]=0; d[D_WPAIR+w2*2+1]=0; w2=w2+1 }
469 w2=0
470 while w2<got { d[D_WPAIR+w2*2]=oaff[w2]; d[D_WPAIR+w2*2+1]=oval[w2]; w2=w2+1 }
471 d[D_EQUIPS]=d[D_EQUIPS]+1
472 } }
473 if dec==1 { if slot==1 {
474 d[D_AT]=tier
475 d[D_ANA]=got
476 var w3: i64=0
477 while w3<6 { d[D_APAIR+w3*2]=0; d[D_APAIR+w3*2+1]=0; w3=w3+1 }
478 w3=0
479 while w3<got { d[D_APAIR+w3*2]=oaff[w3]; d[D_APAIR+w3*2+1]=oval[w3]; w3=w3+1 }
480 d[D_EQUIPS]=d[D_EQUIPS]+1
481 } }
482 }
483 }
484 // up to D2_STRIKERS monsters strike back
485 var struck: i64=0
486 var k2: i64=0
487 while k2<en_count(a) {
488 if struck<D2_STRIKERS {
489 d[D_HP]=d[D_HP]-(2+d[D_ACT])
490 struck=struck+1
491 }
492 k2=k2+1
493 }
494 d[D_TURN]=d[D_TURN]+1
495 return killed
496}
497// render-2d (bit 0): the live campaign as a 2D raster frame -- PURE function of game state via the
498// certified nx_game_raster part. Grid floor/wall cells, monsters as hp-shaded discs at their REAL
499// entity positions, act/kills status bars. 20x10 cells at 16px + 20px strip = 320x180.
500const R2_CELL: i64 = 16
501const R2_W: i64 = 320
502const R2_H: i64 = 180
503func d2_render(d: *i64, fb: *i64) -> i64 {
504 let grid: *i64 = (d as i64 + DG_O_GRID*8) as *i64
505 let a: *i64 = (d as i64 + DG_O_ENT*8) as *i64
506 gr_clear(fb, R2_W, R2_H, gr_pack(18, 14, 22))
507 var cy: i64 = 0
508 while cy < D2_H {
509 var cx: i64 = 0
510 while cx < D2_W {
511 if grid[cy*D2_W+cx] == 0 {
512 gr_rect(fb, R2_W, R2_H, cx*R2_CELL+1, cy*R2_CELL+1, cx*R2_CELL+R2_CELL-2, cy*R2_CELL+R2_CELL-2, gr_pack(70, 60, 50))
513 }
514 cx = cx + 1
515 }
516 cy = cy + 1
517 }
518 var k: i64 = 0
519 while k < en_count(a) {
520 let h: i64 = en_nth(a, k)
521 let pos: i64 = en_get(a, h, 2)
522 let mx: i64 = pos % D2_W
523 let my: i64 = pos / D2_W
524 var hpc: i64 = en_get(a, h, 0) * 12
525 if hpc > 255 { hpc = 255 }
526 gr_disc(fb, R2_W, R2_H, mx*R2_CELL+8, my*R2_CELL+8, 6, gr_pack(hpc, 40, 40))
527 k = k + 1
528 }
529 gr_rect(fb, R2_W, R2_H, 0, 162, 4 + d[D_ACT]*30, 168, gr_pack(90, 140, 240))
530 gr_rect(fb, R2_W, R2_H, 0, 171, 4 + d[D_KILLS]*10, 177, gr_pack(240, 200, 60))
531 return 0
532}
533// MIGRATED to nx_wire_harness (wh_fbck): thin wrapper kept so call sites + the golden-ck proof are
534// unchanged; the checksum body is now the ONE shared definition.
535func d2_fbck(fb: *i64) -> i64 {
536 return wh_fbck(fb, R2_W*R2_H)
537}
538// T11 instrument: replay, rendering per round; chain frame cks. out[0]=changed frames, out[1]=mid-frame
539// fs metrics base (fs written to out[2..7]), returns the chain.
540func d2_rchain(seed: i64, turns: i64, out: *i64) -> i64 {
541 let d: *i64 = sys_mmap(DG_WORDS*8) as *i64
542 d2_new(d, seed)
543 let fb: *i64 = sys_mmap(R2_W*R2_H*8) as *i64
544 var chain: i64 = 1469598103
545 var prev: i64 = 0
546 var moved: i64 = 0
547 var t: i64 = 0
548 while t < turns {
549 d2_tick(d)
550 d2_render(d, fb)
551 let fk: i64 = d2_fbck(fb)
552 if t > 0 { if fk != prev { moved = moved + 1 } }
553 prev = fk
554 chain = (chain*131 + (fk & 0xFFFFFFFF)) & 0x7FFFFFFFFFFFFFFF
555 if t == turns/2 { fs_score_i64(fb, R2_W, R2_H, ((out as i64) + 2*8) as *i64) }
556 t = t + 1
557 }
558 out[0] = moved
559 return chain
560}
561// T10 instrument: replay a real campaign for `turns`, binding the HUD to live state and rendering
562// every round. out[0]=frames changed vs previous, out[1]=final ink px, out[2]=menu selections.
563func d2_hudchain(seed: i64, turns: i64, out: *i64) -> i64 {
564 let d: *i64 = sys_mmap(DG_WORDS*8) as *i64
565 d2_new(d, seed)
566 let font: *u8 = font8x8_table()
567 let labels: *i64 = sys_mmap(8*8) as *i64
568 labels[0]="HP" as i64
569 labels[1]="LVL" as i64
570 labels[2]="ACT" as i64
571 labels[3]="KILLS" as i64
572 labels[4]="TIER" as i64
573 let mlabels: *i64 = sys_mmap(8*8) as *i64
574 mlabels[0]="equip" as i64
575 mlabels[1]="keep" as i64
576 let fb: *u8 = sys_mmap(72000)
577 let hud: *i64 = (d as i64 + DG_O_HUD*8) as *i64
578 var chain: i64 = 1469598103
579 var prev: i64 = 0
580 var moved: i64 = 0
581 var t: i64 = 0
582 while t < turns {
583 d2_tick(d)
584 gh_slot_set(hud, 0, d[D_HP])
585 gh_slot_set(hud, 1, d[D_LVL])
586 gh_slot_set(hud, 2, d[D_ACT])
587 gh_slot_set(hud, 3, d[D_KILLS])
588 gh_slot_set(hud, 4, d[D_WT])
589 var z: i64=0
590 while z<72000 { fb[z]=0 as u8; z=z+1 }
591 gh_render(hud, fb, 200, 120, font, labels, mlabels)
592 let fk: i64 = gh_frame_ck(fb, 200, 120)
593 if t>0 { if fk!=prev { moved=moved+1 } }
594 prev=fk
595 chain = (chain*131 + (fk & 0xFFFFFFFF)) & 0x7FFFFFFFFFFFFFFF
596 t=t+1
597 }
598 out[0]=moved
599 out[1]=gh_ink(fb, 200, 120)
600 out[2]=hud[GH_F_NSEL]
601 return chain
602}
603func d2_run_full(d: *i64) -> i64 {
604 var firstkill: i64=0
605 var go: i64=1
606 while go==1 {
607 if d[D_WIN]==1 { go=0 }
608 if d[D_TURN]>=D2_MAXT { go=0 }
609 if d[D_HP]<=0 { go=0 }
610 if go==1 {
611 let kh: i64 = d2_tick(d)
612 if kh!=0 { if firstkill==0 { firstkill=kh } }
613 }
614 }
615 return firstkill
616}
617func d2_serialize(d: *i64, S: *i64) -> i64 {
618 var i: i64=0
619 while i<D2_HDRN { S[i]=d[i]; i=i+1 }
620 let a: *i64 = (d as i64 + DG_O_ENT*8) as *i64
621 let n: i64 = en_count(a)
622 S[D2_HDRN]=n
623 var z: i64=0
624 while z<D2_CAP*3 { S[D2_HDRN+1+z]=0; z=z+1 }
625 var k: i64=0
626 while k<n {
627 let h: i64 = en_nth(a,k)
628 let b: i64 = D2_HDRN+1+k*3
629 let v0: i64 = en_get(a,h,0)
630 let v1: i64 = en_get(a,h,1)
631 let v2: i64 = en_get(a,h,2)
632 S[b]=v0
633 S[b+1]=v1
634 S[b+2]=v2
635 k=k+1
636 }
637 return D2_NSV
638}
639func d2_restore(d: *i64, S: *i64) -> i64 {
640 var i: i64=0
641 while i<D2_HDRN { d[i]=0; i=i+1 }
642 d[D_WS]=S[D_WS]
643 d[D_ACT]=S[D_ACT]
644 d2_genact(d) // grid: pure fn of (ws,act); entities get overwritten below
645 // full header AFTER genact (genact clobbers D_GENRNG/D_SPAWNED with fresh-act values)
646 i=0
647 while i<D2_HDRN { d[i]=S[i]; i=i+1 }
648 let a: *i64 = (d as i64 + DG_O_ENT*8) as *i64
649 en_init(a, D2_CAP, D2_NCOMP)
650 let n: i64 = S[D2_HDRN]
651 var k: i64=0
652 while k<n {
653 let b: i64 = D2_HDRN+1+k*3
654 let h: i64 = en_spawn(a)
655 en_set(a,h,0,S[b])
656 en_set(a,h,1,S[b+1])
657 en_set(a,h,2,S[b+2])
658 k=k+1
659 }
660 let hud: *i64 = (d as i64 + DG_O_HUD*8) as *i64
661 gh_init(hud, 5) // UI transient: fresh menu machine on restore, game state untouched
662 return 0
663}
664// independent-of-serializer checksum (the T-transparency verifier must not share the save's amnesia)
665func d2_ck(d: *i64) -> i64 {
666 var ck: i64 = 1469598103
667 var i: i64=0
668 while i<D2_HDRN { ck = dckv(ck, d[i]); i=i+1 }
669 let a: *i64 = (d as i64 + DG_O_ENT*8) as *i64
670 let n: i64 = en_count(a)
671 ck = dckv(ck, n)
672 var k: i64=0
673 while k<n {
674 let h: i64 = en_nth(a,k)
675 var c: i64=0
676 while c<3 {
677 let v: i64 = en_get(a,h,c)
678 ck = dckv(ck, v)
679 c=c+1
680 }
681 k=k+1
682 }
683 return ck
684}
685// the act theme: data-driven song, layered melody+bass, rendered deterministically
686func d2_song(sng: *i64, k: i64, a2: i64, b2: i64, c2: i64) -> i64 {
687 sng[k*3]=a2; sng[k*3+1]=b2; sng[k*3+2]=c2
688 return 0
689}
690func d2_render_theme(smp: *i64, nsamp: i64) -> i64 {
691 var i: i64=0
692 while i<nsamp { smp[i]=0; i=i+1 }
693 let mel: *i64 = sys_mmap(16*3*8) as *i64
694 d2_song(mel,0, 9,3,2)
695 d2_song(mel,1, 0,4,2)
696 d2_song(mel,2, 2,4,2)
697 d2_song(mel,3, 3,4,4)
698 d2_song(mel,4, 2,4,2)
699 d2_song(mel,5, 0,4,2)
700 d2_song(mel,6, 9,3,4)
701 d2_song(mel,7, 0-1,0,2)
702 d2_song(mel,8, 7,3,2)
703 d2_song(mel,9, 9,3,2)
704 d2_song(mel,10, 0,4,4)
705 d2_song(mel,11, 9,3,2)
706 d2_song(mel,12, 7,3,2)
707 d2_song(mel,13, 5,3,4)
708 d2_song(mel,14, 0-1,0,2)
709 d2_song(mel,15, 9,2,4)
710 let bas: *i64 = sys_mmap(8*3*8) as *i64
711 d2_song(bas,0, 9,2,8)
712 d2_song(bas,1, 5,2,8)
713 d2_song(bas,2, 7,2,8)
714 d2_song(bas,3, 9,2,8)
715 d2_song(bas,4, 0-1,0,8)
716 d2_song(bas,5, 9,1,8)
717 d2_song(bas,6, 5,2,4)
718 d2_song(bas,7, 9,2,4)
719 let TS: i64 = 1000
720 mus_render(smp, nsamp, mel, 16, 8000, 9000, TS)
721 mus_render(smp, nsamp, bas, 8, 8000, 7000, TS)
722 return nsamp
723}
724
725// T14 helpers: i64 trimesh framebuffer clear / filled census / checksum (same shapes the
726// certified nx_bunny_gate uses on this exact part chain)
727func d_clearfb(fb: *i64, n: i64, c: i64) -> i64 { var i: i64=0; while i<n { fb[i]=c; i=i+1 } return 0 }
728func d_filled(fb: *i64, n: i64, bg: i64) -> i64 { var c: i64=0; var i: i64=0; while i<n { if fb[i]!=bg { c=c+1 } i=i+1 } return c }
729func d_fbck(fb: *i64, n: i64) -> i64 { var ck: i64=1469598103; var i: i64=0; while i<n { ck = dckv(ck, fb[i]); i=i+1 } return ck }
730
731func main() -> i64 {
732 ww("=== nx_wire_diablo2_gate: does the ARPG genre loop run on the certified parts? ===\n\n")
733 var pass: i64=0
734 var checks: i64=0
735 var mask: i64=0
736 let SEED: i64 = 777
737 let d1: *i64 = sys_mmap(DG_WORDS*8) as *i64
738 let d2: *i64 = sys_mmap(DG_WORDS*8) as *i64
739 let S: *i64 = sys_mmap(D2_NSV*8+64) as *i64
740 let S2: *i64 = sys_mmap(D2_NSV*8+64) as *i64
741
742 // ---------- T1 procgen-world (bit 3): act map deterministic + seed-diverse ----------
743 checks=checks+1
744 var t1: i64=0
745 d2_new(d1, SEED)
746 d2_new(d2, SEED)
747 let cka: i64 = d2_ck(d1)
748 let ckb: i64 = d2_ck(d2)
749 d2_new(d2, SEED+1)
750 let ckc: i64 = d2_ck(d2)
751 let grid1: *i64 = (d1 as i64 + DG_O_GRID*8) as *i64
752 let a1: *i64 = (d1 as i64 + DG_O_ENT*8) as *i64
753 var badcell: i64=0
754 var k: i64=0
755 while k<en_count(a1) {
756 let h: i64 = en_nth(a1,k)
757 let pos: i64 = en_get(a1,h,2)
758 if grid1[pos]!=0 { badcell=badcell+1 }
759 k=k+1
760 }
761 if cka==ckb { if cka!=ckc { if badcell==0 { if en_count(a1)==D2_NMON {
762 ww("T1 GREEN procgen: same seed identical (ck "); wn(cka)
763 ww("), seed+1 differs (ck "); wn(ckc); ww("), all "); wn(D2_NMON)
764 ww(" pack monsters on carved floor\n")
765 t1=1; pass=pass+1
766 mask=mask+dbit(3)
767 } } } }
768 if t1==0 {
769 ww("T1 RED procgen: ckA="); wn(cka); ww(" ckB="); wn(ckb); ww(" ckC="); wn(ckc)
770 ww(" badcell="); wn(badcell); ww("\n")
771 }
772
773 // ---------- full deterministic run ----------
774 d2_new(d1, SEED)
775 let fk: i64 = d2_run_full(d1)
776 let a1b: *i64 = (d1 as i64 + DG_O_ENT*8) as *i64
777 let fck: i64 = d2_ck(d1)
778 let runwin: i64 = d1[D_WIN]
779 let runturn: i64 = d1[D_TURN]
780 let runkills: i64 = d1[D_KILLS]
781 let runxp: i64 = d1[D_XP]
782 let runlvl: i64 = d1[D_LVL]
783 let rundrops: i64 = d1[D_DROPS]
784 // captured HERE because T6 reuses the d1 arena for the partial save/load run -- reading
785 // d1[D_PSTEPS] after T6 would compare a 46-turn partial against the full campaign (measured:
786 // exactly that mistake made T12 read 43 vs 54 on its first run)
787 let runpsteps: i64 = d1[D_PSTEPS]
788 ww(" [run] turns="); wn(d1[D_TURN]); ww(" act="); wn(d1[D_ACT]); ww(" win="); wn(d1[D_WIN])
789 ww(" kills="); wn(d1[D_KILLS]); ww(" xp="); wn(d1[D_XP]); ww(" level="); wn(d1[D_LVL])
790 ww(" hp="); wn(d1[D_HP]); ww(" drops="); wn(d1[D_DROPS])
791 ww(" tiers="); wn(d1[D_T0]); ww("/"); wn(d1[D_T1]); ww("/"); wn(d1[D_T2]); ww("/"); wn(d1[D_T3])
792 ww(" equips="); wn(d1[D_EQUIPS]); ww(" ck="); wn(fck); ww("\n")
793
794 // ---------- T2 loot-item-tables (bit 10, FLAGSHIP): kills drop audited items ----------
795 checks=checks+1
796 var t2: i64=0
797 if d1[D_DROPS]==d1[D_KILLS] { if d1[D_DROPS]>=20 {
798 if d1[D_T0]>0 { if d1[D_T1]>0 { if d1[D_T2]>0 { if d1[D_T3]>0 {
799 if d1[D_DUPAFF]==0 { if d1[D_AFFBAD]==0 { if d1[D_EQUIPS]>=1 {
800 ww("T2 GREEN loot: "); wn(d1[D_DROPS]); ww(" drops from "); wn(d1[D_KILLS])
801 ww(" kills, ALL 4 tiers observed ("); wn(d1[D_T0]); ww("/"); wn(d1[D_T1])
802 ww("/"); wn(d1[D_T2]); ww("/"); wn(d1[D_T3])
803 ww("), 0 duplicate affixes, 0 out-of-range values, "); wn(d1[D_EQUIPS])
804 ww(" equips\n")
805 t2=1; pass=pass+1
806 mask=mask+dbit(10)
807 } } }
808 } } } }
809 } }
810 if t2==0 {
811 ww("T2 RED loot: drops="); wn(d1[D_DROPS]); ww(" kills="); wn(d1[D_KILLS])
812 ww(" tiers="); wn(d1[D_T0]); ww("/"); wn(d1[D_T1]); ww("/"); wn(d1[D_T2]); ww("/"); wn(d1[D_T3])
813 ww(" dup="); wn(d1[D_DUPAFF]); ww(" bad="); wn(d1[D_AFFBAD]); ww("\n")
814 }
815
816 // ---------- T3 rpg-stats (bit 9): curve exact + equipped mods ORDER-INDEPENDENT ----------
817 checks=checks+1
818 var t3: i64=0
819 let wantlvl: i64 = rs_level_for_xp(d1[D_XP], D2_XB, D2_XQ)
820 let wm: *i64 = sys_mmap(16*8) as *i64
821 let wnn: i64 = d2_wmods(d1, wm)
822 let fwd: i64 = rs_apply_mods(D2_BDMG + d1[D_LVL], wm, wnn)
823 // reverse the mod list and re-apply: order independence is the part's flagship, proven IN the title
824 let wr: *i64 = sys_mmap(16*8) as *i64
825 var r: i64=0
826 while r<wnn {
827 wr[r*2] = wm[(wnn-1-r)*2]
828 wr[r*2+1] = wm[(wnn-1-r)*2+1]
829 r=r+1
830 }
831 let rev: i64 = rs_apply_mods(D2_BDMG + d1[D_LVL], wr, wnn)
832 if d1[D_XP]>0 { if d1[D_LVL]>1 { if d1[D_LVL]==wantlvl { if fwd==rev { if wnn>=1 {
833 if d1[D_ORDCHK]>=3 { if d1[D_ORDBAD]==0 {
834 ww("T3 GREEN rpgstats: xp "); wn(d1[D_XP]); ww(" -> level "); wn(d1[D_LVL])
835 ww(" EXACT; equipped dmg fwd "); wn(fwd); ww(" == rev "); wn(rev)
836 ww("; ORDER-INDEPENDENCE verified on "); wn(d1[D_ORDCHK])
837 ww(" multi-mod drops in-loop, 0 violations\n")
838 t3=1; pass=pass+1
839 mask=mask+dbit(9)
840 } }
841 } } } } }
842 if t3==0 {
843 ww("T3 RED rpgstats: xp="); wn(d1[D_XP]); ww(" lvl="); wn(d1[D_LVL]); ww(" want="); wn(wantlvl)
844 ww(" fwd="); wn(fwd); ww(" rev="); wn(rev); ww(" nmods="); wn(wnn)
845 ww(" ordchk="); wn(d1[D_ORDCHK]); ww(" ordbad="); wn(d1[D_ORDBAD]); ww("\n")
846 }
847
848 // ---------- T4 entity store (bit 6): stale handle + census ----------
849 checks=checks+1
850 var t4: i64=0
851 var stale: i64=0-1
852 if fk!=0 { stale = en_valid(a1b, fk) }
853 let alive: i64 = en_count(a1b)
854 let census: i64 = d1[D_SPAWNED] - d1[D_KILLS]
855 if fk!=0 { if stale==0 { if alive==census {
856 ww("T4 GREEN entity store: first-killed handle "); wn(fk)
857 ww(" DETECTABLY STALE; census exact: spawned "); wn(d1[D_SPAWNED])
858 ww(" - kills "); wn(d1[D_KILLS]); ww(" = alive "); wn(alive); ww("\n")
859 t4=1; pass=pass+1
860 mask=mask+dbit(6)
861 } } }
862 if t4==0 {
863 ww("T4 RED entity: fk="); wn(fk); ww(" stale="); wn(stale)
864 ww(" alive="); wn(alive); ww(" census="); wn(census); ww("\n")
865 }
866
867 // ---------- T5 audio-sfx-music (bit 16): the act theme renders, bounded + deterministic ----------
868 checks=checks+1
869 var t5: i64=0
870 let NS: i64 = 40000
871 let smp: *i64 = sys_mmap(NS*8+64) as *i64
872 d2_render_theme(smp, NS)
873 var over: i64=0
874 var nonz: i64=0
875 var si: i64=0
876 while si<NS {
877 var v: i64=smp[si]
878 if v<0 { v=0-v }
879 if v>MUS_SAMPMAX { over=over+1 }
880 if v>0 { nonz=nonz+1 }
881 si=si+1
882 }
883 var sck1: i64=1469598103
884 si=0
885 while si<NS { sck1 = dckv(sck1, smp[si]); si=si+1 }
886 let smp2: *i64 = sys_mmap(NS*8+64) as *i64
887 d2_render_theme(smp2, NS)
888 var sck2: i64=1469598103
889 si=0
890 while si<NS { sck2 = dckv(sck2, smp2[si]); si=si+1 }
891 let wbuf: *u8 = sys_mmap(NS*4+128)
892 let wlen: i64 = wav_render_stereo(smp, smp, NS, 8000, wbuf)
893 wav_save("knowledge/nx_wire_diablo2.wav" as *u8, wbuf, wlen)
894 var riff: i64=0
895 if wbuf[0]==(82 as u8) { if wbuf[1]==(73 as u8) { if wbuf[2]==(70 as u8) { if wbuf[3]==(70 as u8) { riff=1 } } } }
896 if nonz>10000 { if over==0 { if sck1==sck2 { if riff==1 { if wlen>100 {
897 ww("T5 GREEN music: act theme (2 layered tracks) "); wn(nonz)
898 ww(" non-zero samples, 0 past the saturating ceiling, byte-identical re-render (ck "); wn(sck1)
899 ww("), real RIFF WAV "); wn(wlen); ww("B -> knowledge/nx_wire_diablo2.wav\n")
900 t5=1; pass=pass+1
901 mask=mask+dbit(16)
902 } } } } }
903 if t5==0 {
904 ww("T5 RED music: nonz="); wn(nonz); ww(" over="); wn(over)
905 ww(" ck1="); wn(sck1); ww(" ck2="); wn(sck2); ww(" riff="); wn(riff); ww(" wlen="); wn(wlen); ww("\n")
906 }
907
908 // ---------- T6 save/load TRANSPARENCY (bit 15) ----------
909 checks=checks+1
910 var t6: i64=0
911 let bank: *i64 = sys_mmap((D2_T2W-D2_T1W+2)*8) as *i64
912 d2_new(d1, SEED)
913 var t: i64=0
914 while t<D2_T1W { d2_tick(d1); t=t+1 }
915 let g1a: *i64 = (d1 as i64 + DG_O_ENT*8) as *i64
916 let nv_alive: i64 = en_count(g1a)
917 let nv_xp: i64 = d1[D_XP]
918 let nv_drops: i64 = d1[D_DROPS]
919 let ckt1: i64 = d2_ck(d1)
920 bank[0]=ckt1
921 t=D2_T1W
922 while t<D2_T2W { d2_tick(d1); t=t+1; let c: i64 = d2_ck(d1); bank[t-D2_T1W]=c }
923 let contwin: i64 = d1[D_WIN]
924 d2_new(d2, SEED)
925 t=0
926 while t<D2_T1W { d2_tick(d2); t=t+1 }
927 d2_serialize(d2,S2)
928 let sr: i64 = gs_save("knowledge/nx_wire_diablo2_mid.sav" as *u8, D2_SCHEMA, S2, D2_NSV, 20260720)
929 var zi: i64=0
930 while zi<DG_WORDS { d2[zi]=0; zi=zi+1 }
931 let Sl: *i64 = sys_mmap(D2_NSV*8+64) as *i64
932 let lr: i64 = gs_load("knowledge/nx_wire_diablo2_mid.sav" as *u8, Sl, D2_NSV, 0 as *i64)
933 d2_restore(d2, Sl)
934 let ckr: i64 = d2_ck(d2)
935 var mismatch: i64=0
936 if ckr!=bank[0] { mismatch=mismatch+1 }
937 t=D2_T1W
938 while t<D2_T2W {
939 d2_tick(d2)
940 t=t+1
941 let c2v: i64 = d2_ck(d2)
942 if c2v!=bank[t-D2_T1W] { mismatch=mismatch+1 }
943 }
944 d2_serialize(d1,S)
945 d2_serialize(d2,S2)
946 var fdiff: i64=0
947 var i2: i64=0
948 while i2<D2_NSV { if S[i2]!=S2[i2] { fdiff=fdiff+1 } i2=i2+1 }
949 if sr>0 { if lr==D2_NSV { if mismatch==0 { if fdiff==0 { if nv_alive>=1 { if nv_xp>0 { if nv_drops>=1 { if contwin==0 {
950 ww("T6 GREEN save/load TRANSPARENT: save turn "); wn(D2_T1W)
951 ww(" -> ZEROED arena -> resume to "); wn(D2_T2W); ww(": all "); wn(D2_T2W-D2_T1W+1)
952 ww(" per-turn checksums identical, 0/"); wn(D2_NSV)
953 ww(" fields differ (world non-trivial: alive="); wn(nv_alive)
954 ww(" xp="); wn(nv_xp); ww(" drops="); wn(nv_drops); ww(")\n")
955 t6=1; pass=pass+1
956 mask=mask+dbit(15)
957 } } } } } } } }
958 if t6==0 {
959 ww("T6 RED transparency: save="); wn(sr); ww(" load="); wn(lr)
960 ww(" mism="); wn(mismatch); ww(" fdiff="); wn(fdiff); ww(" alive="); wn(nv_alive)
961 ww(" xp="); wn(nv_xp); ww(" drops="); wn(nv_drops); ww(" contwin="); wn(contwin); ww("\n")
962 }
963
964 // ---------- T7 corruption refused ----------
965 checks=checks+1
966 var t7: i64=0
967 let lenp: *i64 = sys_mmap(8) as *i64
968 lenp[0]=0
969 let raw: *u8 = sys_read_file("knowledge/nx_wire_diablo2_mid.sav" as *u8, lenp)
970 if (raw as i64)!=0 {
971 let rl: i64 = lenp[0]
972 let flip: i64 = 48+16
973 raw[flip] = (raw[flip] as i64 ^ 255) as u8
974 let cfd: i64 = sys_openat_wr("knowledge/nx_wire_diablo2_corrupt.sav" as *u8, 0x1a4)
975 if cfd>=0 {
976 sys_write(cfd, raw, rl)
977 sys_close(cfd)
978 let Sc: *i64 = sys_mmap(D2_NSV*8+64) as *i64
979 Sc[0]=777777
980 let cr: i64 = gs_load("knowledge/nx_wire_diablo2_corrupt.sav" as *u8, Sc, D2_NSV, 0 as *i64)
981 if cr==(0-6) { if Sc[0]==777777 { t7=1 } }
982 }
983 }
984 if t7==1 {
985 ww("T7 GREEN corruption refused LOUD (rc=-6) and caller state untouched\n")
986 pass=pass+1
987 }
988 if t7==0 { ww("T7 RED corrupt-save handling failed\n") }
989
990 // ---------- T8 determinism ----------
991 checks=checks+1
992 var t8: i64=0
993 d2_new(d2, SEED)
994 d2_run_full(d2)
995 let fck2: i64 = d2_ck(d2)
996 if fck==fck2 { if runwin==d2[D_WIN] {
997 ww("T8 GREEN deterministic: two independent full runs -> identical final checksum "); wn(fck)
998 ww(" at turn "); wn(d2[D_TURN]); ww("\n")
999 t8=1; pass=pass+1
1000 } }
1001 if t8==0 { ww("T8 RED run1 ck="); wn(fck); ww(" run2 ck="); wn(fck2); ww("\n") }
1002
1003 // ---------- T9 anti-vacuity: the ARPG was PLAYED and WON ----------
1004 checks=checks+1
1005 var t9: i64=0
1006 if d2[D_WIN]==1 { if d2[D_TURN]>20 { if d2[D_TURN]<D2_MAXT { if d2[D_KILLS]==D2_ACTS*D2_NMON { if d2[D_HP]>0 {
1007 ww("T9 GREEN the ARPG was PLAYED and WON: "); wn(D2_ACTS); ww(" acts cleared, ")
1008 wn(d2[D_KILLS]); ww(" kills in "); wn(d2[D_TURN]); ww(" rounds, survived at hp "); wn(d2[D_HP]); ww("\n")
1009 t9=1; pass=pass+1
1010 } } } } }
1011 if t9==0 {
1012 ww("T9 RED loop hollow: win="); wn(d2[D_WIN]); ww(" turns="); wn(d2[D_TURN])
1013 ww(" kills="); wn(d2[D_KILLS]); ww(" hp="); wn(d2[D_HP]); ww("\n")
1014 }
1015
1016 // ---------- T10 ui-menus-hud (bit 18): every drop decided through the menu; HUD binds live state ----------
1017 checks=checks+1
1018 let hud2: *i64 = (d2 as i64 + DG_O_HUD*8) as *i64
1019 let menusel: i64 = hud2[GH_F_NSEL]
1020 let o10a: *i64 = sys_mmap(4*8) as *i64
1021 let o10b: *i64 = sys_mmap(4*8) as *i64
1022 let ch10a: i64 = d2_hudchain(SEED, D2_T2W, o10a)
1023 let ch10b: i64 = d2_hudchain(SEED, D2_T2W, o10b)
1024 var t10: i64=0
1025 if ch10a==ch10b { if o10a[0]>=2 { if o10a[1]>=D2_HUDINK { if menusel>=1 { if menusel==d2[D_DROPS] {
1026 ww("T10 GREEN ui-menus-hud: "); wn(menusel); ww(" drops ALL decided through menu selections (nsel==drops), ")
1027 ww("HUD chain deterministic over "); wn(D2_T2W); ww(" rounds ("); wn(o10a[0])
1028 ww(" frame changes, "); wn(o10a[1]); ww(" ink px)\n")
1029 t10=1; pass=pass+1
1030 mask=mask+dbit(18)
1031 } } } } }
1032 if t10==0 {
1033 ww("T10 RED ui-menus-hud: chA="); wn(ch10a); ww(" chB="); wn(ch10b)
1034 ww(" changes="); wn(o10a[0]); ww(" ink="); wn(o10a[1])
1035 ww(" nsel="); wn(menusel); ww(" drops="); wn(d2[D_DROPS]); ww("\n")
1036 }
1037
1038 // ---------- T11 render-2d-raster (bit 0): the campaign renders as a live 2D frame ----------
1039 checks=checks+1
1040 let o11a: *i64 = sys_mmap(8*8) as *i64
1041 let o11b: *i64 = sys_mmap(8*8) as *i64
1042 let ch11a: i64 = d2_rchain(SEED, D2_T2W, o11a)
1043 let ch11b: i64 = d2_rchain(SEED, D2_T2W, o11b)
1044 let fsth11: *i64 = sys_mmap(FS_NMETRIC*8) as *i64
1045 fs_default_th(fsth11)
1046 let fsm11: *i64 = ((o11a as i64) + 2*8) as *i64
1047 var t11: i64=0
1048 if ch11a==ch11b { if o11a[0]>=2 { if fs_verdict(fsm11, fsth11)==1 { t11=1 } } }
1049 if t11==1 {
1050 ww("T11 GREEN render-2d: frame chain deterministic over "); wn(D2_T2W); ww(" rounds, ")
1051 wn(o11a[0]); ww(" frame changes, mid-frame experiential sane (")
1052 wn(fsm11[0]); ww("/"); wn(fsm11[1]); ww("/"); wn(fsm11[2]); ww("/"); wn(fsm11[3]); ww("/"); wn(fsm11[4]); ww(")\n")
1053 pass=pass+1
1054 mask=mask+dbit(0)
1055 }
1056 if t11==0 {
1057 ww("T11 RED render-2d: chA="); wn(ch11a); ww(" chB="); wn(ch11b); ww(" changes="); wn(o11a[0])
1058 ww(" fs="); wn(fsm11[0]); ww("/"); wn(fsm11[1]); ww("/"); wn(fsm11[2]); ww("/"); wn(fsm11[3]); ww("/"); wn(fsm11[4]); ww("\n")
1059 }
1060
1061 // ---------- T12 pathfinding-ai (bit 7): the part drives every approach, validated in-loop ----------
1062 checks=checks+1
1063 var t12: i64=0
1064 if d2[D_WALKS]>=D2_NMON { if d2[D_PSTEPS]>=d2[D_WALKS] { if d2[D_PATHBAD]==0 { if d2[D_PSTEPS]==runpsteps {
1065 ww("T12 GREEN pathfinding: "); wn(d2[D_WALKS]); ww(" click-to-move approaches, ")
1066 wn(d2[D_PSTEPS]); ww(" A* steps walked, every step 4-adjacent floor validated IN-LOOP ")
1067 ww("(0 violations; floors derived: walks >= one act's packs, steps >= walks), identical across independent runs\n")
1068 t12=1; pass=pass+1
1069 mask=mask+dbit(7)
1070 } } } }
1071 if t12==0 {
1072 ww("T12 RED pathfinding: walks="); wn(d2[D_WALKS]); ww(" psteps="); wn(d2[D_PSTEPS])
1073 ww(" pathbad="); wn(d2[D_PATHBAD]); ww(" run1-psteps="); wn(d1[D_PSTEPS]); ww("\n")
1074 }
1075
1076 // ---------- T13 input-realtime (bit 17): equips are CAUSED by edges routed through F1102 ----------
1077 checks=checks+1
1078 let dctl: *i64 = sys_mmap(DG_WORDS*8) as *i64
1079 d2_new(dctl, SEED)
1080 dctl[D_INSCRIPT]=0
1081 d2_run_full(dctl)
1082 let ctlck: i64 = d2_ck(dctl)
1083 var t13: i64=0
1084 if d2[D_INEV]==d2[D_DROPS] { if d2[D_INEV]>=1 { if d2[D_EQUIPS]>=1 { if dctl[D_INEV]==0 { if dctl[D_EQUIPS]==0 { if ctlck!=fck2 {
1085 ww("T13 GREEN input: "); wn(d2[D_INEV]); ww(" confirm edges routed through the F1102 part (one per drop), ")
1086 wn(d2[D_EQUIPS]); ww(" equips all edge-caused; CONTROL run with the script disabled: 0 edges, 0 equips, ")
1087 ww("different campaign (ck "); wn(ctlck); ww(" != "); wn(fck2); ww(") -- input is CAUSAL, not decoration\n")
1088 t13=1; pass=pass+1
1089 mask=mask+dbit(17)
1090 } } } } } }
1091 if t13==0 {
1092 ww("T13 RED input: inev="); wn(d2[D_INEV]); ww(" drops="); wn(d2[D_DROPS])
1093 ww(" equips="); wn(d2[D_EQUIPS]); ww(" ctl-inev="); wn(dctl[D_INEV])
1094 ww(" ctl-equips="); wn(dctl[D_EQUIPS]); ww(" ctlck="); wn(ctlck); ww(" fck2="); wn(fck2); ww("\n")
1095 }
1096
1097 // ---------- T14 asset-pipeline-import (bit 25): the WON campaign's victory screen imports and
1098 // renders the standard-corpus mesh through the certified OBJ chain (nx_objload -> nx_trimesh),
1099 // the exact part nx_bunny_gate certifies: EXACT canonical Stanford counts (35947/69451) prove
1100 // provenance; scale/camera/floor are that gate's own calibration, reused not re-picked. ----------
1101 checks=checks+1
1102 let tw14: i64 = 300
1103 let th14: i64 = 300
1104 let npx14: i64 = tw14*th14
1105 let bg14: i64 = 24 + 26*256 + 34*65536
1106 let fb14: *i64 = sys_mmap(npx14*8) as *i64
1107 let zb14: *i64 = sys_mmap(npx14*8) as *i64
1108 tm_set_spec(0)
1109 tm_set_tex(0)
1110 let ok14: i64 = obj_load("knowledge/stdassets/bunny.obj" as *u8, 1300, 205+200*256+195*65536)
1111 let nv14: i64 = tm_nv()
1112 let nt14: i64 = tm_nt()
1113 d_clearfb(fb14, npx14, bg14)
1114 trimesh_zclear(zb14, npx14)
1115 trimesh_render(fb14, zb14, tw14, th14, 1300, 0-250, 2300, 520, 2)
1116 let fil14: i64 = d_filled(fb14, npx14, bg14)
1117 let rck14: i64 = d_fbck(fb14, npx14)
1118 d_clearfb(fb14, npx14, bg14)
1119 trimesh_zclear(zb14, npx14)
1120 trimesh_render(fb14, zb14, tw14, th14, 1300, 0-250, 2300, 520, 2)
1121 let rck14b: i64 = d_fbck(fb14, npx14)
1122 var t14: i64=0
1123 if d2[D_WIN]==1 { if ok14==1 { if nv14==35947 { if nt14==69451 { if tm_ovf()==0 { if fil14>npx14/12 { if rck14==rck14b {
1124 ww("T14 GREEN asset-import: WON campaign's victory screen renders the imported standard mesh -- ")
1125 ww("EXACT canonical Stanford counts (35947/69451, provenance by the numbers), ")
1126 wn(fil14); ww(" px rasterized (floor npx/12 = the part's own gate calibration), deterministic\n")
1127 t14=1; pass=pass+1
1128 mask=mask+dbit(25)
1129 } } } } } } }
1130 if t14==0 {
1131 ww("T14 RED asset-import: win="); wn(d2[D_WIN]); ww(" ok="); wn(ok14)
1132 ww(" nv="); wn(nv14); ww(" nt="); wn(nt14); ww(" ovf="); wn(tm_ovf())
1133 ww(" filled="); wn(fil14); ww(" ckA="); wn(rck14); ww(" ckB="); wn(rck14b); ww("\n")
1134 }
1135
1136 // ---------- wiring evidence artifact ----------
1137 let art: *i64 = sys_mmap(16*8) as *i64
1138 art[0]=mask
1139 art[1]=fck
1140 art[2]=runturn
1141 art[3]=runkills
1142 art[4]=runxp
1143 art[5]=runlvl
1144 art[6]=rundrops
1145 art[7]=runwin
1146 let aw2: i64 = gs_save("knowledge/nx_wire_diablo2.sav" as *u8, D2_ART_SCHEMA, art, 8, 20260720)
1147 ww("\nwiring artifact knowledge/nx_wire_diablo2.sav bytes="); wn(aw2)
1148 ww(" exercised_mask="); wn(mask); ww(" (bits 0,3,6,7,9,10,15,16,17,18,25 when all their teeth pass)\n")
1149
1150 ww("\n=== nx_wire_diablo2_gate "); wn(pass); ww("/"); wn(checks)
1151 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
1152 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
1153 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
1154 let ctr__dry: *i64 = gv_ctr()
1155 ctr__dry[0] = pass
1156 ctr__dry[1] = checks
1157 let rc__dry: i64 = gv_verdict("WIRE-DIABLO2-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8)
1158 sys_exit(rc__dry)
1159 return rc__dry
1160}