code wiki / _hdl_build / nx_worldgen_tuner_test.nx

nx_worldgen_tuner_test.nx source

↩ module page · 124 lines · 5765 B

1// nx_worldgen_tuner_test.nx -- KATs for the verdict-targeted tuner 2// machinery (nx_worldgen_tunelib). Gate module: /tmp-only side effects 3// (the real tuner's durable banking is exercised by its live runs, not 4// here -- a gate beat must never mutate team state). 5// Exit 0 = all pass; first failing KAT's number is the exit code. 6// 7// KAT 1 conf parse: ints, negatives, missing-key fallback. 8// KAT 2 refine-axis string parse (the banked verdict's form). 9// KAT 3 axis mapping: every refine axis -> a verdict offset; FLATNESS 10// value inverted (lower flat = higher score). 11// KAT 4 score is lexicographic: one grade step beats any axis value. 12// KAT 5 eval determinism: same (preset, density, knobs) -> identical 13// 12-slot verdicts. 14// KAT 6 the knob does its job: detail_amp 140 raises LOCAL_VARIATION 15// vs detail_amp 0 (same preset/density -- the ADD_DETAIL claim 16// at tuner level). 17// KAT 7 knob banking round-trip: write a /tmp conf, tl_load_knobs reads 18// it back exactly; missing file falls back to preset defaults. 19// license_tier: ORIGINAL 20import "nx_syscalls.nx" 21import "nx_tier.nx" 22import "nx_worldgen_tunelib.nx" 23 24func main() -> i64 { 25 // ---- KAT 1: conf int parse ---- 26 let cb: *u8 = "preset=3\ndensity_q10=1024\nriver_depth=-7\n" as *u8 27 var cn: i64 = 0 28 while cb[cn] != (0 as u8) { cn = cn + 1 } 29 if tl_conf_get(cb, cn, "preset" as *u8, 99) != 3 { return 1 } 30 if tl_conf_get(cb, cn, "density_q10" as *u8, 99) != 1024 { return 1 } 31 if tl_conf_get(cb, cn, "river_depth" as *u8, 99) != 0 - 7 { return 1 } 32 if tl_conf_get(cb, cn, "absent" as *u8, 42) != 42 { return 1 } 33 34 // ---- KAT 2: refine-axis string parse ---- 35 let rb: *u8 = "grade=C\nrefine_axis=MORE_FEATURES\n" as *u8 36 var rn: i64 = 0 37 while rb[rn] != (0 as u8) { rn = rn + 1 } 38 if tl_conf_get_refine(rb, rn, NX_WQG_REFINE_NONE) != NX_WQG_REFINE_MORE_FEATURES { return 2 } 39 let rb2: *u8 = "refine_axis=ADD_DETAIL\n" as *u8 40 var rn2: i64 = 0 41 while rb2[rn2] != (0 as u8) { rn2 = rn2 + 1 } 42 if tl_conf_get_refine(rb2, rn2, NX_WQG_REFINE_NONE) != NX_WQG_REFINE_ADD_DETAIL { return 2 } 43 if tl_conf_get_refine(cb, cn, NX_WQG_REFINE_IMPROVE_READ) != NX_WQG_REFINE_IMPROVE_READ { return 2 } 44 45 // ---- KAT 3: axis mapping + flatness inversion ---- 46 if tl_axis_offset(NX_WQG_REFINE_MORE_FEATURES) != NX_WQG_OFF_EXTREMES { return 3 } 47 if tl_axis_offset(NX_WQG_REFINE_ADD_DETAIL) != NX_WQG_OFF_LOCAL_VAR { return 3 } 48 let v12: *i64 = sys_mmap(8 * 12) as *i64 49 var z: i64 = 0 50 while z < 12 { v12[z] = 0; z = z + 1 } 51 v12[NX_WQG_OFF_FLATNESS_PENALTY] = 4000 52 if tl_axis_value(v12, NX_WQG_REFINE_LESS_FLATNESS) != NX_WQG_Q - 4000 { return 3 } 53 v12[NX_WQG_OFF_EXTREMES] = 7000 54 if tl_axis_value(v12, NX_WQG_REFINE_MORE_FEATURES) != 7000 { return 3 } 55 56 // ---- KAT 4: lexicographic score ---- 57 let a12: *i64 = sys_mmap(8 * 12) as *i64 58 var z2: i64 = 0 59 while z2 < 12 { a12[z2] = 0; z2 = z2 + 1 } 60 a12[NX_WQG_OFF_EXTREMES] = NX_WQG_Q // max axis value, lower grade 61 v12[NX_WQG_OFF_EXTREMES] = 0 // min axis value, higher grade 62 let lo_grade_hi_axis: i64 = tl_score(NX_GRADE_C, a12, NX_WQG_REFINE_MORE_FEATURES) 63 let hi_grade_lo_axis: i64 = tl_score(NX_GRADE_B, v12, NX_WQG_REFINE_MORE_FEATURES) 64 if hi_grade_lo_axis <= lo_grade_hi_axis { return 4 } 65 66 // ---- KAT 5: eval determinism ---- 67 let knobs: *i64 = sys_mmap(TL_K_COUNT * 8) as *i64 68 knobs[TL_K_RIVER_DEPTH] = 120 69 knobs[TL_K_RILL_DEPTH] = 45 70 knobs[TL_K_RILL_RADIUS] = 4 71 knobs[TL_K_DETAIL_AMP] = 0 72 let e1: *i64 = sys_mmap(8 * 12) as *i64 73 let e2: *i64 = sys_mmap(8 * 12) as *i64 74 let g1: i64 = tl_eval(4, 1024, knobs, e1) 75 let g2: i64 = tl_eval(4, 1024, knobs, e2) 76 if g1 != g2 { return 5 } 77 var c: i64 = 0 78 while c < 12 { 79 if e1[c] != e2[c] { return 5 } 80 c = c + 1 81 } 82 83 // ---- KAT 6: detail_amp raises LOCAL_VARIATION ---- 84 knobs[TL_K_DETAIL_AMP] = 140 85 tl_eval(4, 1024, knobs, e2) 86 if e2[NX_WQG_OFF_LOCAL_VAR] <= e1[NX_WQG_OFF_LOCAL_VAR] { return 6 } 87 88 // ---- KAT 7: knob banking round-trip + fallback ---- 89 let kp: *u8 = "/tmp/nishi_worldgen_knobs.kat.conf" as *u8 90 let wfd: i64 = sys_openat_wr(kp, 0x1a4) 91 if wfd < 0 { return 7 } 92 let kc: *u8 = "river_depth=150\nrill_depth=30\nrill_radius=6\ndetail_amp=100\npeaks_extra=2\namp_boost=1228\n" as *u8 93 var kn: i64 = 0 94 while kc[kn] != (0 as u8) { kn = kn + 1 } 95 sys_write(wfd, kc, kn) 96 sys_close(wfd) 97 let lk: *i64 = sys_mmap(TL_K_COUNT * 8) as *i64 98 tl_load_knobs(kp, 4, lk) 99 if lk[TL_K_RIVER_DEPTH] != 150 { return 7 } 100 if lk[TL_K_RILL_DEPTH] != 30 { return 7 } 101 if lk[TL_K_RILL_RADIUS] != 6 { return 7 } 102 if lk[TL_K_DETAIL_AMP] != 100 { return 7 } 103 if lk[TL_K_PEAKS_EXTRA] != 2 { return 7 } 104 if lk[TL_K_AMP_BOOST] != 1228 { return 7 } 105 tl_load_knobs("/tmp/nishi_worldgen_knobs.kat.absent" as *u8, 4, lk) 106 if lk[TL_K_RIVER_DEPTH] != nx_water_default_river_depth(4) { return 7 } 107 if lk[TL_K_RILL_DEPTH] != nx_water_default_rill_depth() { return 7 } 108 if lk[TL_K_DETAIL_AMP] != 0 { return 7 } 109 if lk[TL_K_PEAKS_EXTRA] != 0 { return 7 } 110 if lk[TL_K_AMP_BOOST] != 1024 { return 7 } 111 112 // ---- KAT 8: landmark knobs move EXTREMES (the structural handle) ---- 113 let k8: *i64 = sys_mmap(TL_K_COUNT * 8) as *i64 114 tl_load_knobs("/tmp/nishi_worldgen_knobs.kat.absent" as *u8, 4, k8) 115 let b1: *i64 = sys_mmap(8 * 12) as *i64 116 let b2: *i64 = sys_mmap(8 * 12) as *i64 117 tl_eval(4, 1024, k8, b1) 118 k8[TL_K_PEAKS_EXTRA] = 2 119 k8[TL_K_AMP_BOOST] = 1433 120 tl_eval(4, 1024, k8, b2) 121 if b2[NX_WQG_OFF_EXTREMES] <= b1[NX_WQG_OFF_EXTREMES] { return 8 } 122 123 return 0 124}