nx_weather_pattern.nx
buildroot/runtime/nx_weather_pattern.nx
about
nx_weather_pattern.nx -- spatial + temporal weather field.
Seventh demonstration of the kind-specific-generator cardinal
`feedback-kind-specific-generators-not-broad-noise`. Weather is
neither static nor noise -- it has REGIONAL COHERENCE (a single
storm cell covers tens of kilometres) and TEMPORAL CYCLES (weeks,
seasons). Pure FBM noise gets neither right.
Weather-internal logic in v1:
- World partitioned into "weather cells" (default 50 km square).
All voxels inside one cell share the same weather kind at a
given moment.
- Time cycles every ~7 game-days: weather changes deterministically
per (cell, week) hash. Storms come and go.
- 8 sealed-enum weather kinds with characteristic parameters
(precipitation, temperature offset, visibility, wind speed,
fog density).
FULL CAPABILITY (per feedback-maximum-capability-no-simplification
cardinal, 2026-05-16):
- Smooth spatial transitions via bilinear-blend across the 4
surrounding cell centers (nx_weather_params_smooth)
- Per-biome weather distribution (nx_weather_kind_at_biome
reweights the kind histogram by biome -- rainforest gets
RAIN more often; desert gets HEATWAVE; arctic gets BLIZZARD)
- Multi-tick weather evolution: 15% ramp-in + 70% steady + 15%
ramp-out within each cycle blends previous, current, next
cycle params (nx_weather_evolution_factor + smooth-params)
- Wind direction vector (Q14 unit vec dx/dy) per cell+cycle,
hashed to one of 16 compass directions; speed from kind params
- Lightning discrete events for STORM/BLIZZARD: position +
timestamp via deterministic per-cycle hash; composable with
nx_world_event
Loss audit: cell-based kind discretisation loses sub-cell weather
VARIETY (acceptable since real weather IS regionally coherent --
you can't have rain and sun side-by-side in the same valley).
PARAMS, by contrast, smooth across cells via bilinear blending so
renderer doesn't get sharp transitions.
dependencies 3 imports · 0 importers
imports: nx_syscalls.nxnx_tier.nxnx_camera_q14.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
| 56 | const NX_MAGIC_2654435761: i64 = 2654435761 |
| 57 | const NX_MAGIC_1597334677: i64 = 1597334677 |
| 58 | const NX_MAGIC_951712399: i64 = 951712399 |
| 59 | const NX_MAGIC_7919: i64 = 7919 |
| 60 | const NX_MAGIC_25000: i64 = 25000 |
| 61 | const NX_MAGIC_49999: i64 = 49999 |
| 62 | const NX_MAGIC_5000: i64 = 5000 |
| 65 | const NX_WP_Q: nx_int = 16384 |
| 68 | const NX_WP_LCG_A: nx_int = 48271 |
| 69 | const NX_WP_LCG_M: nx_int = 2147483647 |
| 74 | const NX_WP_DEFAULT_CELL_SIZE_Q14: nx_int = 50000 |
| 79 | const NX_WP_DEFAULT_CYCLE_Q14_DAYS: nx_int = 7 |
| 82 | const NX_WEATHER_CLEAR: nx_int = 0 // sunny, no precip |
| 83 | const NX_WEATHER_OVERCAST: nx_int = 1 // cloudy, no precip |
| 84 | const NX_WEATHER_RAIN: nx_int = 2 // moderate liquid precipitation |
| 85 | const NX_WEATHER_SNOW: nx_int = 3 // moderate frozen precipitation |
| 86 | const NX_WEATHER_FOG: nx_int = 4 // low visibility, no precip |
| 87 | const NX_WEATHER_STORM: nx_int = 5 // heavy rain + wind + lightning |
| 88 | const NX_WEATHER_HEATWAVE: nx_int = 6 // clear + extreme temperature |
| 89 | const NX_WEATHER_BLIZZARD: nx_int = 7 // heavy snow + extreme wind + low vis |
| 91 | const NX_WEATHER_KIND_COUNT: nx_int = 8 |
| 95 | const NX_WP_PARAM_PRECIP: nx_int = 0 // Q14 [0, Q]: 0 = dry, Q = monsoon |
| 96 | const NX_WP_PARAM_TEMP_OFFSET: nx_int = 1 // signed Q14 degrees C from baseline |
| 97 | const NX_WP_PARAM_VISIBILITY: nx_int = 2 // Q14 [0, Q]: 0 = none, Q = clear |
| 98 | const NX_WP_PARAM_WIND_SPEED: nx_int = 3 // Q14 [0, Q]: 0 = still, Q = hurricane |
| 99 | const NX_WP_PARAM_FOG_DENSITY: nx_int = 4 // Q14 [0, Q]: 0 = none, Q = pea soup |
| 101 | const NX_WP_PARAM_COUNT: nx_int = 5 |
| 256 | const NX_BIOME_TUNDRA: nx_int = 0 |
| 257 | const NX_BIOME_BOREAL_FOREST: nx_int = 1 |
| 258 | const NX_BIOME_GRASSLAND: nx_int = 4 |
| 259 | const NX_BIOME_TEMPERATE_FOREST: nx_int = 5 |
| 260 | const NX_BIOME_DESERT: nx_int = 8 |
| 261 | const NX_BIOME_TROPICAL_RAINFOREST: nx_int = 11 |
| 262 | const NX_BIOME_SNOW: nx_int = 12 |
| 263 | const NX_BIOME_ICE: nx_int = 13 |
functions
| 104 | func nx_weather_kind_is_valid(k: nx_int) -> nx_int called by 1: main |
| 117 | func _wp_hash(seed: nx_int, a: nx_int, b: nx_int, c: nx_int) -> nx_int |
| 137 | func nx_weather_kind_at( |
| 174 | func nx_weather_params(kind: nx_int, out: *i64) |
| 241 | func nx_weather_at( |
| 275 | func _wp_biome_cumulative(biome: nx_int, slot: nx_int) -> nx_int called by 1: _wp_pick_kind_from_bucket |
| 344 | func _wp_pick_kind_from_bucket(biome: nx_int, bucket: nx_int) -> nx_int |
| 356 | func nx_weather_kind_at_biome( called by 3: nx_weather_wind_atnx_weather_lightning_active_atmain calls 2: _wp_hash_wp_pick_kind_from_bucket |
| 384 | func _wp_evolution_factor(phase_q14: nx_int) -> nx_int called by 1: nx_weather_evolution_factor |
| 404 | func nx_weather_evolution_factor( |
| 425 | func nx_weather_params_smooth( called by 1: main calls 5: nx_weather_evolution_factorsys_mmap_wp_hash_wp_pick_kind_from_bucketnx_weather_params |
| 549 | func nx_weather_wind_at( |
| 595 | func nx_weather_lightning_active_at( |
| 643 | func main() -> i64 |