code wiki / _hdl_build / nx_char_identity_sheet.nx
nx_char_identity_sheet.nx source
↩ module page · 270 lines · 13249 B
1// nx_char_identity_sheet.nx -- the LOOK-AT-IT proof for the identity vector. Numeric gates cannot see
2// framing (this lane has been burned 3x by that), so this emits the sheet a character artist would ask
3// for: ONE identity rendered across four art styles (she must stay recognisably herself), a CAST row of
4// distinct identities (they must not be one woman recoloured), and a genetics row showing sisters whose
5// alleles differ. Every figure is drawn from the SAME dial vector via the same draw call.
6// license_tier: ORIGINAL
7import "nx_syscalls.nx"
8import "nx_char_identity.nx"
9import "nx_game_raster.nx"
10import "nx_game_art.nx"
11import "nx_game_critic.nx"
12import "nx_anatomy_critic.nx"
13import "nx_png_write.nx"
14
15const SW: i64 = 720
16const SH: i64 = 460
17
18func sp2(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
19func sn2(v: i64) -> i64 {
20 let t: *u8 = sys_mmap(32) as *u8
21 var m: i64 = v
22 var w: i64 = 0
23 if m < 0 { t[w] = 45 as u8; w = w + 1; m = 0 - m }
24 if m == 0 { t[w] = 48 as u8; sys_write(1, t, w + 1); return 0 }
25 let d: *u8 = sys_mmap(32) as *u8
26 var k: i64 = 0
27 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
28 var j: i64 = 0
29 while j < k { t[w] = d[k - 1 - j]; w = w + 1; j = j + 1 }
30 sys_write(1, t, w)
31 return 0
32}
33func snl() -> i64 { sp2("\n" as *u8); return 0 }
34
35func isqrt2(n: i64) -> i64 {
36 if n <= 0 { return 0 }
37 var x: i64 = n
38 var y: i64 = (x + 1) / 2
39 var g: i64 = 0
40 while g < 40 { if y < x { x = y; y = (x + n / x) / 2 } g = g + 1 }
41 return x
42}
43// a shaded ellipse in the packed-i64 fb (light upper-left), so figures read as volumes not flat fills
44func fig_ell(fb: *i64, cx: i64, cy: i64, rx: i64, ry: i64, r: i64, g: i64, b: i64) -> i64 {
45 if rx <= 0 { return 0 }
46 if ry <= 0 { return 0 }
47 var y: i64 = 0 - ry
48 while y <= ry {
49 var x: i64 = 0 - rx
50 while x <= rx {
51 let a: i64 = x*x*10000/(rx*rx) + y*y*10000/(ry*ry)
52 if a <= 10000 {
53 var lit: i64 = 100 + (0 - x) * 40 / rx + (0 - y) * 40 / ry
54 if lit < 55 { lit = 55 }
55 if lit > 165 { lit = 165 }
56 let rr: i64 = idv_clamp(r * lit / 100, 0, 255)
57 let gg: i64 = idv_clamp(g * lit / 100, 0, 255)
58 let bb: i64 = idv_clamp(b * lit / 100, 0, 255)
59 gr_px(fb, SW, SH, cx + x, cy + y, gr_pack(rr, gg, bb))
60 }
61 x = x + 1
62 }
63 y = y + 1
64 }
65 return 0
66}
67
68// ★ONE draw call for every figure on this sheet. It reads ONLY the identity vector + the style params,
69// so "the same woman in another style" is structurally the same call with a different head ratio.
70// A schematic figure, deliberately: this lane owns CONSISTENCY, the procgen lane owns fidelity.
71func draw_figure(fb: *i64, idv: *i64, style: i64, ox: i64, oy: i64, hgt: i64) -> i64 {
72 let sp: *i64 = sys_mmap(16 * 8) as *i64
73 idv_style_params(idv, style, sp)
74 let headr: i64 = sp[0] // q10 head-to-body ratio: 137 realistic .. 341 cartoon
75 let bigeyes: i64 = sp[2]
76 let skin: i64 = idv[IDV_SKIN]
77 let sr: i64 = skin & 255
78 let sg: i64 = (skin >> 8) & 255
79 let sb: i64 = (skin >> 16) & 255
80 let hair: i64 = idv[IDV_HAIR]
81 let eye: i64 = idv[IDV_EYE]
82 // proportions: head size scales with the STYLE, body landmarks with the IDENTITY
83 let head: i64 = hgt * headr / 1000
84 let lbr: i64 = idv[IDV_LBR] // leg fraction, per-mille
85 let legs: i64 = hgt * lbr / 1000
86 let torso: i64 = hgt - legs - head
87 // ★WIDTHS FROM MEASURED ANTHROPOMETRY, not eyeballed. The first version used ~105/1000 of height for
88 // shoulder breadth (~19%) and thighs at ~7%, which rendered as stick insects and scored taper 0 on
89 // nx_anatomy_critic -- no waist at all. Real adult female fractions of stature: biacromial breadth
90 // ~0.23, hip breadth ~0.19, waist ~0.15, thigh ~0.10. Dials modulate AROUND those, they do not
91 // replace them, so every identity stays inside the human envelope.
92 let shoulder: i64 = hgt * 230 / 1000 + idv[IDV_D0] * hgt / 4000
93 let waist: i64 = hgt * 150 / 1000 + idv[IDV_D1] * hgt / 6000
94 let hip: i64 = shoulder * 100 / idv[IDV_SHIP] + idv[IDV_D2] * hgt / 5000
95 let bust: i64 = hgt * 62 / 1000 + idv[IDV_D3] * hgt / 4500
96 let feet: i64 = oy + hgt
97 let hipy: i64 = feet - legs
98 let shy: i64 = hipy - torso
99 let heady: i64 = shy - head/2
100 // ★GEOMETRY CORRECTED 2026-07-27 after nx_anatomy_critic rejected the first version: the head floated
101 // free (no neck), the torso lobes were narrower than the leg mass, and an oversized hair ellipse read
102 // as the widest thing on the figure -- so the silhouette had no shoulder>waist<hip taper at all.
103 // legs (drawn first, behind) -- overlap the hips so the body stays ONE connected component
104 // thighs at ~0.10 of stature each, tapering to the ankle -- upper leg then lower leg
105 let thigh: i64 = hgt * 100 / 1000
106 fig_ell(fb, ox - hip/4, hipy + legs/4, thigh/2, legs/2, sr, sg, sb)
107 fig_ell(fb, ox + hip/4, hipy + legs/4, thigh/2, legs/2, sr, sg, sb)
108 fig_ell(fb, ox - hip/4, hipy + legs*3/4, thigh/3, legs/2, sr, sg, sb)
109 fig_ell(fb, ox + hip/4, hipy + legs*3/4, thigh/3, legs/2, sr, sg, sb)
110 // arms (behind the torso, so they never break the silhouette's waist reading)
111 fig_ell(fb, ox - shoulder/2, shy + torso/2, hgt*32/1000+1, torso*2/5, sr, sg, sb)
112 fig_ell(fb, ox + shoulder/2, shy + torso/2, hgt*32/1000+1, torso*2/5, sr, sg, sb)
113 // torso: shoulders -> waist -> hips, overlapping vertically so it reads as one mass
114 fig_ell(fb, ox, shy + torso/4, shoulder/2, torso*3/10, sr, sg, sb)
115 fig_ell(fb, ox, shy + torso/2, waist/2, torso*3/10, sr, sg, sb)
116 fig_ell(fb, ox, hipy - torso/6, hip/2, torso*3/10, sr, sg, sb)
117 if bust > 2 {
118 fig_ell(fb, ox - bust/3, shy + torso/3, bust/2, bust/2, sr, sg, sb)
119 fig_ell(fb, ox + bust/3, shy + torso/3, bust/2, bust/2, sr, sg, sb)
120 }
121 // ★NECK -- the single most important fix. It bridges head to shoulders, which is what makes this
122 // one connected body instead of a torso with a balloon above it.
123 fig_ell(fb, ox, shy - head/6, head/5 + 1, head/3 + 2, sr, sg, sb)
124 // hair mass BEHIND the head -- kept strictly narrower than the shoulders so the taper still reads
125 let hs: i64 = idv[IDV_HAIRSTYLE]
126 var hairw: i64 = head/2 + head/10
127 if hairw > shoulder*2/5 { hairw = shoulder*2/5 }
128 fig_ell(fb, ox, heady, hairw, head/2 + head/8 + hs*head/60,
129 hair & 255, (hair >> 8) & 255, (hair >> 16) & 255)
130 // head
131 fig_ell(fb, ox, heady, head/2, head/2, sr, sg, sb)
132 // eyes -- the style decides SIZE (anime/VN read through the eyes), identity decides COLOUR
133 var er: i64 = head/9 + 1
134 if bigeyes == 1 { er = head/5 + 1 }
135 gr_disc(fb, SW, SH, ox - head/4, heady, er, gr_pack(250,250,255))
136 gr_disc(fb, SW, SH, ox + head/4, heady, er, gr_pack(250,250,255))
137 gr_disc(fb, SW, SH, ox - head/4, heady, er*2/3, gr_pack(eye & 255, (eye >> 8) & 255, (eye >> 16) & 255))
138 gr_disc(fb, SW, SH, ox + head/4, heady, er*2/3, gr_pack(eye & 255, (eye >> 8) & 255, (eye >> 16) & 255))
139 gr_disc(fb, SW, SH, ox - head/4 - er/3, heady - er/3, er/4+1, gr_pack(255,255,255))
140 gr_disc(fb, SW, SH, ox + head/4 - er/3, heady - er/3, er/4+1, gr_pack(255,255,255))
141 return 0
142}
143
144func sheet_png(fb: *i64, path: *u8) -> i64 {
145 let rgb: *u8 = sys_mmap(SW*SH*3) as *u8
146 var p2: i64 = 0
147 let n: i64 = SW*SH
148 while p2 < n {
149 let v: i64 = fb[p2]
150 rgb[p2*3] = (v & 0xff) as u8
151 rgb[p2*3+1] = ((v >> 8) & 0xff) as u8
152 rgb[p2*3+2] = ((v >> 16) & 0xff) as u8
153 p2 = p2 + 1
154 }
155 return nx_png_write_rgb(path, rgb, SW, SH)
156}
157
158func main() -> i64 {
159 let fb: *i64 = sys_mmap(SW*SH*8) as *i64
160 art_nebula(fb, SW, SH, 14, 12, 30, 32, 22, 54)
161 let ink: i64 = gr_pack(238,234,255)
162 let dim: i64 = gr_pack(152,148,182)
163 let hot: i64 = gr_pack(255,200,110)
164
165 gr_rect(fb, SW, SH, 0, 0, SW-1, 24, gr_pack(16,14,34))
166 gr_text(fb, SW, SH, 10, 8, "NISHI CHARACTER IDENTITY -- one token, one woman, any style" as *u8, ink)
167
168 // ---- ROW 1: THE SAME IDENTITY IN FOUR ART STYLES ----
169 let her: *i64 = sys_mmap(IDV_SLOTS * 8) as *i64
170 idv_from_seed(her, 8675309)
171 gr_rect(fb, SW, SH, 8, 32, SW-9, 34, gr_pack(70,62,120))
172 var hx: i64 = gr_text(fb, SW, SH, 12, 40, "SAME identity token (key " as *u8, dim)
173 hx = gr_num(fb, SW, SH, hx, 40, idv_key(her) % 1000000, hot)
174 gr_text(fb, SW, SH, hx, 40, ") rendered in 4 art styles -- identity fields BYTE-IDENTICAL across all four" as *u8, dim)
175 var st: i64 = 0
176 while st < 4 {
177 let cx: i64 = 92 + st * 172
178 draw_figure(fb, her, st, cx, 62, 150)
179 gr_text(fb, SW, SH, cx - 28, 220, idv_style_name(st), ink)
180 st = st + 1
181 }
182
183 // ---- ROW 2: THE CAST -- distinct identities, proving no mode collapse ----
184 gr_rect(fb, SW, SH, 8, 236, SW-9, 238, gr_pack(70,62,120))
185 gr_text(fb, SW, SH, 12, 244, "DISTINCT identities from distinct seeds -- different women, not recolours" as *u8, dim)
186 var i: i64 = 0
187 while i < 8 {
188 let cast: *i64 = sys_mmap(IDV_SLOTS * 8) as *i64
189 idv_from_seed(cast, 1000003 + i * 7919)
190 draw_figure(fb, cast, 1, 52 + i * 84, 262, 108)
191 i = i + 1
192 }
193
194 // ---- ROW 3: SISTERS -- same parents, different alleles ----
195 gr_rect(fb, SW, SH, 8, 386, SW-9, 388, gr_pack(70,62,120))
196 gr_text(fb, SW, SH, 12, 394, "GENETICS: her genome IS her face -- coat locus drives hair, polygenic dose drives height" as *u8, dim)
197 var k: i64 = 0
198 var lastkey: i64 = 0
199 var distinct: i64 = 0
200 while k < 8 {
201 let sis: *i64 = sys_mmap(IDV_SLOTS * 8) as *i64
202 var g: i64 = gx_set(0, GX_COAT, k % 2, (k/2) % 2)
203 g = gx_set(g, GX_HORN, (k/4) % 2, k % 2)
204 g = gx_set(g, GX_ELEM, k % 3, (k+1) % 3)
205 idv_from_companion(sis, g, 60 + k*24, gx_sexgene(GX_SEX_F, 1, 0), 0, k)
206 draw_figure(fb, sis, 1, 52 + k * 84, 404, 46)
207 if idv_key(sis) != lastkey { distinct = distinct + 1 }
208 lastkey = idv_key(sis)
209 k = k + 1
210 }
211
212 sheet_png(fb, "knowledge/nx_char_identity_sheet.png" as *u8)
213
214 // ---- measure: consistency + diversity, the two things this lane can honestly claim ----
215 let a: *i64 = sys_mmap(IDV_SLOTS * 8) as *i64
216 let b: *i64 = sys_mmap(IDV_SLOTS * 8) as *i64
217 idv_from_seed(a, 8675309)
218 idv_from_seed(b, 8675309)
219 var styles_same: i64 = 1
220 var s2: i64 = 0
221 while s2 < 4 {
222 b[IDV_STYLE] = s2
223 if idv_same(a, b) == 0 { styles_same = 0 }
224 s2 = s2 + 1
225 }
226 var dsum: i64 = 0
227 var pairs: i64 = 0
228 var x: i64 = 0
229 while x < 8 {
230 let p1: *i64 = sys_mmap(IDV_SLOTS * 8) as *i64
231 idv_from_seed(p1, 1000003 + x * 7919)
232 var y: i64 = x + 1
233 while y < 8 {
234 let p2b: *i64 = sys_mmap(IDV_SLOTS * 8) as *i64
235 idv_from_seed(p2b, 1000003 + y * 7919)
236 dsum = dsum + idv_distance(p1, p2b)
237 pairs = pairs + 1
238 y = y + 1
239 }
240 x = x + 1
241 }
242 let cout: *i64 = sys_mmap(GC_N * 8) as *i64
243 gc_score(fb, SW, SH, cout)
244 let q: i64 = gc_quality(cout)
245 // ★ANATOMY is the number that decides whether these are BODIES. Richness scored the previous, broken
246 // version 876=SOTA while its heads floated -- so richness is reported here only as context, never as
247 // the verdict. Score the row-1 realistic figure, on its own background patch.
248 let aout: *i64 = sys_mmap(AC2_N * 8) as *i64
249 let bgpix: i64 = fb[6 * SW + 6]
250 ac2_score(fb, SW, SH, 40, 44, 148, 214, bgpix, 0, aout)
251 let anat: i64 = ac2_quality(aout)
252
253 sp2("=== nx_char_identity_sheet: identity sheet emitted ===\n" as *u8)
254 sp2(" frame knowledge/nx_char_identity_sheet.png (720x460)\n" as *u8)
255 sp2(" identity held across all 4 art styles: " as *u8); sn2(styles_same); snl()
256 sp2(" cast mean pairwise identity distance: " as *u8); sn2(dsum / pairs)
257 sp2(" over " as *u8); sn2(pairs); sp2(" pairs\n" as *u8)
258 sp2(" sisters with distinct genomes: " as *u8); sn2(distinct); sp2("/8\n" as *u8)
259 sp2(" ANATOMY (the verdict): " as *u8); sn2(anat); sp2(" = " as *u8); sp2(ac2_verdict(anat))
260 sp2(" [conn " as *u8); sn2(aout[AC2_M_CONN]); sp2(" head " as *u8); sn2(aout[AC2_M_HEAD])
261 sp2(" taper " as *u8); sn2(aout[AC2_M_TAPER]); sp2(" vbal " as *u8); sn2(aout[AC2_M_VBAL])
262 sp2(" limb " as *u8); sn2(aout[AC2_M_LIMB]); sp2("]\n" as *u8)
263 sp2(" richness (CONTEXT ONLY, not the verdict): " as *u8); sn2(q); sp2(" = " as *u8); sp2(gc_verdict(q)); snl()
264 sp2(" ★HONEST SCOPE: this sheet proves CONSISTENCY, DIVERSITY and that the figures READ AS BODIES.\n" as *u8)
265 sp2(" It does NOT claim beauty -- the optimum flips with stimulus realism, so a beauty judge at this\n" as *u8)
266 sp2(" fidelity would teach the WRONG target. Fidelity is the procgen lane's job.\n" as *u8)
267 if styles_same == 1 { if distinct >= 7 { if anat >= AC2_CRUDE { return 0 } } }
268 sp2("REFUSED: the sheet did not meet its own bar\n" as *u8)
269 return 1
270}