code wiki / _hdl_build / nx_craft_erosion_shot.nx

nx_craft_erosion_shot.nx

buildroot/runtime/_hdl_build/nx_craft_erosion_shot.nx

22014 B419 linesdepth 6pulls 37 transitivereach 0 importersview sourcekind tooltopic craft
docsdependenciesstructsconstsfunctions

about

nx_craft_erosion_shot.nx -- THE BEFORE/AFTER PICTURE OF EROSION, TAKEN FROM THE WASM A VISITOR LOADS. WHY THIS EXISTS (operator standing rule, 2026-08-25): "if it's not publishing on a live page then it's not truly deployed, as I can't validate." Talus erosion ships in /craft and is proven by NUMBERS -- nx_wasm_craft_vm_gate measures talus 154/256, 509 of 576 lattice heights moved, rugosity 88 -> 75 permil -- and not one of those is a PICTURE. A number the operator cannot see is a claim he has to take on trust, which is the one thing this estate exists to stop doing. * WHY NOT nx_world_snap, THE INCUMBENT CAPTURE INSTRUMENT. Two reasons, and either alone is decisive. (1) IT RENDERS NATIVELY: it imports nx_wasm_craft as a LIB and calls init_impl_v / render_impl in this process's own memory. That is precisely the "a gate that tests a different build than the one that ships is not testing the product" defect nx_wasm_craft_vm_gate exists to correct -- /craft shipped BLACK TWICE while the native gate read 59/59 GREEN both times, because the native build never meets the wasm memory bound at all. A before/after picture drawn by the native twin would prove the twin erodes, not the product. (2) IT CANNOT REACH THE COLUMN ANYWAY: its style poke is bounded 7..58 and its gen-row allowlist is 0..6, 59, 60, 61 -- so spec idx 64, THE EROSION BUDGET, is unreachable from nx_world_snap in BOTH of its lanes. Measured, not assumed. So this organ drives the emitted .wasm through the estate's own nx_wasm_vm, in a linear memory sized to exactly what the module declares -- the same subject, the same bound and the same VM the vm-gate uses. It opts in through the GENP block byte-for-byte the way craft.html's NXGP loop does, so the erosion it photographs arrives by the SHIPPED door and not through a private back channel. The PNG encoder is COMPOSED, never rewritten: nx_png_write_rgb is the estate's one encoder. usage: nx_craft_erosion_shot <outbase> <variant> <seed> [q] [budgetA] [budgetB] [flat] writes <outbase>_off.png (budgetA, default 0) and <outbase>_on.png (budgetB, default 1), same variant + same seed + same camera; the erosion budget is the only difference. q omitted or 0 -> DERIVED (see es_q_mem / es_q_rays). q given -> explicit, still refused if it breaks the module's declared memory. flat=1 -> ALSO zero P_TAMP1 and P_TAMP2 through the same GENP door, i.e. ask for a world with NO RELIEF. THIS IS THE CONTROL THAT MATTERS, and it was earned the hard way: the obvious control (render /beach, which never opts in) was run first and CAME BACK 680 PERMIL DIFFERENT -- so it proved nothing about the pipeline and could not be published. beach's sand is NEAR-flat (P_TAMP1=2, P_TAMP2=1), not flat, and on a two-block relief a one-block shed moves most columns. A flat world has no slope steeper than its own average at all, so the measured talus is zero and the operator turns itself off. Because budgetA and budgetB then describe the SAME world, one such run proves BOTH that the capture is deterministic AND that erosion does nothing without slopes: an image pipeline that painted noise, drifted with wall-clock time, or added an offset would fail it.

dependencies 5 imports · 0 importers

nx_syscalls.nx nx_wasm_vm.nx nx_wasm_craft.nx nx_png_write.nx nx_lineconf_lib.nx nx_craft_erosion_shot.nx

