code wiki / _hdl_build / nx_wire_diablo2_gate.nx
nx_wire_diablo2_gate.nx source
↩ module page · 979 lines · 37853 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"
33
34// ---- world shape (data at the top, rule 11) ----
35const D2_W: i64 = 20
36const D2_H: i64 = 10
37const D2_ACTS: i64 = 3
38const D2_NMON: i64 = 8
39const D2_CAP: i64 = 12
40const D2_NCOMP: i64 = 3 // 0=hp 1=xp_reward 2=packed pos
41const D2_CARVE: i64 = 90
42const D2_MAXT: i64 = 400
43// rpg tuning
44const D2_XB: i64 = 20
45const D2_XQ: i64 = 10
46const D2_HPB: i64 = 20
47const D2_HPC: i64 = 2
48const D2_HPL: i64 = 4
49const D2_CON: i64 = 12
50const D2_BDMG: i64 = 8 // base weapon damage before mods
51const D2_STRIKERS: i64 = 2 // how many monsters strike back per round
52// loot table (DATA)
53const D2_NTIER: i64 = 4 // normal / magic / rare / unique
54const D2_NAFF: i64 = 5 // +dmg / +dmg% / +hp / +hp% / +armor
55// save shape
56const D2_HDRN: i64 = 48
57const D2_NSV: i64 = 85 // 48 hdr + 1 n + 12*3 monsters
58const D2_SCHEMA: i64 = 7308
59const D2_ART_SCHEMA: i64 = 7318
60// transparency window (full run wins ~turn 60-90; window must sit fully before the win)
61const D2_T1W: i64 = 22
62const D2_T2W: i64 = 46
63// game arena offsets (i64 words)
64const DG_O_GRID: i64 = 64 // 200 cells
65const DG_O_CARVE: i64 = 272 // 208
66const DG_O_ENT: i64 = 480 // en_words(12,3)=4+60+36+8=108 pad 112
67const DG_O_HUD: i64 = 640 // nx_gamehud arena (GH_WORDS=64) APPENDED; UI transient, out of the save
68const DG_WORDS: i64 = 704
69const D2_HUDINK: i64 = 50 // min ink px for a non-vacuous HUD frame (T10 guard)
70// header fields
71const D_WS: i64 = 0
72const D_ACT: i64 = 1
73const D_TURN: i64 = 2
74const D_XP: i64 = 3
75const D_LVL: i64 = 4
76const D_HP: i64 = 5
77const D_KILLS: i64 = 6
78const D_DROPS: i64 = 7
79const D_T0: i64 = 8
80const D_T1: i64 = 9
81const D_T2: i64 = 10
82const D_T3: i64 = 11
83const D_WIN: i64 = 12
84const D_SPAWNED: i64 = 13
85const D_EQUIPS: i64 = 14
86const D_GENRNG: i64 = 15
87const D_DUPAFF: i64 = 16 // duplicate-affix violations observed (must stay 0)
88const D_AFFBAD: i64 = 17 // affix value out of declared range (must stay 0)
89const D_WT: i64 = 18 // equipped weapon tier (-1 none)
90const D_WNA: i64 = 19 // weapon affix count
91const D_WPAIR: i64 = 20 // 6 pairs (affix,val) -> 20..31
92const D_AT: i64 = 32
93const D_ANA: i64 = 33
94const D_APAIR: i64 = 34 // 34..45
95const D_ORDCHK: i64 = 46 // multi-mod drops where fwd/rev order equality was verified
96const D_ORDBAD: i64 = 47 // order-dependence violations observed (must stay 0)
97
98func ww(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
99func wn(v: i64) -> i64 {
100 if v==0 { sys_write(1,"0" as *u8,1); return 0 }
101 var m: i64=v; if m<0 { sys_write(1,"-" as *u8,1); m=0-m }
102 let t: *u8=sys_mmap(32); var k: i64=0
103 while m>0 { t[k]=(48+(m%10)) as u8; m=m/10; k=k+1 }
104 let o: *u8=sys_mmap(32); var q: i64=k-1; var i: i64=0
105 while q>=0 { o[i]=t[q]; i=i+1; q=q-1 }
106 sys_write(1,o,i); return 0
107}
108func dbit(i: i64) -> i64 { var v: i64=1; var k: i64=0; while k<i { v=v*2; k=k+1 } return v }
109func drng(d: *i64) -> i64 {
110 var x: i64 = d[D_GENRNG]
111 x = x ^ (x << 13)
112 x = x ^ (x >> 7)
113 x = x ^ (x << 17)
114 d[D_GENRNG] = x
115 if x < 0 { return 0 - x }
116 return x
117}
118func dckv(ck: i64, v0: i64) -> i64 {
119 var v: i64 = v0
120 if v<0 { v = (0-v)*2+1 } else { v = v*2 }
121 return (ck*131 + v) & 0x7FFFFFFFFFFFFFFF
122}
123// loot tables as DATA (rule 11): weights per-mille-ish, affix ranges
124func d2_tables(tw: *i64, ta: *i64, aw: *i64, alo: *i64, ahi: *i64) -> i64 {
125 tw[0]=600; tw[1]=300; tw[2]=80; tw[3]=20
126 ta[0]=0; ta[1]=1; ta[2]=2; ta[3]=3
127 aw[0]=30; aw[1]=25; aw[2]=20; aw[3]=15; aw[4]=10
128 alo[0]=2; ahi[0]=9 // +dmg
129 alo[1]=5; ahi[1]=20 // +dmg%
130 alo[2]=5; ahi[2]=25 // +hp
131 alo[3]=4; ahi[3]=15 // +hp%
132 alo[4]=1; ahi[4]=8 // +armor
133 return 0
134}
135// ---- act map: PURE function of (ws, act); carve + pack spawn (positions drive loot seeds) ----
136func d2_genact(d: *i64) -> i64 {
137 d[D_GENRNG] = d[D_WS]*1000 + d[D_ACT]*7919
138 if d[D_GENRNG]==0 { d[D_GENRNG]=1 }
139 let grid: *i64 = (d as i64 + DG_O_GRID*8) as *i64
140 let carve: *i64 = (d as i64 + DG_O_CARVE*8) as *i64
141 var i: i64=0
142 while i<D2_W*D2_H { grid[i]=1; i=i+1 }
143 var cx: i64=1
144 var cy: i64=1
145 grid[cy*D2_W+cx]=0
146 carve[0]=cy*D2_W+cx
147 var nc: i64=1
148 var steps: i64=0
149 while steps<D2_CARVE {
150 let dd: i64 = drng(d)%4
151 var tx: i64=cx
152 var ty: i64=cy
153 if dd==0 { tx=cx+1 }
154 if dd==1 { tx=cx-1 }
155 if dd==2 { ty=cy+1 }
156 if dd==3 { ty=cy-1 }
157 if tx>=1 { if tx<=D2_W-2 { if ty>=1 { if ty<=D2_H-2 {
158 cx=tx; cy=ty
159 if grid[cy*D2_W+cx]==1 { grid[cy*D2_W+cx]=0; carve[nc]=cy*D2_W+cx; nc=nc+1 }
160 } } } }
161 steps=steps+1
162 }
163 let a: *i64 = (d as i64 + DG_O_ENT*8) as *i64
164 en_init(a, D2_CAP, D2_NCOMP)
165 let act: i64 = d[D_ACT]
166 var m: i64=0
167 while m<D2_NMON {
168 var placed: i64=0
169 var guard: i64=0
170 while placed==0 {
171 guard=guard+1
172 if guard>200 { placed=1 }
173 let pick: i64 = 1 + (drng(d) % (nc-1))
174 let cell: i64 = carve[pick]
175 var clash: i64=0
176 var k: i64=0
177 while k<en_count(a) {
178 let h: i64 = en_nth(a,k)
179 let op: i64 = en_get(a,h,2)
180 if op==cell { clash=1 }
181 k=k+1
182 }
183 if clash==0 { if placed==0 {
184 let h2: i64 = en_spawn(a)
185 if h2!=EN_NULL {
186 let mhp: i64 = 20 + act*10
187 en_set(a,h2,0,mhp)
188 let mxp: i64 = 20*act
189 en_set(a,h2,1,mxp)
190 en_set(a,h2,2,cell)
191 d[D_SPAWNED]=d[D_SPAWNED]+1
192 placed=1
193 }
194 } }
195 }
196 m=m+1
197 }
198 return nc
199}
200func d2_new(d: *i64, ws: i64) -> i64 {
201 var i: i64=0
202 while i<D2_HDRN { d[i]=0; i=i+1 }
203 d[D_WS]=ws
204 d[D_ACT]=1
205 d[D_LVL]=1
206 d[D_WT]=0-1
207 d[D_AT]=0-1
208 let hp0: i64 = rs_derived_hp(D2_CON, 1, D2_HPB, D2_HPC, D2_HPL)
209 d[D_HP]=hp0
210 d2_genact(d)
211 let hud: *i64 = (d as i64 + DG_O_HUD*8) as *i64
212 gh_init(hud, 5)
213 return 0
214}
215// build the weapon-damage mod list from equipped weapon pairs (affix 0 -> +dmg, 1 -> +dmg%)
216func d2_wmods(d: *i64, mods: *i64) -> i64 {
217 var n: i64=0
218 var i: i64=0
219 while i<d[D_WNA] {
220 let af: i64 = d[D_WPAIR + i*2]
221 let vl: i64 = d[D_WPAIR + i*2 + 1]
222 if af==0 { mods[n*2]=0; mods[n*2+1]=vl; n=n+1 }
223 if af==1 { mods[n*2]=1; mods[n*2+1]=vl; n=n+1 }
224 i=i+1
225 }
226 return n
227}
228// armor-hp mod list from equipped armor pairs (affix 2 -> +hp, 3 -> +hp%)
229func d2_amods(d: *i64, mods: *i64) -> i64 {
230 var n: i64=0
231 var i: i64=0
232 while i<d[D_ANA] {
233 let af: i64 = d[D_APAIR + i*2]
234 let vl: i64 = d[D_APAIR + i*2 + 1]
235 if af==2 { mods[n*2]=0; mods[n*2+1]=vl; n=n+1 }
236 if af==3 { mods[n*2]=1; mods[n*2+1]=vl; n=n+1 }
237 i=i+1
238 }
239 return n
240}
241func d2_maxhp(d: *i64) -> i64 {
242 let base: i64 = rs_derived_hp(D2_CON, d[D_LVL], D2_HPB, D2_HPC, D2_HPL)
243 let am: *i64 = sys_mmap(16*8) as *i64
244 let an: i64 = d2_amods(d, am)
245 return rs_apply_mods(base, am, an)
246}
247// one combat round. returns handle of a monster KILLED this round (0 none).
248func d2_tick(d: *i64) -> i64 {
249 if d[D_WIN]==1 { return 0 }
250 let a: *i64 = (d as i64 + DG_O_ENT*8) as *i64
251 var killed: i64=0
252 if en_count(a)==0 {
253 // act cleared
254 if d[D_ACT]>=D2_ACTS { d[D_WIN]=1 }
255 if d[D_WIN]==0 {
256 d[D_ACT]=d[D_ACT]+1
257 d2_genact(d)
258 let mh: i64 = d2_maxhp(d)
259 d[D_HP]=mh
260 }
261 d[D_TURN]=d[D_TURN]+1
262 return 0
263 }
264 // target = alive monster NEAREST the act entrance (1,1), tie -> lowest dense index
265 var best: i64=0
266 var bestd: i64=999999
267 var k: i64=0
268 while k<en_count(a) {
269 let h: i64 = en_nth(a,k)
270 let pos: i64 = en_get(a,h,2)
271 let mx: i64 = pos % D2_W
272 let my: i64 = pos / D2_W
273 var dx: i64 = mx-1
274 if dx<0 { dx=0-dx }
275 var dy: i64 = my-1
276 if dy<0 { dy=0-dy }
277 let dist: i64 = dx+dy
278 if dist<bestd { bestd=dist; best=h }
279 k=k+1
280 }
281 // player strikes: damage through the ORDER-INDEPENDENT modifier pipeline
282 let wm: *i64 = sys_mmap(16*8) as *i64
283 let wn2: i64 = d2_wmods(d, wm)
284 let dmg: i64 = rs_apply_mods(D2_BDMG + d[D_LVL], wm, wn2)
285 let thp: i64 = en_get(a,best,0) - dmg
286 if thp>0 { en_set(a,best,0,thp) }
287 if thp<=0 {
288 let reward: i64 = en_get(a,best,1)
289 let mpos: i64 = en_get(a,best,2)
290 en_destroy(a,best)
291 killed=best
292 d[D_KILLS]=d[D_KILLS]+1
293 d[D_XP]=d[D_XP]+reward
294 let nl: i64 = rs_level_for_xp(d[D_XP], D2_XB, D2_XQ)
295 if nl>d[D_LVL] {
296 d[D_LVL]=nl
297 let mh2: i64 = d2_maxhp(d)
298 d[D_HP]=mh2
299 }
300 // ---- THE LOOT WIRING (flagship): every kill rolls an item; position feeds the seed ----
301 let tw: *i64 = sys_mmap(8*8) as *i64
302 let ta: *i64 = sys_mmap(8*8) as *i64
303 let aw: *i64 = sys_mmap(8*8) as *i64
304 let alo: *i64 = sys_mmap(8*8) as *i64
305 let ahi: *i64 = sys_mmap(8*8) as *i64
306 d2_tables(tw,ta,aw,alo,ahi)
307 let oaff: *i64 = sys_mmap(8*8) as *i64
308 let oval: *i64 = sys_mmap(8*8) as *i64
309 let onum: *i64 = sys_mmap(8) as *i64
310 let seed: i64 = d[D_WS]*1000003 + d[D_KILLS]*8009 + mpos*127
311 let tier: i64 = lt_roll(seed, tw, ta, D2_NTIER, aw, alo, ahi, D2_NAFF, oaff, oval, onum)
312 if tier>=0 {
313 d[D_DROPS]=d[D_DROPS]+1
314 if tier==0 { d[D_T0]=d[D_T0]+1 }
315 if tier==1 { d[D_T1]=d[D_T1]+1 }
316 if tier==2 { d[D_T2]=d[D_T2]+1 }
317 if tier==3 { d[D_T3]=d[D_T3]+1 }
318 // audit the item: no duplicate affixes, values in declared range (counters, checked by teeth)
319 let got: i64 = onum[0]
320 var x: i64=0
321 while x<got {
322 var y: i64=x+1
323 while y<got {
324 if oaff[x]==oaff[y] { d[D_DUPAFF]=d[D_DUPAFF]+1 }
325 y=y+1
326 }
327 let av: i64 = oval[x]
328 let ai: i64 = oaff[x]
329 if av<alo[ai] { d[D_AFFBAD]=d[D_AFFBAD]+1 }
330 if av>ahi[ai] { d[D_AFFBAD]=d[D_AFFBAD]+1 }
331 x=x+1
332 }
333 // order-independence audit ON THE DROP: map every affix to a stat mod (dmg OR hp pool),
334 // and whenever an item carries 2+ mods, prove fwd-apply == rev-apply right here in the loop.
335 let am2: *i64 = sys_mmap(16*8) as *i64
336 var an2: i64=0
337 var q2: i64=0
338 while q2<got {
339 let af2: i64 = oaff[q2]
340 let vl2: i64 = oval[q2]
341 if af2==0 { am2[an2*2]=0; am2[an2*2+1]=vl2; an2=an2+1 }
342 if af2==1 { am2[an2*2]=1; am2[an2*2+1]=vl2; an2=an2+1 }
343 if af2==2 { am2[an2*2]=0; am2[an2*2+1]=vl2; an2=an2+1 }
344 if af2==3 { am2[an2*2]=1; am2[an2*2+1]=vl2; an2=an2+1 }
345 q2=q2+1
346 }
347 if an2>=2 {
348 let fw2: i64 = rs_apply_mods(100, am2, an2)
349 let rv2: *i64 = sys_mmap(16*8) as *i64
350 var r2: i64=0
351 while r2<an2 {
352 rv2[r2*2] = am2[(an2-1-r2)*2]
353 rv2[r2*2+1] = am2[(an2-1-r2)*2+1]
354 r2=r2+1
355 }
356 let rw2: i64 = rs_apply_mods(100, rv2, an2)
357 d[D_ORDCHK]=d[D_ORDCHK]+1
358 if fw2!=rw2 { d[D_ORDBAD]=d[D_ORDBAD]+1 }
359 }
360 // equip policy THROUGH THE MENU (bit 18): even drops weapons, odd armor; higher tier
361 // replaces. The policy rides menu ORDER (item 0 = the policy action: equip when strictly
362 // higher tier, else keep) and the RETURNED id drives the mutation -- causal, and the full
363 // wrap on every drop exercises gh_menu_move's ring arithmetic. Decisions unchanged
364 // => every banked checksum must hold (the golden-ck acceptance for this wire).
365 let slot: i64 = d[D_DROPS]%2
366 let hud: *i64 = (d as i64 + DG_O_HUD*8) as *i64
367 var curt: i64 = d[D_AT]
368 if slot==0 { curt = d[D_WT] }
369 var pol: i64 = 2
370 if tier>curt { pol = 1 }
371 var alt: i64 = 1
372 if pol==1 { alt = 2 }
373 let dec: i64 = wh_menu_pick2(hud, pol, tier, alt, curt) // MIGRATED to nx_wire_harness
374 if dec==1 { if slot==0 {
375 d[D_WT]=tier
376 d[D_WNA]=got
377 var w2: i64=0
378 while w2<6 { d[D_WPAIR+w2*2]=0; d[D_WPAIR+w2*2+1]=0; w2=w2+1 }
379 w2=0
380 while w2<got { d[D_WPAIR+w2*2]=oaff[w2]; d[D_WPAIR+w2*2+1]=oval[w2]; w2=w2+1 }
381 d[D_EQUIPS]=d[D_EQUIPS]+1
382 } }
383 if dec==1 { if slot==1 {
384 d[D_AT]=tier
385 d[D_ANA]=got
386 var w3: i64=0
387 while w3<6 { d[D_APAIR+w3*2]=0; d[D_APAIR+w3*2+1]=0; w3=w3+1 }
388 w3=0
389 while w3<got { d[D_APAIR+w3*2]=oaff[w3]; d[D_APAIR+w3*2+1]=oval[w3]; w3=w3+1 }
390 d[D_EQUIPS]=d[D_EQUIPS]+1
391 } }
392 }
393 }
394 // up to D2_STRIKERS monsters strike back
395 var struck: i64=0
396 var k2: i64=0
397 while k2<en_count(a) {
398 if struck<D2_STRIKERS {
399 d[D_HP]=d[D_HP]-(2+d[D_ACT])
400 struck=struck+1
401 }
402 k2=k2+1
403 }
404 d[D_TURN]=d[D_TURN]+1
405 return killed
406}
407// render-2d (bit 0): the live campaign as a 2D raster frame -- PURE function of game state via the
408// certified nx_game_raster part. Grid floor/wall cells, monsters as hp-shaded discs at their REAL
409// entity positions, act/kills status bars. 20x10 cells at 16px + 20px strip = 320x180.
410const R2_CELL: i64 = 16
411const R2_W: i64 = 320
412const R2_H: i64 = 180
413func d2_render(d: *i64, fb: *i64) -> i64 {
414 let grid: *i64 = (d as i64 + DG_O_GRID*8) as *i64
415 let a: *i64 = (d as i64 + DG_O_ENT*8) as *i64
416 gr_clear(fb, R2_W, R2_H, gr_pack(18, 14, 22))
417 var cy: i64 = 0
418 while cy < D2_H {
419 var cx: i64 = 0
420 while cx < D2_W {
421 if grid[cy*D2_W+cx] == 0 {
422 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))
423 }
424 cx = cx + 1
425 }
426 cy = cy + 1
427 }
428 var k: i64 = 0
429 while k < en_count(a) {
430 let h: i64 = en_nth(a, k)
431 let pos: i64 = en_get(a, h, 2)
432 let mx: i64 = pos % D2_W
433 let my: i64 = pos / D2_W
434 var hpc: i64 = en_get(a, h, 0) * 12
435 if hpc > 255 { hpc = 255 }
436 gr_disc(fb, R2_W, R2_H, mx*R2_CELL+8, my*R2_CELL+8, 6, gr_pack(hpc, 40, 40))
437 k = k + 1
438 }
439 gr_rect(fb, R2_W, R2_H, 0, 162, 4 + d[D_ACT]*30, 168, gr_pack(90, 140, 240))
440 gr_rect(fb, R2_W, R2_H, 0, 171, 4 + d[D_KILLS]*10, 177, gr_pack(240, 200, 60))
441 return 0
442}
443// MIGRATED to nx_wire_harness (wh_fbck): thin wrapper kept so call sites + the golden-ck proof are
444// unchanged; the checksum body is now the ONE shared definition.
445func d2_fbck(fb: *i64) -> i64 {
446 return wh_fbck(fb, R2_W*R2_H)
447}
448// T11 instrument: replay, rendering per round; chain frame cks. out[0]=changed frames, out[1]=mid-frame
449// fs metrics base (fs written to out[2..7]), returns the chain.
450func d2_rchain(seed: i64, turns: i64, out: *i64) -> i64 {
451 let d: *i64 = sys_mmap(DG_WORDS*8) as *i64
452 d2_new(d, seed)
453 let fb: *i64 = sys_mmap(R2_W*R2_H*8) as *i64
454 var chain: i64 = 1469598103
455 var prev: i64 = 0
456 var moved: i64 = 0
457 var t: i64 = 0
458 while t < turns {
459 d2_tick(d)
460 d2_render(d, fb)
461 let fk: i64 = d2_fbck(fb)
462 if t > 0 { if fk != prev { moved = moved + 1 } }
463 prev = fk
464 chain = (chain*131 + (fk & 0xFFFFFFFF)) & 0x7FFFFFFFFFFFFFFF
465 if t == turns/2 { fs_score_i64(fb, R2_W, R2_H, ((out as i64) + 2*8) as *i64) }
466 t = t + 1
467 }
468 out[0] = moved
469 return chain
470}
471// T10 instrument: replay a real campaign for `turns`, binding the HUD to live state and rendering
472// every round. out[0]=frames changed vs previous, out[1]=final ink px, out[2]=menu selections.
473func d2_hudchain(seed: i64, turns: i64, out: *i64) -> i64 {
474 let d: *i64 = sys_mmap(DG_WORDS*8) as *i64
475 d2_new(d, seed)
476 let font: *u8 = font8x8_table()
477 let labels: *i64 = sys_mmap(8*8) as *i64
478 labels[0]="HP" as i64
479 labels[1]="LVL" as i64
480 labels[2]="ACT" as i64
481 labels[3]="KILLS" as i64
482 labels[4]="TIER" as i64
483 let mlabels: *i64 = sys_mmap(8*8) as *i64
484 mlabels[0]="equip" as i64
485 mlabels[1]="keep" as i64
486 let fb: *u8 = sys_mmap(72000)
487 let hud: *i64 = (d as i64 + DG_O_HUD*8) as *i64
488 var chain: i64 = 1469598103
489 var prev: i64 = 0
490 var moved: i64 = 0
491 var t: i64 = 0
492 while t < turns {
493 d2_tick(d)
494 gh_slot_set(hud, 0, d[D_HP])
495 gh_slot_set(hud, 1, d[D_LVL])
496 gh_slot_set(hud, 2, d[D_ACT])
497 gh_slot_set(hud, 3, d[D_KILLS])
498 gh_slot_set(hud, 4, d[D_WT])
499 var z: i64=0
500 while z<72000 { fb[z]=0 as u8; z=z+1 }
501 gh_render(hud, fb, 200, 120, font, labels, mlabels)
502 let fk: i64 = gh_frame_ck(fb, 200, 120)
503 if t>0 { if fk!=prev { moved=moved+1 } }
504 prev=fk
505 chain = (chain*131 + (fk & 0xFFFFFFFF)) & 0x7FFFFFFFFFFFFFFF
506 t=t+1
507 }
508 out[0]=moved
509 out[1]=gh_ink(fb, 200, 120)
510 out[2]=hud[GH_F_NSEL]
511 return chain
512}
513func d2_run_full(d: *i64) -> i64 {
514 var firstkill: i64=0
515 var go: i64=1
516 while go==1 {
517 if d[D_WIN]==1 { go=0 }
518 if d[D_TURN]>=D2_MAXT { go=0 }
519 if d[D_HP]<=0 { go=0 }
520 if go==1 {
521 let kh: i64 = d2_tick(d)
522 if kh!=0 { if firstkill==0 { firstkill=kh } }
523 }
524 }
525 return firstkill
526}
527func d2_serialize(d: *i64, S: *i64) -> i64 {
528 var i: i64=0
529 while i<D2_HDRN { S[i]=d[i]; i=i+1 }
530 let a: *i64 = (d as i64 + DG_O_ENT*8) as *i64
531 let n: i64 = en_count(a)
532 S[D2_HDRN]=n
533 var z: i64=0
534 while z<D2_CAP*3 { S[D2_HDRN+1+z]=0; z=z+1 }
535 var k: i64=0
536 while k<n {
537 let h: i64 = en_nth(a,k)
538 let b: i64 = D2_HDRN+1+k*3
539 let v0: i64 = en_get(a,h,0)
540 let v1: i64 = en_get(a,h,1)
541 let v2: i64 = en_get(a,h,2)
542 S[b]=v0
543 S[b+1]=v1
544 S[b+2]=v2
545 k=k+1
546 }
547 return D2_NSV
548}
549func d2_restore(d: *i64, S: *i64) -> i64 {
550 var i: i64=0
551 while i<D2_HDRN { d[i]=0; i=i+1 }
552 d[D_WS]=S[D_WS]
553 d[D_ACT]=S[D_ACT]
554 d2_genact(d) // grid: pure fn of (ws,act); entities get overwritten below
555 // full header AFTER genact (genact clobbers D_GENRNG/D_SPAWNED with fresh-act values)
556 i=0
557 while i<D2_HDRN { d[i]=S[i]; i=i+1 }
558 let a: *i64 = (d as i64 + DG_O_ENT*8) as *i64
559 en_init(a, D2_CAP, D2_NCOMP)
560 let n: i64 = S[D2_HDRN]
561 var k: i64=0
562 while k<n {
563 let b: i64 = D2_HDRN+1+k*3
564 let h: i64 = en_spawn(a)
565 en_set(a,h,0,S[b])
566 en_set(a,h,1,S[b+1])
567 en_set(a,h,2,S[b+2])
568 k=k+1
569 }
570 let hud: *i64 = (d as i64 + DG_O_HUD*8) as *i64
571 gh_init(hud, 5) // UI transient: fresh menu machine on restore, game state untouched
572 return 0
573}
574// independent-of-serializer checksum (the T-transparency verifier must not share the save's amnesia)
575func d2_ck(d: *i64) -> i64 {
576 var ck: i64 = 1469598103
577 var i: i64=0
578 while i<D2_HDRN { ck = dckv(ck, d[i]); i=i+1 }
579 let a: *i64 = (d as i64 + DG_O_ENT*8) as *i64
580 let n: i64 = en_count(a)
581 ck = dckv(ck, n)
582 var k: i64=0
583 while k<n {
584 let h: i64 = en_nth(a,k)
585 var c: i64=0
586 while c<3 {
587 let v: i64 = en_get(a,h,c)
588 ck = dckv(ck, v)
589 c=c+1
590 }
591 k=k+1
592 }
593 return ck
594}
595// the act theme: data-driven song, layered melody+bass, rendered deterministically
596func d2_song(sng: *i64, k: i64, a2: i64, b2: i64, c2: i64) -> i64 {
597 sng[k*3]=a2; sng[k*3+1]=b2; sng[k*3+2]=c2
598 return 0
599}
600func d2_render_theme(smp: *i64, nsamp: i64) -> i64 {
601 var i: i64=0
602 while i<nsamp { smp[i]=0; i=i+1 }
603 let mel: *i64 = sys_mmap(16*3*8) as *i64
604 d2_song(mel,0, 9,3,2)
605 d2_song(mel,1, 0,4,2)
606 d2_song(mel,2, 2,4,2)
607 d2_song(mel,3, 3,4,4)
608 d2_song(mel,4, 2,4,2)
609 d2_song(mel,5, 0,4,2)
610 d2_song(mel,6, 9,3,4)
611 d2_song(mel,7, 0-1,0,2)
612 d2_song(mel,8, 7,3,2)
613 d2_song(mel,9, 9,3,2)
614 d2_song(mel,10, 0,4,4)
615 d2_song(mel,11, 9,3,2)
616 d2_song(mel,12, 7,3,2)
617 d2_song(mel,13, 5,3,4)
618 d2_song(mel,14, 0-1,0,2)
619 d2_song(mel,15, 9,2,4)
620 let bas: *i64 = sys_mmap(8*3*8) as *i64
621 d2_song(bas,0, 9,2,8)
622 d2_song(bas,1, 5,2,8)
623 d2_song(bas,2, 7,2,8)
624 d2_song(bas,3, 9,2,8)
625 d2_song(bas,4, 0-1,0,8)
626 d2_song(bas,5, 9,1,8)
627 d2_song(bas,6, 5,2,4)
628 d2_song(bas,7, 9,2,4)
629 let TS: i64 = 1000
630 mus_render(smp, nsamp, mel, 16, 8000, 9000, TS)
631 mus_render(smp, nsamp, bas, 8, 8000, 7000, TS)
632 return nsamp
633}
634
635func main() -> i64 {
636 ww("=== nx_wire_diablo2_gate: does the ARPG genre loop run on the certified parts? ===\n\n")
637 var pass: i64=0
638 var checks: i64=0
639 var mask: i64=0
640 let SEED: i64 = 777
641 let d1: *i64 = sys_mmap(DG_WORDS*8) as *i64
642 let d2: *i64 = sys_mmap(DG_WORDS*8) as *i64
643 let S: *i64 = sys_mmap(D2_NSV*8+64) as *i64
644 let S2: *i64 = sys_mmap(D2_NSV*8+64) as *i64
645
646 // ---------- T1 procgen-world (bit 3): act map deterministic + seed-diverse ----------
647 checks=checks+1
648 var t1: i64=0
649 d2_new(d1, SEED)
650 d2_new(d2, SEED)
651 let cka: i64 = d2_ck(d1)
652 let ckb: i64 = d2_ck(d2)
653 d2_new(d2, SEED+1)
654 let ckc: i64 = d2_ck(d2)
655 let grid1: *i64 = (d1 as i64 + DG_O_GRID*8) as *i64
656 let a1: *i64 = (d1 as i64 + DG_O_ENT*8) as *i64
657 var badcell: i64=0
658 var k: i64=0
659 while k<en_count(a1) {
660 let h: i64 = en_nth(a1,k)
661 let pos: i64 = en_get(a1,h,2)
662 if grid1[pos]!=0 { badcell=badcell+1 }
663 k=k+1
664 }
665 if cka==ckb { if cka!=ckc { if badcell==0 { if en_count(a1)==D2_NMON {
666 ww("T1 GREEN procgen: same seed identical (ck "); wn(cka)
667 ww("), seed+1 differs (ck "); wn(ckc); ww("), all "); wn(D2_NMON)
668 ww(" pack monsters on carved floor\n")
669 t1=1; pass=pass+1
670 mask=mask+dbit(3)
671 } } } }
672 if t1==0 {
673 ww("T1 RED procgen: ckA="); wn(cka); ww(" ckB="); wn(ckb); ww(" ckC="); wn(ckc)
674 ww(" badcell="); wn(badcell); ww("\n")
675 }
676
677 // ---------- full deterministic run ----------
678 d2_new(d1, SEED)
679 let fk: i64 = d2_run_full(d1)
680 let a1b: *i64 = (d1 as i64 + DG_O_ENT*8) as *i64
681 let fck: i64 = d2_ck(d1)
682 let runwin: i64 = d1[D_WIN]
683 let runturn: i64 = d1[D_TURN]
684 let runkills: i64 = d1[D_KILLS]
685 let runxp: i64 = d1[D_XP]
686 let runlvl: i64 = d1[D_LVL]
687 let rundrops: i64 = d1[D_DROPS]
688 ww(" [run] turns="); wn(d1[D_TURN]); ww(" act="); wn(d1[D_ACT]); ww(" win="); wn(d1[D_WIN])
689 ww(" kills="); wn(d1[D_KILLS]); ww(" xp="); wn(d1[D_XP]); ww(" level="); wn(d1[D_LVL])
690 ww(" hp="); wn(d1[D_HP]); ww(" drops="); wn(d1[D_DROPS])
691 ww(" tiers="); wn(d1[D_T0]); ww("/"); wn(d1[D_T1]); ww("/"); wn(d1[D_T2]); ww("/"); wn(d1[D_T3])
692 ww(" equips="); wn(d1[D_EQUIPS]); ww(" ck="); wn(fck); ww("\n")
693
694 // ---------- T2 loot-item-tables (bit 10, FLAGSHIP): kills drop audited items ----------
695 checks=checks+1
696 var t2: i64=0
697 if d1[D_DROPS]==d1[D_KILLS] { if d1[D_DROPS]>=20 {
698 if d1[D_T0]>0 { if d1[D_T1]>0 { if d1[D_T2]>0 { if d1[D_T3]>0 {
699 if d1[D_DUPAFF]==0 { if d1[D_AFFBAD]==0 { if d1[D_EQUIPS]>=1 {
700 ww("T2 GREEN loot: "); wn(d1[D_DROPS]); ww(" drops from "); wn(d1[D_KILLS])
701 ww(" kills, ALL 4 tiers observed ("); wn(d1[D_T0]); ww("/"); wn(d1[D_T1])
702 ww("/"); wn(d1[D_T2]); ww("/"); wn(d1[D_T3])
703 ww("), 0 duplicate affixes, 0 out-of-range values, "); wn(d1[D_EQUIPS])
704 ww(" equips\n")
705 t2=1; pass=pass+1
706 mask=mask+dbit(10)
707 } } }
708 } } } }
709 } }
710 if t2==0 {
711 ww("T2 RED loot: drops="); wn(d1[D_DROPS]); ww(" kills="); wn(d1[D_KILLS])
712 ww(" tiers="); wn(d1[D_T0]); ww("/"); wn(d1[D_T1]); ww("/"); wn(d1[D_T2]); ww("/"); wn(d1[D_T3])
713 ww(" dup="); wn(d1[D_DUPAFF]); ww(" bad="); wn(d1[D_AFFBAD]); ww("\n")
714 }
715
716 // ---------- T3 rpg-stats (bit 9): curve exact + equipped mods ORDER-INDEPENDENT ----------
717 checks=checks+1
718 var t3: i64=0
719 let wantlvl: i64 = rs_level_for_xp(d1[D_XP], D2_XB, D2_XQ)
720 let wm: *i64 = sys_mmap(16*8) as *i64
721 let wnn: i64 = d2_wmods(d1, wm)
722 let fwd: i64 = rs_apply_mods(D2_BDMG + d1[D_LVL], wm, wnn)
723 // reverse the mod list and re-apply: order independence is the part's flagship, proven IN the title
724 let wr: *i64 = sys_mmap(16*8) as *i64
725 var r: i64=0
726 while r<wnn {
727 wr[r*2] = wm[(wnn-1-r)*2]
728 wr[r*2+1] = wm[(wnn-1-r)*2+1]
729 r=r+1
730 }
731 let rev: i64 = rs_apply_mods(D2_BDMG + d1[D_LVL], wr, wnn)
732 if d1[D_XP]>0 { if d1[D_LVL]>1 { if d1[D_LVL]==wantlvl { if fwd==rev { if wnn>=1 {
733 if d1[D_ORDCHK]>=3 { if d1[D_ORDBAD]==0 {
734 ww("T3 GREEN rpgstats: xp "); wn(d1[D_XP]); ww(" -> level "); wn(d1[D_LVL])
735 ww(" EXACT; equipped dmg fwd "); wn(fwd); ww(" == rev "); wn(rev)
736 ww("; ORDER-INDEPENDENCE verified on "); wn(d1[D_ORDCHK])
737 ww(" multi-mod drops in-loop, 0 violations\n")
738 t3=1; pass=pass+1
739 mask=mask+dbit(9)
740 } }
741 } } } } }
742 if t3==0 {
743 ww("T3 RED rpgstats: xp="); wn(d1[D_XP]); ww(" lvl="); wn(d1[D_LVL]); ww(" want="); wn(wantlvl)
744 ww(" fwd="); wn(fwd); ww(" rev="); wn(rev); ww(" nmods="); wn(wnn)
745 ww(" ordchk="); wn(d1[D_ORDCHK]); ww(" ordbad="); wn(d1[D_ORDBAD]); ww("\n")
746 }
747
748 // ---------- T4 entity store (bit 6): stale handle + census ----------
749 checks=checks+1
750 var t4: i64=0
751 var stale: i64=0-1
752 if fk!=0 { stale = en_valid(a1b, fk) }
753 let alive: i64 = en_count(a1b)
754 let census: i64 = d1[D_SPAWNED] - d1[D_KILLS]
755 if fk!=0 { if stale==0 { if alive==census {
756 ww("T4 GREEN entity store: first-killed handle "); wn(fk)
757 ww(" DETECTABLY STALE; census exact: spawned "); wn(d1[D_SPAWNED])
758 ww(" - kills "); wn(d1[D_KILLS]); ww(" = alive "); wn(alive); ww("\n")
759 t4=1; pass=pass+1
760 mask=mask+dbit(6)
761 } } }
762 if t4==0 {
763 ww("T4 RED entity: fk="); wn(fk); ww(" stale="); wn(stale)
764 ww(" alive="); wn(alive); ww(" census="); wn(census); ww("\n")
765 }
766
767 // ---------- T5 audio-sfx-music (bit 16): the act theme renders, bounded + deterministic ----------
768 checks=checks+1
769 var t5: i64=0
770 let NS: i64 = 40000
771 let smp: *i64 = sys_mmap(NS*8+64) as *i64
772 d2_render_theme(smp, NS)
773 var over: i64=0
774 var nonz: i64=0
775 var si: i64=0
776 while si<NS {
777 var v: i64=smp[si]
778 if v<0 { v=0-v }
779 if v>MUS_SAMPMAX { over=over+1 }
780 if v>0 { nonz=nonz+1 }
781 si=si+1
782 }
783 var sck1: i64=1469598103
784 si=0
785 while si<NS { sck1 = dckv(sck1, smp[si]); si=si+1 }
786 let smp2: *i64 = sys_mmap(NS*8+64) as *i64
787 d2_render_theme(smp2, NS)
788 var sck2: i64=1469598103
789 si=0
790 while si<NS { sck2 = dckv(sck2, smp2[si]); si=si+1 }
791 let wbuf: *u8 = sys_mmap(NS*4+128)
792 let wlen: i64 = wav_render_stereo(smp, smp, NS, 8000, wbuf)
793 wav_save("knowledge/nx_wire_diablo2.wav" as *u8, wbuf, wlen)
794 var riff: i64=0
795 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 } } } }
796 if nonz>10000 { if over==0 { if sck1==sck2 { if riff==1 { if wlen>100 {
797 ww("T5 GREEN music: act theme (2 layered tracks) "); wn(nonz)
798 ww(" non-zero samples, 0 past the saturating ceiling, byte-identical re-render (ck "); wn(sck1)
799 ww("), real RIFF WAV "); wn(wlen); ww("B -> knowledge/nx_wire_diablo2.wav\n")
800 t5=1; pass=pass+1
801 mask=mask+dbit(16)
802 } } } } }
803 if t5==0 {
804 ww("T5 RED music: nonz="); wn(nonz); ww(" over="); wn(over)
805 ww(" ck1="); wn(sck1); ww(" ck2="); wn(sck2); ww(" riff="); wn(riff); ww(" wlen="); wn(wlen); ww("\n")
806 }
807
808 // ---------- T6 save/load TRANSPARENCY (bit 15) ----------
809 checks=checks+1
810 var t6: i64=0
811 let bank: *i64 = sys_mmap((D2_T2W-D2_T1W+2)*8) as *i64
812 d2_new(d1, SEED)
813 var t: i64=0
814 while t<D2_T1W { d2_tick(d1); t=t+1 }
815 let g1a: *i64 = (d1 as i64 + DG_O_ENT*8) as *i64
816 let nv_alive: i64 = en_count(g1a)
817 let nv_xp: i64 = d1[D_XP]
818 let nv_drops: i64 = d1[D_DROPS]
819 let ckt1: i64 = d2_ck(d1)
820 bank[0]=ckt1
821 t=D2_T1W
822 while t<D2_T2W { d2_tick(d1); t=t+1; let c: i64 = d2_ck(d1); bank[t-D2_T1W]=c }
823 let contwin: i64 = d1[D_WIN]
824 d2_new(d2, SEED)
825 t=0
826 while t<D2_T1W { d2_tick(d2); t=t+1 }
827 d2_serialize(d2,S2)
828 let sr: i64 = gs_save("knowledge/nx_wire_diablo2_mid.sav" as *u8, D2_SCHEMA, S2, D2_NSV, 20260720)
829 var zi: i64=0
830 while zi<DG_WORDS { d2[zi]=0; zi=zi+1 }
831 let Sl: *i64 = sys_mmap(D2_NSV*8+64) as *i64
832 let lr: i64 = gs_load("knowledge/nx_wire_diablo2_mid.sav" as *u8, Sl, D2_NSV, 0 as *i64)
833 d2_restore(d2, Sl)
834 let ckr: i64 = d2_ck(d2)
835 var mismatch: i64=0
836 if ckr!=bank[0] { mismatch=mismatch+1 }
837 t=D2_T1W
838 while t<D2_T2W {
839 d2_tick(d2)
840 t=t+1
841 let c2v: i64 = d2_ck(d2)
842 if c2v!=bank[t-D2_T1W] { mismatch=mismatch+1 }
843 }
844 d2_serialize(d1,S)
845 d2_serialize(d2,S2)
846 var fdiff: i64=0
847 var i2: i64=0
848 while i2<D2_NSV { if S[i2]!=S2[i2] { fdiff=fdiff+1 } i2=i2+1 }
849 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 {
850 ww("T6 GREEN save/load TRANSPARENT: save turn "); wn(D2_T1W)
851 ww(" -> ZEROED arena -> resume to "); wn(D2_T2W); ww(": all "); wn(D2_T2W-D2_T1W+1)
852 ww(" per-turn checksums identical, 0/"); wn(D2_NSV)
853 ww(" fields differ (world non-trivial: alive="); wn(nv_alive)
854 ww(" xp="); wn(nv_xp); ww(" drops="); wn(nv_drops); ww(")\n")
855 t6=1; pass=pass+1
856 mask=mask+dbit(15)
857 } } } } } } } }
858 if t6==0 {
859 ww("T6 RED transparency: save="); wn(sr); ww(" load="); wn(lr)
860 ww(" mism="); wn(mismatch); ww(" fdiff="); wn(fdiff); ww(" alive="); wn(nv_alive)
861 ww(" xp="); wn(nv_xp); ww(" drops="); wn(nv_drops); ww(" contwin="); wn(contwin); ww("\n")
862 }
863
864 // ---------- T7 corruption refused ----------
865 checks=checks+1
866 var t7: i64=0
867 let lenp: *i64 = sys_mmap(8) as *i64
868 lenp[0]=0
869 let raw: *u8 = sys_read_file("knowledge/nx_wire_diablo2_mid.sav" as *u8, lenp)
870 if (raw as i64)!=0 {
871 let rl: i64 = lenp[0]
872 let flip: i64 = 48+16
873 raw[flip] = (raw[flip] as i64 ^ 255) as u8
874 let cfd: i64 = sys_openat_wr("knowledge/nx_wire_diablo2_corrupt.sav" as *u8, 0x1a4)
875 if cfd>=0 {
876 sys_write(cfd, raw, rl)
877 sys_close(cfd)
878 let Sc: *i64 = sys_mmap(D2_NSV*8+64) as *i64
879 Sc[0]=777777
880 let cr: i64 = gs_load("knowledge/nx_wire_diablo2_corrupt.sav" as *u8, Sc, D2_NSV, 0 as *i64)
881 if cr==(0-6) { if Sc[0]==777777 { t7=1 } }
882 }
883 }
884 if t7==1 {
885 ww("T7 GREEN corruption refused LOUD (rc=-6) and caller state untouched\n")
886 pass=pass+1
887 }
888 if t7==0 { ww("T7 RED corrupt-save handling failed\n") }
889
890 // ---------- T8 determinism ----------
891 checks=checks+1
892 var t8: i64=0
893 d2_new(d2, SEED)
894 d2_run_full(d2)
895 let fck2: i64 = d2_ck(d2)
896 if fck==fck2 { if runwin==d2[D_WIN] {
897 ww("T8 GREEN deterministic: two independent full runs -> identical final checksum "); wn(fck)
898 ww(" at turn "); wn(d2[D_TURN]); ww("\n")
899 t8=1; pass=pass+1
900 } }
901 if t8==0 { ww("T8 RED run1 ck="); wn(fck); ww(" run2 ck="); wn(fck2); ww("\n") }
902
903 // ---------- T9 anti-vacuity: the ARPG was PLAYED and WON ----------
904 checks=checks+1
905 var t9: i64=0
906 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 {
907 ww("T9 GREEN the ARPG was PLAYED and WON: "); wn(D2_ACTS); ww(" acts cleared, ")
908 wn(d2[D_KILLS]); ww(" kills in "); wn(d2[D_TURN]); ww(" rounds, survived at hp "); wn(d2[D_HP]); ww("\n")
909 t9=1; pass=pass+1
910 } } } } }
911 if t9==0 {
912 ww("T9 RED loop hollow: win="); wn(d2[D_WIN]); ww(" turns="); wn(d2[D_TURN])
913 ww(" kills="); wn(d2[D_KILLS]); ww(" hp="); wn(d2[D_HP]); ww("\n")
914 }
915
916 // ---------- T10 ui-menus-hud (bit 18): every drop decided through the menu; HUD binds live state ----------
917 checks=checks+1
918 let hud2: *i64 = (d2 as i64 + DG_O_HUD*8) as *i64
919 let menusel: i64 = hud2[GH_F_NSEL]
920 let o10a: *i64 = sys_mmap(4*8) as *i64
921 let o10b: *i64 = sys_mmap(4*8) as *i64
922 let ch10a: i64 = d2_hudchain(SEED, D2_T2W, o10a)
923 let ch10b: i64 = d2_hudchain(SEED, D2_T2W, o10b)
924 var t10: i64=0
925 if ch10a==ch10b { if o10a[0]>=2 { if o10a[1]>=D2_HUDINK { if menusel>=1 { if menusel==d2[D_DROPS] {
926 ww("T10 GREEN ui-menus-hud: "); wn(menusel); ww(" drops ALL decided through menu selections (nsel==drops), ")
927 ww("HUD chain deterministic over "); wn(D2_T2W); ww(" rounds ("); wn(o10a[0])
928 ww(" frame changes, "); wn(o10a[1]); ww(" ink px)\n")
929 t10=1; pass=pass+1
930 mask=mask+dbit(18)
931 } } } } }
932 if t10==0 {
933 ww("T10 RED ui-menus-hud: chA="); wn(ch10a); ww(" chB="); wn(ch10b)
934 ww(" changes="); wn(o10a[0]); ww(" ink="); wn(o10a[1])
935 ww(" nsel="); wn(menusel); ww(" drops="); wn(d2[D_DROPS]); ww("\n")
936 }
937
938 // ---------- T11 render-2d-raster (bit 0): the campaign renders as a live 2D frame ----------
939 checks=checks+1
940 let o11a: *i64 = sys_mmap(8*8) as *i64
941 let o11b: *i64 = sys_mmap(8*8) as *i64
942 let ch11a: i64 = d2_rchain(SEED, D2_T2W, o11a)
943 let ch11b: i64 = d2_rchain(SEED, D2_T2W, o11b)
944 let fsth11: *i64 = sys_mmap(FS_NMETRIC*8) as *i64
945 fs_default_th(fsth11)
946 let fsm11: *i64 = ((o11a as i64) + 2*8) as *i64
947 var t11: i64=0
948 if ch11a==ch11b { if o11a[0]>=2 { if fs_verdict(fsm11, fsth11)==1 { t11=1 } } }
949 if t11==1 {
950 ww("T11 GREEN render-2d: frame chain deterministic over "); wn(D2_T2W); ww(" rounds, ")
951 wn(o11a[0]); ww(" frame changes, mid-frame experiential sane (")
952 wn(fsm11[0]); ww("/"); wn(fsm11[1]); ww("/"); wn(fsm11[2]); ww("/"); wn(fsm11[3]); ww("/"); wn(fsm11[4]); ww(")\n")
953 pass=pass+1
954 mask=mask+dbit(0)
955 }
956 if t11==0 {
957 ww("T11 RED render-2d: chA="); wn(ch11a); ww(" chB="); wn(ch11b); ww(" changes="); wn(o11a[0])
958 ww(" fs="); wn(fsm11[0]); ww("/"); wn(fsm11[1]); ww("/"); wn(fsm11[2]); ww("/"); wn(fsm11[3]); ww("/"); wn(fsm11[4]); ww("\n")
959 }
960
961 // ---------- wiring evidence artifact ----------
962 let art: *i64 = sys_mmap(16*8) as *i64
963 art[0]=mask
964 art[1]=fck
965 art[2]=runturn
966 art[3]=runkills
967 art[4]=runxp
968 art[5]=runlvl
969 art[6]=rundrops
970 art[7]=runwin
971 let aw2: i64 = gs_save("knowledge/nx_wire_diablo2.sav" as *u8, D2_ART_SCHEMA, art, 8, 20260720)
972 ww("\nwiring artifact knowledge/nx_wire_diablo2.sav bytes="); wn(aw2)
973 ww(" exercised_mask="); wn(mask); ww(" (bits 0,3,10,9,6,16,15,18 when all their teeth pass)\n")
974
975 ww("\n=== nx_wire_diablo2_gate "); wn(pass); ww("/"); wn(checks)
976 if pass==checks { ww(" verdict=GREEN ===\n"); return 0 }
977 ww(" RED ===\n")
978 return 1
979}