nx_eroticism_ladder.nx source
↩ module page · 234 lines · 11034 B
1// nx_eroticism_ladder.nx -- 10-rank typed eroticism scale + arousal validator.
2//
3// User cardinal: "eroticism being s or a 10/10 whatever we are using for
4// measurement level for actually seeing penetration with her properly
5// responding and a class being her properly presenting herself for
6// fucking all the way down to 1 right now. this would validate and
7// audit the arousal number she has."
8//
9// 10 sealed ranks (S..F), each gated by required-tag bundles:
10// 10 (S) ACTIVE_PENETRATION_WITH_RESPONSE
11// 9 (A+) ACTIVE_PENETRATION
12// 8 (A) PRESENTING_FOR_PENETRATION
13// 7 (B+) EXPLICIT_INVITATION (fingers on pussy, spread cheeks, eye-contact-while-spread)
14// 6 (B) SUGGESTIVE_NUDE (nude + arched / hand-framing pose)
15// 5 (C+) ARTISTIC_NUDE (nude neutral pose)
16// 4 (C) TEASING_DRESSED (sexy outfit + suggestive pose)
17// 3 (D+) SUGGESTIVE_DRESSED (clothed + seductive cues)
18// 2 (D) NORMAL_FEMININE_DRESSED
19// 1 (F) MODEST_NEUTRAL
20//
21// The substrate compares the measured rank vs the rank implied by the
22// character's declared arousal_q10 and emits MATCH / UNDERSHOOT /
23// OVERSHOOT verdict so the auto-fix loop can push the render toward
24// what the character's arousal state actually calls for.
25//
26// All inputs are TYPED FLAGS (i64 bitfield bundled as separate i64
27// per axis to avoid bitwise complexity in nxc2 codegen). Flat-array
28// result avoids the struct-pointer-return codegen bug.
29
30// nx_safety_envelope:
31// intended_use: AUTO_APPLIED -- primitive-specific tuning queued
32// sil_target: SIL1
33// evidence: [bulk_applied_2026-05-16, see-file-comment-for-detail]
34// verdict: NOT_YET_EVALUATED
35
36import "nx_syscalls.nx"
37
38// Sealed ranks (1-10).
39const NX_EROS_RANK_MODEST_NEUTRAL: i64 = 1
40const NX_EROS_RANK_NORMAL_FEMININE_DRESSED: i64 = 2
41const NX_EROS_RANK_SUGGESTIVE_DRESSED: i64 = 3
42const NX_EROS_RANK_TEASING_DRESSED: i64 = 4
43const NX_EROS_RANK_ARTISTIC_NUDE: i64 = 5
44const NX_EROS_RANK_SUGGESTIVE_NUDE: i64 = 6
45const NX_EROS_RANK_EXPLICIT_INVITATION: i64 = 7
46const NX_EROS_RANK_PRESENTING_FOR_PENETRATION: i64 = 8
47const NX_EROS_RANK_ACTIVE_PENETRATION: i64 = 9
48const NX_EROS_RANK_ACTIVE_PENETRATION_WITH_RESPONSE: i64 = 10
49
50// Measured-state flags (1 = present, 0 = absent).
51// Caller fills the measurement struct from V7 region/pose detectors.
52//
53// Nudity axis (sealed):
54const NX_EROS_NUDITY_FULLY_DRESSED: i64 = 0
55const NX_EROS_NUDITY_PARTIAL_CLOTHED: i64 = 1
56const NX_EROS_NUDITY_TOPLESS: i64 = 2
57const NX_EROS_NUDITY_FULL_NUDE: i64 = 3
58// Pussy visibility axis (mirrors PussyVisibility):
59const NX_EROS_PUSSY_HIDDEN: i64 = 0
60const NX_EROS_PUSSY_PARTIAL: i64 = 1
61const NX_EROS_PUSSY_SPREAD: i64 = 2
62const NX_EROS_PUSSY_DETAILED: i64 = 3
63// Pose suggestiveness axis (sealed):
64const NX_EROS_POSE_MODEST: i64 = 0
65const NX_EROS_POSE_NEUTRAL: i64 = 1
66const NX_EROS_POSE_SUGGESTIVE: i64 = 2
67const NX_EROS_POSE_INVITING: i64 = 3
68const NX_EROS_POSE_PRESENTING: i64 = 4
69// Penetration axis (binary today):
70const NX_EROS_PENETRATION_NONE: i64 = 0
71const NX_EROS_PENETRATION_VISIBLE: i64 = 1
72// Response signals (additive count: 0..4 of {flushed_skin, parted_lips, body_tension, fluid}):
73// passed as integer in [0,4]
74
75// Result layout.
76const NX_EROS_RES_MEASURED_RANK: i64 = 0
77const NX_EROS_RES_EXPECTED_RANK: i64 = 1
78const NX_EROS_RES_DELTA: i64 = 2 // signed (measured - expected)
79const NX_EROS_RES_VERDICT: i64 = 3
80const NX_EROS_RES_AROUSAL_Q10: i64 = 4
81const NX_EROS_RES_FIELDS: i64 = 5
82
83// Verdict.
84const NX_EROS_VERDICT_SEVERE_UNDERSHOOT: i64 = 0 // measured 2+ ranks below
85const NX_EROS_VERDICT_UNDERSHOOT: i64 = 1 // measured 1 rank below
86const NX_EROS_VERDICT_MATCH: i64 = 2 // measured == expected
87const NX_EROS_VERDICT_OVERSHOOT: i64 = 3 // measured 1 rank above
88const NX_EROS_VERDICT_SEVERE_OVERSHOOT: i64 = 4 // measured 2+ ranks above
89
90// Map declared arousal_q10 (0..1024) to expected rank (1..10).
91func nx_eros_expected_rank_for_arousal(arousal_q10: i64) -> i64 {
92 if arousal_q10 < 0 { return NX_EROS_RANK_MODEST_NEUTRAL }
93 if arousal_q10 >= 921 { return NX_EROS_RANK_ACTIVE_PENETRATION_WITH_RESPONSE }
94 if arousal_q10 >= 819 { return NX_EROS_RANK_ACTIVE_PENETRATION }
95 if arousal_q10 >= 717 { return NX_EROS_RANK_PRESENTING_FOR_PENETRATION }
96 if arousal_q10 >= 614 { return NX_EROS_RANK_EXPLICIT_INVITATION }
97 if arousal_q10 >= 512 { return NX_EROS_RANK_SUGGESTIVE_NUDE }
98 if arousal_q10 >= 410 { return NX_EROS_RANK_ARTISTIC_NUDE }
99 if arousal_q10 >= 307 { return NX_EROS_RANK_TEASING_DRESSED }
100 if arousal_q10 >= 205 { return NX_EROS_RANK_SUGGESTIVE_DRESSED }
101 if arousal_q10 >= 102 { return NX_EROS_RANK_NORMAL_FEMININE_DRESSED }
102 return NX_EROS_RANK_MODEST_NEUTRAL
103}
104
105// Classify measured rank from typed axis inputs.
106// Hierarchy: penetration > pussy_visibility > pose > nudity.
107func nx_eros_classify_measured(nudity: i64, pussy_vis: i64, pose: i64,
108 penetration: i64, response_count: i64) -> i64 {
109 if penetration >= NX_EROS_PENETRATION_VISIBLE {
110 if response_count >= 2 { return NX_EROS_RANK_ACTIVE_PENETRATION_WITH_RESPONSE }
111 return NX_EROS_RANK_ACTIVE_PENETRATION
112 }
113 if pose >= NX_EROS_POSE_PRESENTING {
114 if pussy_vis >= NX_EROS_PUSSY_DETAILED { return NX_EROS_RANK_PRESENTING_FOR_PENETRATION }
115 }
116 if pussy_vis >= NX_EROS_PUSSY_SPREAD {
117 if pose >= NX_EROS_POSE_INVITING { return NX_EROS_RANK_EXPLICIT_INVITATION }
118 }
119 if nudity >= NX_EROS_NUDITY_FULL_NUDE {
120 if pose >= NX_EROS_POSE_SUGGESTIVE { return NX_EROS_RANK_SUGGESTIVE_NUDE }
121 return NX_EROS_RANK_ARTISTIC_NUDE
122 }
123 if nudity == NX_EROS_NUDITY_TOPLESS {
124 if pose >= NX_EROS_POSE_INVITING { return NX_EROS_RANK_SUGGESTIVE_NUDE }
125 if pose >= NX_EROS_POSE_SUGGESTIVE { return NX_EROS_RANK_ARTISTIC_NUDE }
126 return NX_EROS_RANK_ARTISTIC_NUDE
127 }
128 if nudity == NX_EROS_NUDITY_PARTIAL_CLOTHED {
129 if pose >= NX_EROS_POSE_INVITING { return NX_EROS_RANK_TEASING_DRESSED }
130 if pose >= NX_EROS_POSE_SUGGESTIVE { return NX_EROS_RANK_SUGGESTIVE_DRESSED }
131 return NX_EROS_RANK_NORMAL_FEMININE_DRESSED
132 }
133 // Fully dressed.
134 if pose >= NX_EROS_POSE_INVITING { return NX_EROS_RANK_SUGGESTIVE_DRESSED }
135 if pose >= NX_EROS_POSE_SUGGESTIVE { return NX_EROS_RANK_NORMAL_FEMININE_DRESSED }
136 if pose == NX_EROS_POSE_MODEST { return NX_EROS_RANK_MODEST_NEUTRAL }
137 return NX_EROS_RANK_NORMAL_FEMININE_DRESSED
138}
139
140// Validate measured-vs-declared. Returns 0; writes result.
141func nx_eros_validate(arousal_q10: i64,
142 nudity: i64, pussy_vis: i64, pose: i64,
143 penetration: i64, response_count: i64,
144 result: *i64) -> i64 {
145 var i: i64 = 0
146 while i < NX_EROS_RES_FIELDS { result[i] = 0; i = i + 1 }
147
148 let expected: i64 = nx_eros_expected_rank_for_arousal(arousal_q10)
149 let measured: i64 = nx_eros_classify_measured(nudity, pussy_vis, pose,
150 penetration, response_count)
151 let delta: i64 = measured - expected
152
153 result[NX_EROS_RES_MEASURED_RANK] = measured
154 result[NX_EROS_RES_EXPECTED_RANK] = expected
155 result[NX_EROS_RES_DELTA] = delta
156 result[NX_EROS_RES_AROUSAL_Q10] = arousal_q10
157
158 var verdict: i64 = NX_EROS_VERDICT_MATCH
159 if delta <= -2 { verdict = NX_EROS_VERDICT_SEVERE_UNDERSHOOT }
160 else { if delta == -1 { verdict = NX_EROS_VERDICT_UNDERSHOOT }
161 else { if delta == 1 { verdict = NX_EROS_VERDICT_OVERSHOOT }
162 else { if delta >= 2 { verdict = NX_EROS_VERDICT_SEVERE_OVERSHOOT } } } }
163 result[NX_EROS_RES_VERDICT] = verdict
164 return 0
165}
166
167// Corrective-phrase ids: returned in phrase_ids buffer, count via return.
168const NX_EROS_PHRASE_ELEVATE_NUDITY: i64 = 100 // strip down further
169const NX_EROS_PHRASE_ELEVATE_POSE: i64 = 101 // more inviting posture
170const NX_EROS_PHRASE_ELEVATE_PUSSY_VIS: i64 = 102 // spread / present more
171const NX_EROS_PHRASE_ELEVATE_PENETRATION: i64 = 103 // show act
172const NX_EROS_PHRASE_ELEVATE_RESPONSE: i64 = 104 // flushed / parted lips / fluid
173const NX_EROS_PHRASE_DEMURE_NUDITY: i64 = 110 // cover up
174const NX_EROS_PHRASE_DEMURE_POSE: i64 = 111 // close legs / less arched
175const NX_EROS_PHRASE_DEMURE_PUSSY: i64 = 112 // legs together / hidden
176
177// Suggest corrective axis(es) to fix the delta.
178func nx_eros_corrective_phrases(result: *i64,
179 measured_nudity: i64,
180 measured_pussy: i64,
181 measured_pose: i64,
182 measured_penetration: i64,
183 response_count: i64,
184 phrase_ids: *i64) -> i64 {
185 var n: i64 = 0
186 let verdict: i64 = result[NX_EROS_RES_VERDICT]
187 let delta: i64 = result[NX_EROS_RES_DELTA]
188 let expected: i64 = result[NX_EROS_RES_EXPECTED_RANK]
189
190 if delta == 0 { return 0 }
191 if delta < 0 {
192 // Undershoot: pick the LOWEST-ranked axis still falling short.
193 if expected >= NX_EROS_RANK_ACTIVE_PENETRATION {
194 if measured_penetration == NX_EROS_PENETRATION_NONE {
195 phrase_ids[n] = NX_EROS_PHRASE_ELEVATE_PENETRATION; n = n + 1
196 }
197 if response_count < 2 {
198 phrase_ids[n] = NX_EROS_PHRASE_ELEVATE_RESPONSE; n = n + 1
199 }
200 }
201 if expected >= NX_EROS_RANK_EXPLICIT_INVITATION {
202 if measured_pussy < NX_EROS_PUSSY_SPREAD {
203 phrase_ids[n] = NX_EROS_PHRASE_ELEVATE_PUSSY_VIS; n = n + 1
204 }
205 }
206 if expected >= NX_EROS_RANK_SUGGESTIVE_NUDE {
207 if measured_nudity < NX_EROS_NUDITY_FULL_NUDE {
208 phrase_ids[n] = NX_EROS_PHRASE_ELEVATE_NUDITY; n = n + 1
209 }
210 if measured_pose < NX_EROS_POSE_SUGGESTIVE {
211 phrase_ids[n] = NX_EROS_PHRASE_ELEVATE_POSE; n = n + 1
212 }
213 }
214 if n == 0 {
215 // Generic elevation hint when no specific axis is short.
216 phrase_ids[n] = NX_EROS_PHRASE_ELEVATE_POSE; n = n + 1
217 }
218 return n
219 }
220 // Overshoot: bring it back toward modest.
221 if measured_penetration == NX_EROS_PENETRATION_VISIBLE {
222 phrase_ids[n] = NX_EROS_PHRASE_DEMURE_POSE; n = n + 1
223 }
224 if measured_pussy >= NX_EROS_PUSSY_SPREAD {
225 phrase_ids[n] = NX_EROS_PHRASE_DEMURE_PUSSY; n = n + 1
226 }
227 if measured_nudity >= NX_EROS_NUDITY_FULL_NUDE {
228 phrase_ids[n] = NX_EROS_PHRASE_DEMURE_NUDITY; n = n + 1
229 }
230 if n == 0 {
231 phrase_ids[n] = NX_EROS_PHRASE_DEMURE_POSE; n = n + 1
232 }
233 return n
234}