nx_id_palette.nx source
↩ module page · 87 lines · 4451 B
1// nx_id_palette.nx -- THE CORRELATED IDENTITY PALETTE. /compare/procgen C33, symbol
2// gn_palette_sample. The first consumer of nx_id_param_core, and the direct answer on the
3// GENERATOR side to the operator's "our colour palette is barely used".
4//
5// WHAT WAS THERE BEFORE, MEASURED: nx_breeding carries exactly ONE colour trait, GN_T_HUE, drawn
6// as an independent uniform. nx_skin_ita then maps that single scalar onto a straight L* locus at
7// fixed a* and fixed b*. So a cast of N characters occupies a ONE-DIMENSIONAL, UNCORRELATED colour
8// space: nothing about a character's hair relates to anything about her skin, because there is no
9// hair gene at all -- the live page tints the iris with the same scalar.
10//
11// WHAT THIS EMITS: three swatch genes -- skin, hair, eye -- drawn from ONE shared melanin factor
12// with a per-tissue loading, so they COVARY. Each lands on nx_breeding's own 0..1000 range, so a
13// swatch is a drop-in for the single hue trait it supersedes rather than a parallel colour system.
14//
15// THE LOADINGS ARE THE MODEL'S ONLY FREE PARAMETERS AND THEIR ORDERING IS THE FALSIFIABLE CLAIM:
16// skin is the most strongly determined by the shared melanin factor, hair next, eye least -- iris
17// colour is the most independently varying of the three. That ordering, not the exact values, is
18// what the gate tests, and the values live in knowledge/id_palette.conf with their provenance.
19//
20// THE INCUMBENT IS KEPT RUNNABLE below as the control. A baseline you cannot re-run is a number and
21// not a control, so the gate measures the old behaviour at runtime instead of quoting a figure.
22//
23// LIB, no main (ecosystem convention). license_tier: ORIGINAL No hw writes (Rule 26).
24import "nx_syscalls.nx"
25import "nx_id_param_core.nx"
26import "nx_skin_ita.nx"
27
28const IDPAL_FACTOR_MELANIN: i64 = 0 // the shared chromophore. Factor ids are split streams too.
29const IDPAL_AX_SKIN: i64 = 0
30const IDPAL_AX_HAIR: i64 = 1
31const IDPAL_AX_EYE: i64 = 2
32const IDPAL_N: i64 = 3
33// per-tissue loadings in permil: how much of this tissue's colour is the shared melanin cause.
34const IDPAL_LOAD_SKIN: i64 = 900
35const IDPAL_LOAD_HAIR: i64 = 750
36const IDPAL_LOAD_EYE: i64 = 600
37const IDPAL_SPAN: i64 = 1000 // nx_breeding's GN_T_HUE range, matched deliberately
38const IDPAL_V: i64 = 1
39
40func gn_palette_version() -> i64 { return IDPAL_V }
41func gn_palette_load(axis: i64) -> i64 {
42 if axis == IDPAL_AX_SKIN { return IDPAL_LOAD_SKIN }
43 if axis == IDPAL_AX_HAIR { return IDPAL_LOAD_HAIR }
44 return IDPAL_LOAD_EYE
45}
46
47// THE PALETTE. Writes three correlated swatch genes into out3. Deterministic and allocation-free:
48// the same seed yields the same cast on the NAS and in the engine, which is what makes this
49// shippable across the offline/live boundary rather than a second colour system.
50func gn_palette_sample(seed: i64, out3: *i64) -> i64 {
51 let m: i64 = idp_master(seed, IDPAL_FACTOR_MELANIN)
52 var a: i64 = 0
53 while a < IDPAL_N {
54 out3[a] = idp_to_span(idp_fan(m, gn_palette_load(a), seed, a), IDPAL_SPAN)
55 a = a + 1
56 }
57 return 0
58}
59
60// THE INCUMBENT, KEPT RUNNABLE: an independent uniform draw per axis -- the class nx_breeding's
61// gn_wild is in today. Setting every loading to zero reproduces it EXACTLY, which is why the gate
62// can measure the defect and the fix on ONE ruler instead of two.
63func gn_palette_sample_uncorrelated(seed: i64, out3: *i64) -> i64 {
64 var a: i64 = 0
65 while a < IDPAL_N {
66 out3[a] = idp_to_span(idp_fan(0, 0, seed, a), IDPAL_SPAN)
67 a = a + 1
68 }
69 return 0
70}
71
72// THE COLLAPSED IMPLEMENTATION, kept runnable as a negative control: every axis simply IS the
73// master. It scores a perfect correlation and destroys the very thing correlation was meant to
74// organise -- three tissues that are always the same number. Named here so the gate can CALL it
75// rather than describe it.
76func gn_palette_sample_collapsed(seed: i64, out3: *i64) -> i64 {
77 let m: i64 = idp_master(seed, IDPAL_FACTOR_MELANIN)
78 var a: i64 = 0
79 while a < IDPAL_N { out3[a] = idp_to_span(m, IDPAL_SPAN); a = a + 1 }
80 return 0
81}
82
83// the skin swatch as a real sRGB albedo, through the published ITA locus nx_skin_ita already owns.
84// Composed, never re-derived: there is one colour standard in this estate and this is not a copy.
85func gn_palette_skin_srgb(skin_gene: i64, region_dl: i64, out3: *i64) -> i64 {
86 return si_albedo_of_gene(skin_gene, region_dl, out3)
87}