code wiki / (root) / nx_decl_simple_scene.nx

nx_decl_simple_scene.nx source

↩ module page · 163 lines · 6428 B

1// nx_decl_simple_scene.nx -- second declarative #tag-style primitive. 2// 3// license_tier: ORIGINAL 4// 5// One substrate call composes random_environment + camera + lighting 6// into a fully-specified "simple scene" struct. Equivalent of the 7// TypeScript `#simple_scene <modifier>` directive. Validates that 8// the #tag pattern COMPOSES: nx_decl_simple_scene calls 9// nx_decl_random_environment for the env half, then adds camera + 10// light defaults per modifier. 11// 12// Per S-class roadmap §A3 -- second slice toward the user's vision: 13// "define something like #random_environment real and it generates 14// with other things like size or other stuff" 15 16// nx_safety_envelope: 17// intended_use: AUTO_APPLIED -- primitive-specific tuning queued 18// sil_target: SIL1 19// evidence: [bulk_applied_2026-05-16, see-file-comment-for-detail] 20// verdict: NOT_YET_EVALUATED 21 22import "nx_syscalls.nx" 23import "nx_types.nx" 24import "nx_tier.nx" 25import "nx_biome_classifier.nx" 26import "nx_decl_random_environment.nx" 27 28struct NxSimpleScene { 29 seed: nx_int, 30 modifier: nx_int, 31 // Pointer to environment (allocated by alloc helper). 32 env: *NxRandomEnvironment, 33 // Camera (Q14 fixed-point). 34 cam_yaw_q14: nx_int, // 0..2*pi in Q14 (0..102943) 35 cam_pitch_q14: nx_int, // -pi/2..pi/2 in Q14 36 cam_distance_m: nx_int, // meters from origin 37 cam_fov_deg: nx_int, // 0..180 38 // Light. 39 light_kind: nx_int, // sealed enum NX_SS_LIGHT_* 40 light_temp_kelvin: nx_int, // 1500..10000 K 41 light_intensity_q10: nx_int, // 0..1024 42 is_valid: nx_int, 43} 44 45// Light kinds (sealed enum). 46const NX_SS_LIGHT_DAWN: nx_int = 0 // 2800K, warm low sun 47const NX_SS_LIGHT_NOON: nx_int = 1 // 5500K, neutral overhead 48const NX_SS_LIGHT_DUSK: nx_int = 2 // 3200K, warm low sun 49const NX_SS_LIGHT_NIGHT: nx_int = 3 // 4100K, moonlight blue 50const NX_SS_LIGHT_OVERCAST: nx_int = 4 // 6500K, flat diffuse 51const NX_SS_LIGHT_ALIEN: nx_int = 5 // 9000K, sci-fi cool 52const NX_SS_LIGHT_FANTASTICAL: nx_int = 6 // 7500K, magical 53const NX_SS_LIGHT_N: nx_int = 7 54 55func nx_ss_light_is_valid(l: nx_int) -> nx_int { 56 if l < 0 { return 0 } 57 if l >= NX_SS_LIGHT_N { return 0 } 58 return 1 59} 60 61// Elm-style reflection: light kind -> human name. 62func nx_ss_light_name(l: nx_int) -> *u8 { 63 if l == NX_SS_LIGHT_DAWN { return "DAWN" as *u8 } 64 if l == NX_SS_LIGHT_NOON { return "NOON" as *u8 } 65 if l == NX_SS_LIGHT_DUSK { return "DUSK" as *u8 } 66 if l == NX_SS_LIGHT_NIGHT { return "NIGHT" as *u8 } 67 if l == NX_SS_LIGHT_OVERCAST { return "OVERCAST" as *u8 } 68 if l == NX_SS_LIGHT_ALIEN { return "ALIEN" as *u8 } 69 if l == NX_SS_LIGHT_FANTASTICAL { return "FANTASTICAL" as *u8 } 70 return "<invalid light>" as *u8 71} 72 73// Light defaults per (modifier, biome). 74func _ss_default_light(modifier: nx_int, biome: nx_int, seed: nx_int) -> nx_int { 75 if modifier == NX_RE_MODIFIER_SCI_FI { return NX_SS_LIGHT_ALIEN } 76 if modifier == NX_RE_MODIFIER_FANTASY { return NX_SS_LIGHT_FANTASTICAL } 77 // REAL: roll one of the four diurnal kinds from seed. 78 let roll: nx_int = _re_hash_mod(seed, 7, 5) 79 if roll == 0 { return NX_SS_LIGHT_DAWN } 80 if roll == 1 { return NX_SS_LIGHT_NOON } 81 if roll == 2 { return NX_SS_LIGHT_DUSK } 82 if roll == 3 { return NX_SS_LIGHT_NIGHT } 83 return NX_SS_LIGHT_OVERCAST 84} 85 86// Temperature (Kelvin) for a given light kind. Substrate-internal 87// table; mirrors the kind names. 88func _ss_light_kelvin(kind: nx_int) -> nx_int { 89 if kind == NX_SS_LIGHT_DAWN { return 2800 } 90 if kind == NX_SS_LIGHT_NOON { return 5500 } 91 if kind == NX_SS_LIGHT_DUSK { return 3200 } 92 if kind == NX_SS_LIGHT_NIGHT { return 4100 } 93 if kind == NX_SS_LIGHT_OVERCAST { return 6500 } 94 if kind == NX_SS_LIGHT_ALIEN { return 9000 } 95 if kind == NX_SS_LIGHT_FANTASTICAL { return 7500 } 96 return 5500 97} 98 99// Intensity Q10 for kind. 100func _ss_light_intensity_q10(kind: nx_int) -> nx_int { 101 if kind == NX_SS_LIGHT_DAWN { return 384 } // 0.375 102 if kind == NX_SS_LIGHT_NOON { return 1024 } // 1.0 103 if kind == NX_SS_LIGHT_DUSK { return 384 } // 0.375 104 if kind == NX_SS_LIGHT_NIGHT { return 102 } // 0.1 105 if kind == NX_SS_LIGHT_OVERCAST { return 640 } // 0.625 106 if kind == NX_SS_LIGHT_ALIEN { return 768 } 107 if kind == NX_SS_LIGHT_FANTASTICAL { return 896 } 108 return 512 109} 110 111// Default camera per modifier. 112func _ss_default_cam_distance(modifier: nx_int, env_size: nx_int) -> nx_int { 113 // Distance scales with environment size; ~3x tile size for a 114 // medium-far establishing shot. 115 return env_size * 3 116} 117 118func _ss_default_cam_fov(modifier: nx_int) -> nx_int { 119 if modifier == NX_RE_MODIFIER_SCI_FI { return 90 } 120 if modifier == NX_RE_MODIFIER_FANTASY { return 75 } 121 return 60 122} 123 124// Main declarator. Composes random_environment + camera + light. 125func nx_decl_simple_scene(out: *NxSimpleScene, modifier: nx_int, seed: nx_int) -> nx_int { 126 if nx_re_modifier_is_valid(modifier) == 0 { 127 out.is_valid = 0 128 return 0 129 } 130 out.seed = seed 131 out.modifier = modifier 132 133 // Phase 1: allocate + populate environment. 134 let env: *NxRandomEnvironment = nx_re_alloc() 135 nx_decl_random_environment(env, modifier, seed) 136 if env.is_valid == 0 { 137 out.is_valid = 0 138 return 0 139 } 140 out.env = env 141 142 // Phase 2: camera. Yaw is seed-hashed in [0, 2pi) Q14. 143 // 2*pi in Q14 = 102943. Q14 = 16384 per unit. 144 let two_pi_q14: nx_int = 102943 145 out.cam_yaw_q14 = _re_hash_mod(seed, 3, two_pi_q14) 146 out.cam_pitch_q14 = -8192 // -pi/4 Q14 (slight downward tilt) 147 out.cam_distance_m = _ss_default_cam_distance(modifier, env.size_tiles) 148 out.cam_fov_deg = _ss_default_cam_fov(modifier) 149 150 // Phase 3: light. 151 out.light_kind = _ss_default_light(modifier, env.biome, seed) 152 out.light_temp_kelvin = _ss_light_kelvin(out.light_kind) 153 out.light_intensity_q10 = _ss_light_intensity_q10(out.light_kind) 154 155 out.is_valid = 1 156 return 1 157} 158 159func nx_ss_alloc() -> *NxSimpleScene { 160 let raw: *u8 = sys_mmap(256) 161 let s: *NxSimpleScene = raw as *NxSimpleScene 162 return s 163}