code wiki / (root) / nx_id_param_core.nx

nx_id_param_core.nx

buildroot/runtime/nx_id_param_core.nx

11318 B200 linesdepth 3pulls 3 transitivereach 2 importersview sourcekind librarytopic id
docsdependenciesstructsconstsfunctions

about

nx_id_param_core.nx -- THE PURE IDENTITY-PARAMETER CORE. /compare/procgen C36, symbol id_param_core. Extracted 2026-08-28 on the pattern nx_worldpipe_core proved for TERRAIN the same week: a pure, allocation-free arithmetic core that both the NAS-side generate/judge loop and the shipping engine import, so the two can never disagree about who a character is. Terrain got this treatment first; a body is the same problem with a different field. THE DEFECT IT CLOSES, MEASURED RATHER THAN ASSUMED. nx_breeding's gn_wild draws every trait as g[t] = lo(t) + gn_hash3(seed, t, 1) % span -- twelve INDEPENDENT uniform draws with ZERO covariance, of which exactly ONE (GN_T_HUE) is a colour. Downstream, nx_skin_ita maps that single scalar onto a straight L* locus at FIXED a* and FIXED b*, so the entire cast varies along ONE LINE in a perceptually uniform space. That is the mechanical content of the operator's "our colour palette is barely used": not a palette that is under-used, but an identity space that is one-dimensional and uncorrelated. A cast drawn that way cannot read as deliberate, because nothing about any character relates to anything else about it. WHAT IS ALREADY RIGHT, SAID PLAINLY SO THIS CORE IS NOT CREDITED WITH IT: gn_hash3(seed, t, ...) is ALREADY a split stream keyed on the trait id, so adding trait 12 cannot reshuffle traits 0..11 and every character is already bit-identically reproducible from its seed. That property is INHERITED here, not invented here. What is new is CORRELATION. THE MODEL: ONE FACTOR, STATED RATHER THAN FITTED. An axis is x = (m*load + r*sqrt(UNIT^2 - load^2)) / UNIT with m the shared master variate, r the axis's own independent residual, and load in 0..UNIT. This is the standard one-factor construction, and it has two properties a hand-rolled blend does not: corr(x, m) is load/UNIT BY CONSTRUCTION, and the marginal spread of x is the SAME whatever the load -- so tightening a family resemblance never quietly costs variety. Both are gate teeth, measured with a real estimator rather than asserted. WHY A FACTOR MODEL AND NOT A COVARIANCE MATRIX. A full matrix needs entries fitted to a population we have not measured -- numbers with no source, which is the defect rule 11 exists to stop. A factor model needs ONE loading per axis and states what it means: how much of this axis is the shared cause. For pigmentation that shared cause is not a statistical convenience, it is physical -- skin, hair and iris colour are all produced by the same melanin chromophore -- so a single latent factor is the honest structure and the loadings are the only free parameters. SETTING load TO ZERO REPRODUCES THE INCUMBENT EXACTLY: an independent uniform draw per axis. The gate uses that as its control, so the defect and the fix are measured on ONE ruler. LIB, no main (ecosystem convention). license_tier: ORIGINAL No hw writes (Rule 26).

dependencies 2 imports · 2 importers

nx_syscalls.nx nx_breeding.nx nx_id_param_core.nx nx_id_palette.nx nx_id_param_gate.nx

imports: nx_syscalls.nxnx_breeding.nx

imported by: nx_id_palette.nxnx_id_param_gate.nx

structs

none

consts

43const IDP_UNIT: i64 = 1000
44const IDP_V: i64 = 1
48const IDP_SALT_MASTER: i64 = 7001
49const IDP_SALT_RESID: i64 = 7002
52const IDP_CORR_UNDEF: i64 = 0 - 100000
90const IDP_AVAL_MUL: i64 = 1274126177
91const IDP_AVAL_1: i64 = 13
92const IDP_AVAL_2: i64 = 16
93const IDP_AVAL_MASK: i64 = 4611686018427387903

functions

57func id_param_core() -> i64 { return IDP_V }
called by 1: main
61func idp_isqrt(v: i64) -> i64
94func idp_avalanche(h0: i64) -> i64
called by 1: idp_stream
105func idp_stream_raw(seed: i64, axis: i64, salt: i64) -> i64 { return gn_hash3(seed, axis, salt) }
called by 1: idp_unit_raw calls 1: gn_hash3
106func idp_unit_raw(seed: i64, axis: i64, salt: i64) -> i64 { return idp_stream_raw(seed, axis, salt) % (IDP_UNIT + 1) }
called by 1: idp_centered_raw calls 1: idp_stream_raw
107func idp_centered_raw(seed: i64, axis: i64, salt: i64) -> i64 { return 2 * idp_unit_raw(seed, axis, salt) - IDP_UNIT }
called by 1: main calls 1: idp_unit_raw
110func idp_stream(seed: i64, axis: i64, salt: i64) -> i64 { return idp_avalanche(gn_hash3(seed, axis, salt)) }
called by 1: idp_unit calls 2: idp_avalanchegn_hash3
113func idp_unit(seed: i64, axis: i64, salt: i64) -> i64
called by 1: idp_centered calls 1: idp_stream
117func idp_centered(seed: i64, axis: i64, salt: i64) -> i64
called by 3: idp_masteridp_fanmain calls 1: idp_unit
123func idp_master(seed: i64, factor: i64) -> i64
142func idp_fan(master: i64, load: i64, seed: i64, axis: i64) -> i64
155func idp_to_span(c: i64, span: i64) -> i64
164func idp_corr_permil(xs: *i64, ys: *i64, n: i64) -> i64
called by 1: main calls 1: idp_isqrt
190func idp_spread(xs: *i64, n: i64) -> i64
called by 1: main calls 1: idp_isqrt