imports: nx_syscalls.nxnx_wasm_vm.nxnx_wasm_craft.nxnx_png_write.nxnx_lineconf_lib.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main es_w sys_write es_slen es_int es_n sys_write ↻ sys_mmap nxa_die sys_write ↻ sys_exit nxa_lock_take nxa_lock_addr sys_write ↻ nxa_lock_give nxa_lock_addr ↻ nxa_report_overrun sys_write ↻ nxa_dump_printable sys_write ↻ nxa_dump_sizes sys_write ↻ sys_munmap sys_mmap ↻ sys_read_file sys_openat_rd sys_lseek sys_mmap ↻ sys_read sys_munmap ↻ sys_close sys_munmap ↻ es_q_mem lcf_int_of sys_mmap ↻ sys_read_file ↻ lcf_int lcf_find es_q_rays es_shoot

structs

none

consts

50const ES_WASM: *u8 = "buildroot/_build/nx_wasm_craft_emit.wasm"
51const ES_CONF: *u8 = "knowledge/craft_erosion_shot.conf"
52const ES_KEY_RAYS: *u8 = "shot-ray-budget"
53const ES_W64: i64 = 8 // bytes in an i64 -- every plane below is made of these
54const ES_RGB: i64 = 3 // bytes per pixel handed to nx_png_write_rgb
55const ES_BYTE: i64 = 256 // one colour channel's modulus
56const ES_PATHCAP: i64 = 512
57const ES_COLCAP: i64 = 4096 // distinct-colour census ceiling. A frame that reaches it is
60const ES_MS_PER_S: i64 = 1000
61const ES_NS_PER_MS: i64 = 1000000
62const ES_PERMIL: i64 = 1000
63const ES_SCRATCH: i64 = 32
64const ES_BOX: i64 = 16
67const ES_GP_MAGIC: i64 = 0
68const ES_GP_N: i64 = 1
69const ES_GP_IDX0: i64 = 2
70const ES_GP_VAL0: i64 = 3
71const ES_GP_STRIDE: i64 = 2 // words per (idx,val) pair
72const ES_GENP_N: i64 = 1 // the erosion pair (P_ERODE, budget) is always written
73const ES_GENP_FLAT: i64 = 3 // ...plus P_TAMP1=0 and P_TAMP2=0 when a FLAT world is asked for
75const ES_O_RW: i64 = 0
76const ES_O_RH: i64 = 1
77const ES_O_INITMS: i64 = 2
78const ES_O_RENDMS: i64 = 3
79const ES_O_FBOFF: i64 = 4
80const ES_O_DISTINCT: i64 = 5
81const ES_O_GENP: i64 = 6 // S_GENP: how many overrides the ENGINE says it applied. World
87const ES_O_CX: i64 = 7
88const ES_O_CY: i64 = 8
89const ES_O_CZ: i64 = 9
90const ES_O_YAW: i64 = 10
91const ES_O_PITCH: i64 = 11
92const ES_OBOX: i64 = 16
93const ES_EXIT_USAGE: i64 = 2
94const ES_EXIT_WASM: i64 = 4
95const ES_EXIT_PNG: i64 = 5
96const ES_EXIT_NOFIT: i64 = 6

functions

98func es_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
called by 1: es_w
99func es_w(s: *u8) -> i64 { sys_write(1, s, es_slen(s)); return 0 }
called by 2: es_reportmain calls 2: sys_writees_slen
100func es_n(v: i64) -> i64
115func es_int(s: *u8) -> i64
called by 1: main
125func es_ms(ts: *i64) -> i64
called by 1: es_shoot calls 1: sys_clock_gettime_mono
130func es_path(dst: *u8, base: *u8, sfx: *u8) -> *u8
called by 1: main
150func es_q_mem(fboff: i64) -> i64
called by 1: main
158func es_q_rays(budget: i64) -> i64
called by 1: main
168func es_genp(mem: *u8, k: i64, idx: i64, val: i64) -> i64
called by 1: es_shoot
188func es_shoot(mod: *WasmMod, v: i64, seed: i64, erode: i64, flat: i64, q: i64, rgb: *u8, ob: *i64, ts: *i64, pin: *i64) -> i64
called by 1: main calls 4: sys_mmapes_genpes_mssys_munmap
267func es_report(tag: *u8, ob: *i64) -> i64
called by 1: main calls 2: es_wes_n
279func main(argc: i64, argv: *i64) -> i64