code wiki / (root) / nx_world_grade.nx

nx_world_grade.nx source

↩ module page · 224 lines · 8518 B

1// nx_world_grade.nx -- GRADE A LIVE nx_wasm_craft WORLD WITH nx_world_quality_grader. 2// 3// The gap this closes, measured 2026-09-01: nx_world_quality_grader.nx had shipped on 4// 2026-05-16 and had NEVER BEEN BUILT, and even once built it takes a heightmap ARRAY in 5// process and has no argv -- so it could not be pointed at any world that actually exists. 6// The published /world/beach page had no referee at all. This organ is the missing arm: it 7// runs the SAME engine source the page wasm is compiled from (nx_wasm_craft as a lib, which 8// nx_world_snap already does natively) and hands the grader the real terrain. 9// 10// NO DUPLICATE RULER IS CREATED HERE. The terrain comes from the engine own mob_ground, the 11// verdict comes from the shipped grader, and this file only composes the two and prints. 12// 13// usage: nx_world_grade <identity_v> <seed> [ticks] 14// identity_v 2 + seed 20260728 IS the served beach: sites/nishifamily/world/beach.html 15// carries const NXV=2 and ex.init_v(BigInt(NXV),BigInt(20260728)). 16// exit: 0 graded | 2 usage 17// 18// SCOPE, DECLARED SO THE NUMBER CANNOT BE OVER-READ: the heightmap axes are measured from 19// the live world; BIOME_COHERENCE and FEATURE_VARIETY are NOT supplied, so the grader 20// abstains on them (score 0, verdict MARGINAL) and the grade therefore CANNOT reach S by 21// construction. That ceiling is printed beside the grade rather than left for the reader to 22// discover. license_tier: ORIGINAL No hw writes (Rule 26). 23import "nx_wasm_craft.nx" 24import "nx_world_quality_grader.nx" 25 26const WGD_PAD: i64 = 4096 // the slack nx_world_snap also leaves past CRAFT_TOTAL 27const WGD_ARGC_MIN: i64 = 3 // program + identity + seed 28const WGD_ARGC_TICKS: i64 = 4 29const WGD_EXIT_USAGE: i64 = 2 30const WGD_NUMBUF: i64 = 32 31const WGD_TICK_MS: i64 = 16 // the engine frame budget nx_world_snap ticks with 32const WGD_ASCII_ZERO: i64 = 48 33const WGD_ASCII_NINE: i64 = 57 34const WGD_ASCII_MINUS: i64 = 45 35const WGD_TEN: i64 = 10 36const WGD_PERMIL: i64 = 1000 37 38func wgd_slen(s: *u8) -> i64 { 39 var i: i64 = 0 40 while s[i] != (0 as u8) { i = i + 1 } 41 return i 42} 43 44func wgd_puts(s: *u8) -> i64 { 45 sys_write(1, s, wgd_slen(s)) 46 return 0 47} 48 49func wgd_putn(v: i64) -> i64 { 50 if v == 0 { 51 sys_write(1, "0" as *u8, 1) 52 return 0 53 } 54 var m: i64 = v 55 if m < 0 { 56 sys_write(1, "-" as *u8, 1) 57 m = 0 - m 58 } 59 let t: *u8 = sys_mmap(WGD_NUMBUF) 60 var k: i64 = 0 61 while m > 0 { 62 t[k] = ((m % WGD_TEN) + WGD_ASCII_ZERO) as u8 63 m = m / WGD_TEN 64 k = k + 1 65 } 66 let o: *u8 = sys_mmap(WGD_NUMBUF) 67 var j: i64 = 0 68 while j < k { 69 o[j] = t[k - 1 - j] 70 j = j + 1 71 } 72 sys_write(1, o, k) 73 sys_munmap(t, WGD_NUMBUF) 74 sys_munmap(o, WGD_NUMBUF) 75 return 0 76} 77 78func wgd_row(label: *u8, val: i64) -> i64 { 79 wgd_puts(label) 80 wgd_putn(val) 81 wgd_puts("\n" as *u8) 82 return 0 83} 84 85// Q14 score rendered in permil beside its raw value, because a reader comparing axes should 86// not have to divide by 16384 in their head to see which one lost. 87func wgd_axis(label: *u8, q: i64) -> i64 { 88 wgd_puts(label) 89 wgd_putn(q) 90 wgd_puts(" q14 permil=" as *u8) 91 wgd_putn((q * WGD_PERMIL) / NX_WQG_Q) 92 if q >= NX_WQG_AXIS_WIN_FLOOR { wgd_puts(" WIN\n" as *u8) } 93 if q < NX_WQG_AXIS_WIN_FLOOR { 94 if q >= NX_WQG_AXIS_MARGINAL_FLOOR { wgd_puts(" MARGINAL\n" as *u8) } 95 if q < NX_WQG_AXIS_MARGINAL_FLOOR { wgd_puts(" LOSS\n" as *u8) } 96 } 97 return 0 98} 99 100func wgd_grade_word(g: i64) -> *u8 { 101 if g == NX_GRADE_F { return "F" as *u8 } 102 if g == NX_GRADE_D { return "D" as *u8 } 103 if g == NX_GRADE_C { return "C" as *u8 } 104 if g == NX_GRADE_B { return "B" as *u8 } 105 if g == NX_GRADE_A { return "A" as *u8 } 106 if g == NX_GRADE_S { return "S" as *u8 } 107 return "UNKNOWN-GRADE" as *u8 108} 109 110func wgd_refine_word(r: i64) -> *u8 { 111 if r == NX_WQG_REFINE_NONE { return "NONE" as *u8 } 112 if r == NX_WQG_REFINE_MORE_RELIEF { return "MORE_RELIEF" as *u8 } 113 if r == NX_WQG_REFINE_MORE_FEATURES { return "MORE_FEATURES" as *u8 } 114 if r == NX_WQG_REFINE_LESS_FLATNESS { return "LESS_FLATNESS" as *u8 } 115 if r == NX_WQG_REFINE_ADD_DETAIL { return "ADD_DETAIL" as *u8 } 116 if r == NX_WQG_REFINE_SMOOTH_NOISE { return "SMOOTH_NOISE" as *u8 } 117 if r == NX_WQG_REFINE_FIX_FRACTAL { return "FIX_FRACTAL" as *u8 } 118 if r == NX_WQG_REFINE_FIX_BIOMES { return "FIX_BIOMES" as *u8 } 119 if r == NX_WQG_REFINE_MORE_VARIETY { return "MORE_VARIETY" as *u8 } 120 if r == NX_WQG_REFINE_IMPROVE_READ { return "IMPROVE_READ" as *u8 } 121 return "UNKNOWN-REFINE" as *u8 122} 123 124func wgd_num(s: *u8) -> i64 { 125 var i: i64 = 0 126 var neg: i64 = 0 127 if s[0] == (WGD_ASCII_MINUS as u8) { 128 neg = 1 129 i = 1 130 } 131 var acc: i64 = 0 132 while s[i] != (0 as u8) { 133 let c: i64 = s[i] as i64 134 if c >= WGD_ASCII_ZERO { 135 if c <= WGD_ASCII_NINE { acc = acc * WGD_TEN + (c - WGD_ASCII_ZERO) } 136 } 137 i = i + 1 138 } 139 if neg == 1 { return 0 - acc } 140 return acc 141} 142 143func main(argc: i64, argv: *i64) -> i64 { 144 if argc < WGD_ARGC_MIN { 145 wgd_puts("usage: nx_world_grade <identity_v> <seed> [ticks]\n" as *u8) 146 wgd_puts(" the served beach is identity 2 seed 20260728\n" as *u8) 147 return WGD_EXIT_USAGE 148 } 149 let v: i64 = wgd_num(argv[1] as *u8) 150 let seed: i64 = wgd_num(argv[2] as *u8) 151 var ticks: i64 = 0 152 if argc >= WGD_ARGC_TICKS { ticks = wgd_num(argv[3] as *u8) } 153 154 wgd_puts("NX-WORLD-GRADE nx_wasm_craft world graded by nx_world_quality_grader\n" as *u8) 155 wgd_row("identity_v=" as *u8, v) 156 wgd_row("seed=" as *u8, seed) 157 wgd_row("ticks=" as *u8, ticks) 158 159 let base: i64 = sys_mmap(CRAFT_TOTAL + WGD_PAD) as i64 160 init_impl_v(base, v, seed) 161 var t: i64 = 0 162 while t < ticks { 163 tick_impl(base, WGD_TICK_MS) 164 t = t + 1 165 } 166 167 // THE HEIGHTMAP IS THE ENGINE OWN ANSWER, NOT A RE-IMPLEMENTATION: mob_ground walks the 168 // column from the sky down and returns the topmost solid block, which is exactly the 169 // surface a player stands on. A column with no solid block at all answers -1; those are 170 // clamped to 0 for the grader AND COUNTED, because an uncounted clamp is a fabricated 171 // measurement and the count is the only thing that says how much of the grid was real. 172 let n: i64 = WX * WZ 173 let hmap: *i64 = (sys_mmap(n * NX_SIZEOF_NX_INT)) as *i64 174 var empty_cols: i64 = 0 175 var z: i64 = 0 176 while z < WZ { 177 var x: i64 = 0 178 while x < WX { 179 var g: i64 = mob_ground(base, x, WY - 1, z) 180 if g < 0 { 181 g = 0 182 empty_cols = empty_cols + 1 183 } 184 hmap[z * WX + x] = g 185 x = x + 1 186 } 187 z = z + 1 188 } 189 190 wgd_row("grid_w=" as *u8, WX) 191 wgd_row("grid_h=" as *u8, WZ) 192 wgd_row("cells=" as *u8, n) 193 wgd_row("max_expected_relief=" as *u8, WY) 194 wgd_row("columns_with_no_solid_block=" as *u8, empty_cols) 195 196 let out: *i64 = (sys_mmap(NX_WQG_OUT_STRIDE * NX_SIZEOF_NX_INT)) as *i64 197 let nullp: *i64 = 0 as *i64 198 nx_world_quality_grade(hmap, WX, WZ, WY, nullp, nullp, 0, out) 199 200 wgd_puts("min_height=" as *u8) 201 wgd_putn(out[NX_WQG_OFF_MIN_HEIGHT]) 202 wgd_puts(" max_height=" as *u8) 203 wgd_putn(out[NX_WQG_OFF_MAX_HEIGHT]) 204 wgd_puts("\n" as *u8) 205 206 wgd_axis("DIVERSITY = " as *u8, out[NX_WQG_OFF_DIVERSITY]) 207 wgd_axis("LOCAL_VARIATION = " as *u8, out[NX_WQG_OFF_LOCAL_VAR]) 208 wgd_axis("EXTREMES = " as *u8, out[NX_WQG_OFF_EXTREMES]) 209 wgd_axis("FLATNESS_PENALTY = " as *u8, out[NX_WQG_OFF_FLATNESS_PENALTY]) 210 wgd_puts(" (FLATNESS is INVERTED: higher means flatter means worse)\n" as *u8) 211 wgd_axis("FRACTAL_DIM = " as *u8, out[NX_WQG_OFF_FRACTAL_DIM]) 212 wgd_axis("READABILITY = " as *u8, out[NX_WQG_OFF_READABILITY]) 213 wgd_puts("BIOME_COHERENCE = NOT SUPPLIED -- the grader abstains (MARGINAL), it does not acquit\n" as *u8) 214 wgd_puts("FEATURE_VARIETY = NOT SUPPLIED -- the grader abstains (MARGINAL), it does not acquit\n" as *u8) 215 wgd_puts("CEILING: with two axes abstaining this world CANNOT reach S; the grade below is bounded above by A\n" as *u8) 216 217 wgd_puts("refine_axis=" as *u8) 218 wgd_puts(wgd_refine_word(out[NX_WQG_OFF_REFINE_AXIS])) 219 wgd_puts("\n" as *u8) 220 wgd_puts("grade=" as *u8) 221 wgd_puts(wgd_grade_word(out[NX_WQG_OFF_GRADE])) 222 wgd_puts("\n" as *u8) 223 return 0 224}