nx_forest_layout.nx
buildroot/runtime/nx_forest_layout.nx
about
nx_forest_layout.nx -- specialized forest generator (NOT FBM noise).
First demonstration of the kind-specific-generator cardinal
`feedback-kind-specific-generators-not-broad-noise`. Forests have
INTERNAL LOGIC -- species distribution by biome, age affecting
canopy size, clearings, edge effects -- none of which is FBM noise.
This primitive ships that logic.
Per user 2026-05-15: "what houdini is doing or blender where you
have nodes that are tiny gens of their own... right now our
minecraft clone has no sense of these things... forest rivers wind
erosion water erosion beaches gradients weather hammered lush etc
all shouldnt be broad stroked."
Forest-internal logic in v1:
- Hash-deterministic tree positions inside a region (per-tree x,
y from seed). V2 will compose nx_poisson_disk for guaranteed
spacing.
- Species hash from a per-biome species set (cold biomes get
pine/spruce/dead; temperate get oak/birch/maple; tropical get
palm + jungle species).
- Per-tree height correlated with species (pine tall + thin,
oak short + wide, dead-winter skeletal).
- Canopy radius correlated with height + age.
- Per-voxel material query: WOOD inside trunk cylinder, LEAVES
inside canopy sphere (above 60% of tree height).
FULL CAPABILITY (per feedback-maximum-capability-no-simplification
cardinal, 2026-05-16):
- Poisson-disk tree spacing: nx_forest_layout_generate_poisson
enforces minimum inter-tree distance via greedy rejection
sampling. Honest fallback when budget exhausted.
- Clearing detection: callers pass a list of clearing centres
(cx, cy, radius); trees within any clearing are rejected at
placement time (anti-poisson meadow zones).
- Edge effects: radial density falloff via hash-rejection scaling
with distance to region centre (edge cells are sparser than
centre cells).
- Understory predicate: nx_forest_understory_at returns BUSH /
FERN / AIR for non-trunk cells in the tree zone (modelled as
dependencies 3 imports · 0 importers
imports: nx_syscalls.nxnx_hal.nxnx_tier.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 75 | const NX_MAGIC_8000: i64 = 8000 |
| 76 | const NX_MAGIC_4000: i64 = 4000 |
| 77 | const NX_MAGIC_18000: i64 = 18000 |
| 78 | const NX_MAGIC_10000: i64 = 10000 |
| 79 | const NX_MAGIC_25000: i64 = 25000 |
| 80 | const NX_MAGIC_3500: i64 = 3500 |
| 81 | const NX_MAGIC_12000: i64 = 12000 |
| 82 | const NX_MAGIC_3000: i64 = 3000 |
| 83 | const NX_MAGIC_22000: i64 = 22000 |
| 84 | const NX_MAGIC_7000: i64 = 7000 |
| 85 | const NX_MAGIC_15000: i64 = 15000 |
| 86 | const NX_MAGIC_8500: i64 = 8500 |
| 87 | const NX_MAGIC_14000: i64 = 14000 |
| 88 | const NX_MAGIC_5000: i64 = 5000 |
| 89 | const NX_MAGIC_2654435761: i64 = 2654435761 |
| 90 | const NX_MAGIC_1597334677: i64 = 1597334677 |
| 91 | const NX_MAGIC_9800: i64 = 9800 |
| 94 | const NX_FOREST_Q: nx_int = 16384 |
| 97 | const NX_FOREST_LCG_A: nx_int = 48271 |
| 98 | const NX_FOREST_LCG_M: nx_int = 2147483647 |
| 101 | const NX_FOREST_TREE_STRIDE: nx_int = 8 |
| 104 | const NX_FOREST_OFF_SPECIES: nx_int = 0 |
| 105 | const NX_FOREST_OFF_X: nx_int = 1 |
| 106 | const NX_FOREST_OFF_Y_GROUND: nx_int = 2 // ground level at this tree |
| 107 | const NX_FOREST_OFF_Z: nx_int = 3 |
| 108 | const NX_FOREST_OFF_HEIGHT: nx_int = 4 |
| 109 | const NX_FOREST_OFF_CANOPY_RADIUS: nx_int = 5 |
| 110 | const NX_FOREST_OFF_TRUNK_RADIUS: nx_int = 6 |
| 111 | const NX_FOREST_OFF_AGE: nx_int = 7 // Q14 [0, Q] |
| 115 | const NX_FOREST_TYPE_DENSE: nx_int = 0 // tight spacing, full canopy |
| 116 | const NX_FOREST_TYPE_SPARSE: nx_int = 1 // wide spacing, sun-lit |
| 117 | const NX_FOREST_TYPE_FRAGMENTED: nx_int = 2 // small groves with gaps |
| 118 | const NX_FOREST_TYPE_EDGE: nx_int = 3 // boundary biome transition |
| 119 | const NX_FOREST_TYPE_WINTER_DEAD: nx_int = 4 // skeletal winter (Nordic ref image) |
| 121 | const NX_FOREST_TYPE_COUNT: nx_int = 5 |
| 124 | const NX_TREE_OAK: nx_int = 0 // temperate deciduous, spreading canopy |
| 125 | const NX_TREE_PINE: nx_int = 1 // coniferous, tall + narrow |
| 126 | const NX_TREE_BIRCH: nx_int = 2 // temperate, slim trunk |
| 127 | const NX_TREE_SPRUCE: nx_int = 3 // coniferous, pyramidal |
| 128 | const NX_TREE_WILLOW: nx_int = 4 // wet, drooping canopy |
| 129 | const NX_TREE_MAPLE: nx_int = 5 // temperate, broad-leaf |
| 130 | const NX_TREE_DEAD: nx_int = 6 // skeletal (winter / fire-scarred) |
| 131 | const NX_TREE_PALM: nx_int = 7 // tropical, fan canopy |
| 133 | const NX_TREE_SPECIES_COUNT: nx_int = 8 |
| 234 | const NX_FOREST_RET_AIR: nx_int = 0 |
| 235 | const NX_FOREST_RET_WOOD: nx_int = 6 |
| 236 | const NX_FOREST_RET_LEAVES: nx_int = 7 |
| 237 | const NX_FOREST_RET_FERN: nx_int = 8 |
| 238 | const NX_FOREST_RET_BUSH: nx_int = 9 |
functions
| 136 | func nx_forest_type_is_valid(t: nx_int) -> nx_int |
| 145 | func nx_tree_species_is_valid(s: nx_int) -> nx_int called by 1: main |
| 164 | func _forest_species_params(species: nx_int, out: *i64) |
| 188 | func _forest_species_for_type(forest_type: nx_int, n: nx_int) -> nx_int |
| 216 | func _forest_hash(seed: nx_int, i: nx_int, axis: nx_int) -> nx_int |
| 225 | func _forest_mod(h: nx_int, span: nx_int) -> nx_int |
| 251 | func nx_forest_layout_generate( |
| 333 | func nx_forest_layout_generate_poisson( |
| 472 | func nx_forest_understory_at( |
| 531 | func nx_forest_material_at( called by 1: main |
| 573 | func main() -> i64 |