nx_indoorgen_lib.nx
buildroot/runtime/nx_indoorgen_lib.nx
about
nx_indoorgen_lib.nx -- GR6 INDOOR ROOMS BY CONSTRAINT SOLVE (the Infinigen 2.0 expansion,
/compare/graphics watch contract ig_room_solve, operator 2026-08-17 "properly emitting in the
infinigen way"). COMPOSES the incumbent solver (nx_part_solver_lib, the Infinigen-Indoors
transfer) -- one solver in the estate; this file only DECLARES rooms and consumes solutions.
Shape: an ARCHETYPE (cottage / hut / stonecot) is data rows here; ig_room_solve(arch,variant,salt)
builds a declarative constraint set in memory (envelope + pairwise noclip + door clearance +
wall-hug bands + mate face rows), runs ps_solve, then QUANTIZES the solved placements to voxel
cells and enforces the pre-declared ACCEPT RULE:
solved AND quantized-disjoint AND door-approach-free AND all-inside.
A set that cannot satisfy is REFUSED (return 0, nothing emitted) -- never overlapped furniture.
Variants differ by hashed initial placements (different local optima of the SAME constraints --
the Infinigen pattern: one program, seeded variation). The world engine consumes only the
emitted DATA TABLE (nx_indoorgen_data.nx, written by the nx_indoorgen CLI): the wasm worlds
never run the solver, so the solver's mmap arena never meets the wasm memory bound.
license_tier: ORIGINAL
dependencies 2 imports · 2 importers
imports: nx_syscalls.nxnx_part_solver_lib.nx
imported by: nx_indoorgen.nxnx_indoorgen_gate.nx
structs
| none |
consts
| 21 | const IG_CELL: i64 = 16 // solver units per voxel cell (extents are half-units) |
| 22 | const IG_NARCH: i64 = 3 |
| 23 | const IG_NVAR: i64 = 4 |
| 24 | const IG_SALTS: i64 = 8 // deterministic re-rolls before a variant is REFUSED (4 was |
| 27 | const IG_MAXF: i64 = 16 // emitted furniture rows cap per (arch,variant) |
| 28 | const IG_CONF_CAP: i64 = 8192 |
| 29 | const IG_NEGCTL: i64 = 99 // the named negative control: a 1x2 room that CANNOT hold a bed |
| 30 | const IG_NOCLIP_GAP: i64 = 16 // one full cell -> quantized cells can touch, never overlap |
| 31 | const IG_HUG_LO: i64 = 24 // wall-hug band: off-center, toward the wall ring |
| 32 | const IG_HUG_HI: i64 = 72 |
| 33 | const IG_MATE_LO: i64 = 16 // mate band: adjacent cells (stool by its table/bed) |
| 34 | const IG_MATE_HI: i64 = 28 |
| 37 | const IGK_PLAIN: i64 = 1 // one cell, one block at floor+1 |
| 38 | const IGK_BED: i64 = 2 // two cells along the facing axis, white bedding blocks |
| 39 | const IGK_HEARTH: i64 = 3 // one cell, stone at floor+1 and an ember glow at floor+2 |
| 42 | const IG_BLK_STONE: i64 = 3 |
| 43 | const IG_BLK_SAND: i64 = 5 |
| 44 | const IG_BLK_WOOD: i64 = 6 |
| 45 | const IG_BLK_SCRUB: i64 = 7 // leaves slot -- reads as thatch on the hut roof |
| 46 | const IG_BLK_BED: i64 = 8 // snow slot -- reads as white bedding indoors |
| 47 | const IG_BLK_EMBER: i64 = 11 // gold slot -- the hearth glow |
| 50 | const IGP_KIND_MASK: i64 = 15 // bits 0-3 |
| 51 | const IGP_BLK_SH: i64 = 4 // bits 4-7 |
| 52 | const IGP_EX_SH: i64 = 8 // bits 8-13 |
| 53 | const IGP_EY_SH: i64 = 14 // bits 14-19 |
| 54 | const IGP_CLR_SH: i64 = 20 // bits 20-26 (door clearance, solver units) |
| 55 | const IGP_HUG_SH: i64 = 27 // bit 27 (wall-hug band) |
| 56 | const IGP_MATE_SH: i64 = 28 // bits 28-30 (mate part index + 1) |
functions
| 63 | func ig_reset() -> i64 |
| 73 | func ig_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } called by 1: igc_puts |
| 75 | func ig_ws(b: *u8, p: i64, s: *u8) -> i64 |
| 81 | func ig_wn(b: *u8, p: i64, v: i64) -> i64 |
| 101 | func ig_hash(a: i64, b2: i64) -> i64 called by 1: ig_room_solve |
| 113 | func ig_dims(arch: i64) -> i64 |
| 120 | func ig_mats(arch: i64) -> i64 |
| 125 | func ig_doorx(arch: i64) -> i64 { return (ig_dims(arch) & 255)/2 } |
| 127 | func ig_nparts(arch: i64) -> i64 called by 1: ig_room_solve |
| 134 | func ig_mkpart(kind: i64, blk: i64, ex: i64, ey: i64, clr: i64, hug: i64, mate: i64) -> i64 called by 1: ig_part |
| 139 | func ig_part(arch: i64, i: i64) -> i64 |
| 161 | func ig_pname(b: *u8, p: i64, i: i64) -> i64 |
| 167 | func ig_ck_accept(rows: *i64, nr: i64, w: i64, d: i64, doorx: i64) -> i64 |
| 193 | func ig_room_solve(arch: i64, variant: i64, salt: i64) -> i64 |
| 344 | func ig_nrows() -> i64 { return IG_NROWS } |
| 345 | func ig_row(i: i64) -> i64 { let r: *i64 = IG_ROWS as *i64; return r[i] } called by 1: main |
| 346 | func ig_why() -> i64 { return IG_LASTWHY } called by 1: main |
| 349 | func ig_solve_salted(arch: i64, variant: i64) -> i64 |
| 360 | func ige_emit(out: *u8) -> i64 |