LifePlay-Revival/Docs/Migration/etat/ST/STE/STE-ORG4c-SPEC.md
edujiro5972 8084622450 LifePlay UE 5.8 : état de développement au 2026-10-19
Tickets : REP1-T4

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 22:57:42 +02:00

60 KiB
Raw Blame History

Fiche STE-ORG4c — Niveau N3 — Modèle prévu (modèle de l'agent lp-cart) | utilisé claude-sonnet-5-5 — Agent lp-cart — Skills lp-mcp (lu : .claude\skills\lp-mcp\SKILL.md, lecture seule), sk-protocol (invoqué), ue-cpp-build, lp-commandlets, lp-paths (préchargés avec l'agent)

STE-ORG4c-SPEC : bonus d'orgasme à Endsex pour chaque participant, seuil selon le sexe (O4c, remplace O4b) (2026-10-14, complété le 2026-10-14 : décisions de l'utilisateur intégrées, Q-ORG4c-2 = IsMale OU Genital == 'Penis')

Hors gabarit : les sections suivent le gabarit SPEC de D:\Game\LifePlay-Sandbox\Tools\claude\skills\lp-doc\gabarits.md (§ 1 à 7, dans l'ordre) ; correspondance avec la rubrique 7 de la fiche : objectif et comportement = § 1 et § 2.5 ; O4c au geste près, comptes = § 2.3 et § 2.4 ; règle commune ORG4 / ORG5 = § 2.6 ; repli = § 3 ; Q# = § 4 ; V5 / V6 mis à jour = § 7. Lecture seule stricte (Read, Grep, Glob ; Bash pour git rev-parse, md5sum, git status) ; aucun éditeur, MCP, commandlet, build ni jeu ; un seul fichier écrit : ce livrable.

Annonce en tête

  • O4c remplace O4b de STE-ORG4-SPEC.md (§ 2.3) : les nœuds O4b-* ne sont pas créés. O4a (garde PersonCumming dans AfterCumSpeed) est reprise sans changement de STE-ORG4-SPEC.md § 2.2 (3 nœuds, 1 coupure, 6 liens, 1 valeur) ; elle reste indépendante et peut partir seule (Q-ORG4-5).
  • Person, SexAction, PC ne sont pas touchés ; GI est touché (Content\BPs\GI.uasset, graphe EventGraph seul), qui porte déjà G16 (STE-H3g) et B7-a (STG) non commités (R-ORG4-2 de STE-ORG4-SPEC.md).
  • Décisions de l'utilisateur intégrées (section finale « Décisions », 2026-10-14) : seuil femme 100 gardé (Q1) ; « homme » = IsMale OU Genital == 'Penis' (Q2, la règle de « Close to cumming ») ; >= 90 et >= 100 (Q3) ; garde IsValid par élément oui (Q4) ; deux libellés de marqueur, pas de marqueur à l'orgasme réel (Q5).
  • Statut : exécutable par MCP, sous la condition P0 (lecture de SexAction ; le dump n'existe toujours pas : Glob **\*SexAction* sous etat\ST\STE → aucun fichier). Sept type_id n'ont jamais été créés par MCP dans ce projet : Utilities|Array|ForEachLoop, Classe|Person|ObtenirIsMale, Classe|Person|ObtenirSexOrgasm, Classe|Person|ObtenirGenital, Classe|Person|GiveOrgasmReward, la conversion Texte vers chaîne (Conv_TextToString) et l'égalité de chaînes (EqualEqual_StriStri) : ils se relèvent par find_node_types avant tout geste (§ 2.1). Relus et déjà créés : Branche, IsValid pur, Inférieurà(<), Développement|PrintString, Math|Booléen|ORBoolean.
  • Trois constats qui changent la lecture de la décision (détails § 1.2) :
    1. « homme » se lit par IsMale OU Genital == 'Penis' : exactement la combinaison du jeu pour « Close to cumming » (P-STG:17340-17359), et GI en lit déjà une variante sur SexPersons[0] (GI-P2:18904-18931). Genital est un Texte : conversion en chaîne puis égalité de chaînes (précédent identique dans GI et dans Person).
    2. Le seuil femme = 100 n'est atteignable à aucun moment de l'interface : à Sex_Orgasm == 100.0 l'orgasme automatique se déclenche dans le même appel et remet la jauge à 0. La branche « non homme » de O4c est écrite fidèlement à la décision (gardée) mais ne s'exécute pas en pratique (Q-ORG4c-1, R-ORG4c-2). V6 ne peut pas la rejouer.
    3. Le corps de boucle n'a pas à rejoindre AfterCumSpeed : un chemin qui s'arrête dans le corps passe à l'élément suivant (précédent dans le même graphe, § 1.2 F6) ; seule la sortie Completed rejoint la suite existante.

Abréviations (chemins absolus) : E = D:\Game\LifePlay-master 5.8\Docs\Migration\etat\ ; ORG4S = EST\STE\STE-ORG4-SPEC.md ; ORG5S = EST\STE\STE-ORG5-SPEC.md ; GI-P2 = EST\STE\dumps\GI__EventGraph_P2.txt (6 249 nœuds, en-tête ligne 1) ; P-STG = EST\STG\dumps\Person__EventGraph.txt ; PC-STE = EST\STE\dumps\PC__EventGraph.txt ; AUD = EST\STE\STE-ORG-AUDIT.md ; H3gI = EST\STE\STE-H3g-IMPL.md ; H5bC = EST\STE\STE-H5b-C0.md ; H10I = EST\STE\STE-H10-IMPL.md ; H10G1 = EST\STE\STE-H10-GI1-IMPL.md ; H10G2 = EST\STE\STE-H10-GI2-IMPL.md ; B7aI = EST\STG\STG-B7a-IMPL.md ; B2PI = EST\STG\STG-B2P-IMPL.md ; CAMB2g = ECAM\CAM-B2g-IMPL.md ; UE = D:\Game\Launcher\Engine\UE_5.8\Engine\Source\.

État relevé à l'entrée de cette SPEC (Bash, lecture, 2026-10-14)

Commande Sortie
git -C "D:/Game/LifePlay-master 5.8" rev-parse --short HEAD 0745917
md5sum …/Content/BPs/GI.uasset e64b5b37c9ef0db7735de0d6e3bd7c1c (= valeur de ORG4S, GI inchangé depuis)
md5sum …/Content/BPs/Person.uasset 8668a47c627f7a5254910cf0ac33b12a (= ORG4S)
md5sum …/Content/UI/SexAction.uasset a8705f7fbe1fde1daba0464bfc9ff9b5 (= ORG4S)
git -C … status --short -- Content/BPs/GI.uasset Content/BPs/Person.uasset Content/BPs/Room.uasset Content/UI/SexAction.uasset Content/BPs/PC.uasset M pour GI, PC, Person, Room ; SexAction non listé
Grep ^=== GI sur GI-P2 1:=== GI :: EventGraph (6249 noeuds) === et 30177:=== GI :: EventGraph (6249 noeuds) === (le fichier contient deux blocs à en-tête identique : liste des nœuds avec broches, puis liste de l'exécution)

Écart à ORG4S : PC.uasset est maintenant M (ORG4S : « SexAction et PC non listés »). PC n'est pas touché par O4c et n'est lu qu'à titre descriptif (dump PC-STE du 2026-10-10, antérieur) : l'écart ne conditionne pas ce correctif, mais le dump de PC est périmé (R-ORG4c-8). N0 (nœuds de GI:EventGraph à l'entrée) = 6 253 (repris de ORG4S, état relevé, ligne 27 ; chaîne H3g puis B7-a ; non relu à la source aujourd'hui, P1 le refait). Le dump GI-P2 (6 249) reste valable pour les nœuds du chemin Cum (aucun n'a changé de nom : ORG4S, même ligne).

1. Objectif mesurable

1.1 Rappel de la cause (renvoi à ORG4S § 1.1)

Endsex appelle GI::Cum directement avec (estimé fort, P0) ForceEnd = true, sans passer par Person::Cum : ni GiveOrgasmReward ni l'incrément de Sex_OrgasmCounts ne sont atteints. Le chemin dans GI : CustomEvent_4245 (Cum) puis IfThenElse_875 (Condition = ForceEnd, GI-P2:14554-14558) puis then vers CallFunction_11423 (AfterCumSpeed, GI-P2:10905-10908) puis la suite jusqu'à EndSex (IfThenElse_876, GI-P2:14559-14567). O4c s'insère entre IfThenElse_875.then et CallFunction_11423.execute.

1.2 Faits relevés pour O4c (établi sauf mention)

# Fait Source
F1 Le sexe d'une personne est porté par la variable booléenne IsMale de Person ; GI la lit par un VariableGet dont self est une référence Person (IsMale vers BooleanAND.B, self ← PersonCumming). Elle est écrite par le chargen (PlayerChangeGender, paramètre NewIsMale). Aucune variable IsFemale ni Gender dans GI-P2 ni dans P-STG (les occurrences de GI-P2 sont GenderBender, GenderOnly, SortSexPersonsByGender, CheckCbeGenderModel, un champ de structure isMale_5_…). GI-P2:28056-28063 ; GI-P2:3830-3835, 973 ; Grep `variable '(IsMale
F2 Le jeu connaît une seconde notion : Genital (Texte) = 'Penis'. Il l'utilise avec IsMale : IsMale OU (Genital == 'Penis') pour le texte « Close to cumming » (TogglePulloutNotification, seuil Sex_Orgasm >= 90, index 0 de SexPersons seulement, filtres MF / MM / FF+tag Shemale), et Genital == 'Penis' seul pour NoPregCheck dans Cum. C'est la règle retenue par l'utilisateur pour « homme » (Q2). P-STG:17340-17359, 17360-17367, 17376-17396, 17408-17417 ; P-STG:15942-15957
F3 Sex_Orgasm est un double (GreaterEqual_DoubleDouble, Less_DoubleDouble, EqualEqual_DoubleDouble), borné à [0, 100] par FClamp. P-STG:17363-17367 ; P-STG:16126-16129 ; P-STG:16030-16033 ; P-STG:15896-15901
F4 Orgasme automatique à 100 pour tout le monde : UpdateOeChange écrit Sex_Orgasm (somme clampée), écrit Sex_Energy, appelle TogglePulloutNotification, puis Sex_Orgasm == 100.0 vrai → Cum(), le tout de façon synchrone. Écrivains de Sex_Orgasm dans P-STG : trois seulement, valeurs 0.0 (début de scène), somme clampée, 0.0 (dans Cum). Aucun écrivain dans GI-P2 (0 occurrence de Sex_Orgasm : Grep variable 'Sex_Orgasm'), ni dans PC-STE, ni dans SexInterface__EventGraph.txt, ni dans GI__PlayAppropriateSexAnimation.txt (Grep VariableSet_\d+ +variable 'Sex_Orgasm' → 0 dans chacun des trois). Conclusion : une jauge à 100 est remise à 0 dans l'image où elle y arrive → à Endsex, Sex_Orgasm == 100.0 est inatteignable (estimé fort : seuls les graphes dumpés sont lus ; les fonctions annexes de Person et les mods ne le sont pas). écrivains : P-STG:15807-15812 (0.0), 15873-15876 (somme), 15896-15901 (FClamp), 17282-17287 (0.0) ; chaîne : P-STG:15874-15875, 15890-15892, 17315-17318, 16035-16043 ; AUD:72 (« pour chaque personne »)
F5 Ordre dans Person::Cum : PersonCumming := self → macro IncrementInt(Sex_OrgasmCounts) → Sex_Orgasm := 0.0 → PlayCumParticle → GiveOrgasmReward → SetText(CumText) → SwitchInteger → GI.Cum(ForceEnd = false, NoEnd = true). Tout est synchrone. L'incrément de Sex_OrgasmCounts n'existe qu'ici (accroche H1 d'ORG5 ; 0 occurrence de Sex_OrgasmCounts dans GI-P2, Grep). P-STG:17592-17594 ; P-STG:16121-16125 ; P-STG:17282-17284 ; P-STG:16751-16753 ; P-STG:16107-16110 ; P-STG:15980-15982 ; P-STG:15958-15973
F5b Les autres appelants de GI.Cum dans Person passent aussi ForceEnd = false : Cum (deux appels, NoEnd = true) et Exhausted (NoPregCheck = true, NoEnd = false, NoShake = true). Donc la boucle O4c (branche ForceEnd vrai) n'est jamais exécutée lors d'un orgasme réel ni d'un épuisement. P-STG:15962, 15970 ; P-STG:16000-16007 ; GI-P2:14554-14558
F6 Macro ForEachLoop : nœud existant MacroInstance_806 sur SexPersons : Exec ← 4 sources, Array ← VariableGet_15054.SexPersons, LoopBody → CallFunction_34754.execute dont then est vide (corps qui se termine dans une impasse : la boucle passe à l'élément suivant), Array Element → VariableGet_13432.self, Completed → VariableSet_5686.execute. type_id relu sur nœud existant : `Utilities Array
F7 Précédents de création de macros par create_node avec un type_id en anglais `Utilities …:Utilities
F8 PrintString : type_id relu en 5.8 et déjà créé dans GI : `Développement PrintString; brochesexecute0,InString1,bPrintToScreen2,bPrintToLog3 (défaut true),then` 0.
F9 Comparateur < : `Utilitaires Opérateurs
F10 Autres type_id relus : Branche `Utilitaires ContrôleDeFlux
F11 GiveOrgasmReward : événement personnalisé de l'EventGraph de Person (sans paramètre) : OrgasmIrBoost, puis ModifyStat mood +20 si isPlayer, sinon attractiontoplayer (+3 / +6) si le joueur est dans SexPersons, rien sinon ; n'appelle aucun nœud de GI. P-STG:16059-16106 ; P-STG:19074-19077 ; AUD:23
F12 SexPersons : il existe un appel SortSexPersonsByGender dans GI : l'ordre des index n'est pas toujours l'ordre de création (ordre exact non lu). GI-P2:10451
F13 Précédent exact de la lecture « pénis » (type_id et chaîne de nœuds à reproduire). Dans Person : VariableGet_14 (IsMale) → BooleanOR.A ; VariableGet_15 (Genital, Texte) → CallFunction_884 Conv_TextToString → CallFunction_12 EqualEqual_StriStri (A ← conversion, B = 'Penis') → BooleanOR.B ; la sortie du OU est l'un des trois termes d'un ET (CommutativeAssociativeBinaryOperator_1). Dans GI : GetArrayItem_2 (élément de SexPersons) → VariableGet_84 (IsMale) → Not_PreBool ; VariableGet_85 (Genital, self = l'élément) → CallFunction_5 Conv_TextToString → CallFunction_1060 EqualEqual_StriStri (B = 'Penis') → ET : c'est la combinaison « non IsMale ET pénis », suivie du test de l'étiquette 'Shemale' (Array_Contains). Une variante à comparaison de textes existe aussi dans GI : EqualEqual_IgnoreCase_TextText (non retenue : le précédent de la règle « Close to cumming » est la forme chaîne). P-STG:17340-17359 ; P-STG:17343-17347 ; GI-P2:18904-18931 ; GI-P2:18937-18946 ; GI-P2:14315-14325
F14 `Math Booléen
F15 EqualEqual_StriStri (« Equal, Case Insensitive (String) », titre compact ==) compare sans tenir compte de la casse (FCString::Stricmp). 'Penis' et 'penis' sont donc équivalents. UERuntime\Engine\Private\KismetStringLibrary.cpp:34-37 ; UERuntime\Engine\Classes\Kismet\KismetStringLibrary.h:285-286
F16 Le jeu permet un personnage non IsMale avec pénis : le pénis est replacé selon IsMale (MalePenisLocation si vrai, FemPenisLocation sinon) ; GI teste « non IsMale ET Genital == 'Penis' » puis l'étiquette 'Shemale' ; Person filtre « FF + Shemale » pour « Close to cumming ». La création d'un tel personnage au chargen n'est pas lue (dump du chargen absent). GI-P2:3790-3802, 3806-3807 ; GI-P2:18904-18946 ; P-STG:17376-17396

1.3 Objectifs mesurables

  • O4a (inchangé, ORG4S § 2.2) : 2 avertissements Accessed None … PersonCumming par clic Endsex (ORG4S § 1.1) → 0. GI:EventGraph : N0 → N0 + 3.
  • O4c (changement de comportement voulu, décisions de l'utilisateur du 2026-10-14) : à Endsex (branche ForceEnd vrai de GI::Cum, avant AfterCumSpeed / EndSex), chaque élément de SexPersons, l'un après l'autre (index 0, 1, …), reçoit GiveOrgasmReward si et seulement si : (homme et Sex_Orgasm >= 90) ou (non homme et Sex_Orgasm >= 100), où homme = (IsMale vrai OU Genital == 'Penis') ; un marqueur de trace par bonus donné (ORG4 bonus Endsex homme / … femme ; homme = groupe du seuil 90 au sens de la règle, femme = groupe du seuil 100) ; aucun Person::Cum ; Sex_OrgasmCounts inchangé ; une personne non éligible ou invalide ne bloque pas les suivantes. GI:EventGraph : + 17 nœuds.
  • Total (O4a + O4c) : GI:EventGraph N0 + 20 = 6 273 ; 2 coupures ; 32 liens ; 8 valeurs posées ; MD5 de Person et de SexAction inchangés ; Sex_OrgasmCounts jamais écrit par GI (V5).

2. Fichiers touchés, ordre

Un seul fichier : Content\BPs\GI.uasset, graphe EventGraph (événements AfterCumSpeed pour O4a, Cum branche ForceEnd pour O4c). Ni Person, ni SexAction, ni PC, ni C++, ni scènes, ni modules. Ordre : P0 à P7 → O4a → O4c → compile_blueprint → save_assets unique → fermeture de l'éditeur. O4a et O4c dans une seule session MCP, un seul instantané, un seul save_assets. Aucun nœud commun aux deux (O4a : CustomEvent_702, VariableSet_9760, CallFunction_960, VariableGet_720 ; O4c : IfThenElse_875, CallFunction_11423, VariableGet_3498).

2.0 Préalables (identiques à ORG4S § 2.0, adaptés)

  • P0 (bloquant pour O4c) : dump du gestionnaire de clic de SexAction, éditeur fermé (.\Tools\UeState.ps1 -Kind Editeur = 0) : .\Tools\RunCommandlet.ps1 -Lot STE-ORG4 -Commandlet LPDumpFunction -Args '-BP=SexAction -Fn=EventGraph -Pins -Exec' -EtatDir "D:\Game\LifePlay-master 5.8\Docs\Migration\etat\ST\STE" (demandé à Big Boss, non attendu ici). Attendu : un appel GI_C::Cum avec ForceEnd = 'true' sur le chemin de la comparaison avec 'Endsex', aucun appel direct de EndSex. Écart : arrêt, rapport (O4c serait sans effet ; V5 passerait, V6-S1 échouerait).
  • P1 : MD5 de GI à l'entrée (attendu e64b5b37…) ; refaire le dump -BP=GI -Fn=EventGraph -Pins -Exec (en-tête attendu === GI :: EventGraph (6253 noeuds) ===) ; relever dans ce dump les comptes de référence pour V5, avec le même Grep avant et après (le fichier contient deux blocs, § État relevé) : macro 'ForEachLoop' (GI-P2 : 79 lignes, Grep macro 'ForEachLoop' → 79, baseline à refaire sur le dump P1), PrintString, GiveOrgasmReward (attendu 0), variable 'IsMale', variable 'Genital' (GI-P2 : 4 lignes aux l. 14315, 18920, 19919, 20792 dans la liste Grep limitée à 20 lignes ; recompter), Conv_TextToString, EqualEqual_StriStri, BooleanOR, variable 'Sex_Orgasm' (GI-P2 : 0).
  • P2 : MD5 relevé juste avant l'IMPL = valeur de repli.
  • P3 : gel annoncé à toutes les sessions (lp-mcp § 1 règle 7) ; .\Tools\Snapshot.ps1 -Lot STE-ORG4 ; éditeur headless (lp-mcp § 2) ; AssetTools.load_asset /Game/BPs/GI.
  • P4 (get_node_infos {nodes:[{refPath:"/Game/BPs/GI.GI:EventGraph.K2Node_<Nom>"}]}, deux appels de dix nœuds au plus ; tout écart : arrêt) : CustomEvent_4245, IfThenElse_172, IfThenElse_98, IfThenElse_875, IfThenElse_876, CallFunction_11423, VariableGet_3498, GetArrayItem_1037, MacroInstance_18, MacroInstance_806 (modèle d'indices de la macro) ; puis ceux d'O4a (ORG4S § 2.0 P4 : CustomEvent_702, VariableSet_9760, CallFunction_960, VariableGet_720, VariableGet_721, VariableGet_722) ; modèles de la chaîne Genital pour les indices de broches : VariableGet_85, CallFunction_5, CallFunction_1060 (GI-P2:18920-18931) et, pour le OU, le nœud Room CommutativeAssociativeBinaryOperator_60 (CAMB2g:69) si la lecture de Room est permise (sinon relever les indices sur le nœud créé). Liens attendus : IfThenElse_875.then → CallFunction_11423.execute seul ; CallFunction_11423.execute ← IfThenElse_875.then, CallFunction_32955.then, IfThenElse_189.then (GI-P2:10906) ; IfThenElse_875.else → MacroInstance_18.exec (14558) ; VariableGet_3498.SexPersons → GetArrayItem_1037.Array seul (10879-10883) ; MacroInstance_806 : broches Exec 0, Array 1, LoopBody 0, Array Element 1, Array Index 2, Completed 3 (à confirmer sur le nœud créé) ; VariableGet_85.self ← GetArrayItem_2.Output, CallFunction_1060.B = Penis.
  • P5 (type_id) : avant chaque create_node, find_node_types {graph:{refPath:"/Game/BPs/GI.GI:EventGraph"}, type_id_filter:<filtre du § 2.1>, context_pins:[]} ; le type_id attendu doit figurer exactement dans la réponse (sinon arrêt) ; après création, get_node_infos du nœud (indices). Pas de type_id improvisé.
  • P6 : P0 lu et conforme ; décisions de l'utilisateur reçues (section « Décisions » : Q1 gardé, Q2 = IsMale OU Genital, Q3 >=, Q4 oui, Q5 deux libellés) ; Q-ORG4c-6 (UE-GO) donné.
  • P7 (lecture, sans écriture) : find_node_types filtre GiveOrgasmReward → Classe|Person|GiveOrgasmReward ; filtre IsMale → l'entrée Classe|Person|ObtenirIsMale (parmi d'éventuelles autres : prendre celle de Person) ; filtre Orgasm → l'entrée Classe|Person|ObtenirSexOrgasm (le tiret bas disparaît : règle reprise de ORG4S § 2.1, exemple ObtenirVolBGA) ; filtre Genital → l'entrée Classe|Person|ObtenirGenital (de Person). Person MD5 8668a47c… à l'entrée, sinon arrêt. Aucun enregistrement de Person.

2.1 Conventions et table des type_id

Rôle type_id État Filtre find_node_types
Boucle `Utilities Array ForEachLoop`
Branche `Utilitaires ContrôleDeFlux Branche`
IsValid pur `Utilitaires IsValid` relu et créé
Lecteur IsMale `Classe Person ObtenirIsMale`
Lecteur Genital `Classe Person ObtenirGenital`
Conversion Texte vers chaîne fonction Conv_TextToString (KismetTextLibrary) ; type_id jamais créé, à relever précédent de nœud : P-STG:17351-17354, GI-P2:18923-18926 ToString puis Texte / Text, avec context_pins = sortie Genital de O4c-N (créer O4c-N avant) ; le nœud créé doit porter Conv_TextToString (broche InText Texte, ReturnValue chaîne) ; sinon arrêt
Égalité de chaînes fonction EqualEqual_StriStri (« Equal, Case Insensitive (String) », titre compact ==, F15) ; type_id jamais créé, à relever précédent de nœud : P-STG:17355-17359, GI-P2:18927-18931 Insensitive puis casse puis ==, avec context_pins = sortie de O4c-T ; l'entrée `Utilitaires
OU booléen `Math Booléen ORBoolean`
Lecteur Sex_Orgasm `Classe Person ObtenirSexOrgasm`
Comparateur < `Utilitaires Opérateurs Inférieurà(<)`
Marqueur `Développement PrintString` relu et créé dans GI
Bonus `Classe Person GiveOrgasmReward`
  • Pourquoi < + else : « Sex_Orgasm >= seuil » (décision Q3) = « non (Sex_Orgasm < seuil) » ; le comparateur < est le seul déjà créé ; le chemin « éligible » est la sortie else de la Branche. >= listé mais jamais créé reste un repli (même sémantique, branches inversées).
  • Cascades de branches (lp-mcp § 1 règle 4 : pas de Select, AND, OR purs) sauf une exception décidée : le OU O4c-O (consigne de l'orchestrateur du 2026-10-14). Il est sûr ici : ses deux opérandes sont des lectures pures (IsMale, comparaison de Genital) sur l'élément que O4c-B0 (garde IsValid) a déjà validé ; aucune lecture sur objet nul, donc la règle 4 (« tout est évalué ») ne crée pas d'Accessed None (R-ORG4c-11). Pas de Person::Cum appelé depuis GI (ORG4S § 2.3, R-ORG4-5). delete_node interdit. Positions libres. Outils Epic seulement, un appel MCP par message.
  • Ordre des liens et types génériques : les broches Array et Array Element de la macro sont génériques et prennent le type de l'élément (Person) au lien 2 ; faire les liens 1 à 3 d'abord, relire le type de Array Element (référence Person) avant le lien 5 ; de même, O4c-C1.A / O4c-C2.A avant leur B, et O4c-E.A avant O4c-E.B (la valeur Penis se pose une fois A typé chaîne).
  • Compilation et enregistrement : compile_blueprint {blueprint:{refPath:"/Game/BPs/GI.GI"}, warnings_as_errors:true} → null, journal de l'éditeur lu ; puis save_assets {asset_paths:["/Game/BPs/GI"]} ; hyper_blueprint_debug_inspect absent (mémoire du projet) : repli = compilation stricte + journal ; éditeur fermé, .\Tools\UeState.ps1 = 0, MD5 relevé.

2.2 Garde PersonCumming — O4a

Reprise telle quelle de ORG4S § 2.2 (nœuds O4a-V Utilitaires|IsValid, O4a-B Branche, O4a-S Définir Rate ; 1 coupure CustomEvent_702.then / VariableSet_9760.execute ; 6 liens ; Rate = 0.25). Comptes O4a : 3 nœuds ; 1 coupure ; 6 liens ; 1 valeur. Elle est exécutée avant O4c (ordre sans importance technique : nœuds disjoints).

2.3 Bonus à Endsex pour chaque participant — O4c (événement Cum, branche ForceEnd)

Schéma (L = boucle ; les impasses sont voulues et marquées ⊘) :

IfThenElse_875.then → L.Exec
L.Array ← VariableGet_3498.SexPersons
L.LoopBody → B0 (IsValid de l'élément)
    B0.else ⊘ (élément invalide : itération suivante)
    B0.then → B1   Condition de B1 = O = ( M : IsMale de l'élément ) OU ( E : Conv(Genital de l'élément) == 'Penis' )
        B1.then (homme au sens de la règle) → B2 (Sex_Orgasm < 90 ?)
            B2.then ⊘ (jauge < 90 : pas de bonus, itération suivante)
            B2.else → Ph (marqueur « homme ») → R
        B1.else (non homme) → B3 (Sex_Orgasm < 100 ?)
            B3.then ⊘ (jauge < 100 : pas de bonus)
            B3.else → Pf (marqueur « femme ») → R
        R = GiveOrgasmReward(élément) ; R.then ⊘ (itération suivante)
L.Completed → CallFunction_11423.execute (AfterCumSpeed, suite existante)
Chaîne de données de la condition : L.Array Element → M.self ; L.Array Element → N.self (Genital) → T (Texte vers chaîne) → E (== 'Penis') ; M et E → O → B1.Condition

Nœuds créés (17 ; ordre de création conseillé : L, V, B0, M, N, T, E, O, B1, G, C1, C2, B2, B3, Ph, Pf, R ; N avant T, T avant E à cause des context_pins) :

ID Nœud type_id (P5, § 2.1) Broches (à relever par get_node_infos)
O4c-L ForEachLoop `Utilities Array
O4c-V IsValid (pur) `Utilitaires IsValid`
O4c-B0 Branche (garde) `Utilitaires ContrôleDeFlux
O4c-M Lecteur IsMale `Classe Person
O4c-N Lecteur Genital `Classe Person
O4c-T Conversion Texte vers chaîne Conv_TextToString (type_id à relever, § 2.1) InText 0 ; ReturnValue 0 (chaîne)
O4c-E Égalité de chaînes sans casse EqualEqual_StriStri (type_id à relever, § 2.1) A 0, B 1 ; ReturnValue 0
O4c-O OU booléen `Math Booléen
O4c-B1 Branche (sexe) `Utilitaires ContrôleDeFlux
O4c-G Lecteur Sex_Orgasm `Classe Person
O4c-C1 Comparateur < (seuil homme) `Utilitaires Opérateurs
O4c-C2 Comparateur < (seuil femme) idem idem
O4c-B2 Branche (homme) Branche idem
O4c-B3 Branche (non homme) Branche idem
O4c-Ph PrintString « homme » `Développement PrintString`
O4c-Pf PrintString « femme » idem idem
O4c-R Appel Person_C::GiveOrgasmReward `Classe Person

Coupure (1) : break_pins IfThenElse_875.then (sortie 0) / CallFunction_11423.execute (entrée 0).

Liens (26), un appel connect_pins par message, dans cet ordre (relier O4c-G.Sex_Orgasm à O4c-C1.A et à O4c-C2.A avant de poser les B ; relier O4c-T.ReturnValue à O4c-E.A avant de poser O4c-E.B) :

  1. IfThenElse_875.then (0) → O4c-L.Exec (0)
  2. VariableGet_3498.SexPersons → O4c-L.Array (1) (le lien vers GetArrayItem_1037.Array reste)
  3. O4c-L.Completed (3) → CallFunction_11423.execute (0)
  4. O4c-L.LoopBody (0) → O4c-B0.execute (0)
  5. O4c-L.Array Element (1) → O4c-V.Object (0)
  6. O4c-V.ReturnValue (0) → O4c-B0.Condition (1)
  7. O4c-B0.then (0) → O4c-B1.execute (0)
  8. O4c-L.Array Element → O4c-M.self (0)
  9. O4c-M.IsMale (0) → O4c-O.A (0)
  10. O4c-L.Array Element → O4c-N.self (0)
  11. O4c-N.Genital (0) → O4c-T.InText (0)
  12. O4c-T.ReturnValue (0) → O4c-E.A (0)
  13. O4c-E.ReturnValue (0) → O4c-O.B (1)
  14. O4c-O.ReturnValue (0) → O4c-B1.Condition (1)
  15. O4c-B1.then (0) → O4c-B2.execute (0)
  16. O4c-B1.else (1) → O4c-B3.execute (0)
  17. O4c-L.Array Element → O4c-G.self (0)
  18. O4c-G.Sex_Orgasm (0) → O4c-C1.A (0)
  19. O4c-G.Sex_Orgasm (0) → O4c-C2.A (0)
  20. O4c-C1.ReturnValue (0) → O4c-B2.Condition (1)
  21. O4c-C2.ReturnValue (0) → O4c-B3.Condition (1)
  22. O4c-B2.else (1) → O4c-Ph.execute (0)
  23. O4c-B3.else (1) → O4c-Pf.execute (0)
  24. O4c-Ph.then (0) → O4c-R.execute (0)
  25. O4c-Pf.then (0) → O4c-R.execute (0)
  26. O4c-L.Array Element → O4c-R.self (1)

Valeurs (7, set_pin_value, relire avant et après) : O4c-E.B = Penis (après le lien 12) ; O4c-C1.B = 90.0 (après le lien 18) ; O4c-C2.B = 100.0 (après le lien 19) ; O4c-Ph.InString = ORG4 bonus Endsex homme ; O4c-Ph.bPrintToScreen = false ; O4c-Pf.InString = ORG4 bonus Endsex femme ; O4c-Pf.bPrintToScreen = false (bPrintToLog reste vrai).

Relecture (get_node_infos des 17 nœuds + des 3 existants touchés) :

  • IfThenElse_875.then → O4c-L.Exec seul ; IfThenElse_875.else → MacroInstance_18.exec inchangé ;
  • CallFunction_11423.execute ← 3 sources : O4c-L.Completed, CallFunction_32955.then, IfThenElse_189.then (même nombre qu'avant : IfThenElse_875.then est remplacé par O4c-L.Completed) ;
  • VariableGet_3498.SexPersons → 2 cibles (GetArrayItem_1037.Array, O4c-L.Array) ;
  • O4c-L.Array Element → 5 cibles (O4c-V.Object, O4c-M.self, O4c-N.self, O4c-G.self, O4c-R.self) ; O4c-G.Sex_Orgasm → 2 cibles ; O4c-R.execute ← 2 sources (Ph.then, Pf.then) ;
  • condition du sexe : O4c-O.A ← O4c-M.IsMale ; O4c-O.B ← O4c-E.ReturnValue ; O4c-E.A ← O4c-T.ReturnValue ; O4c-E.B = Penis ; O4c-T.InText ← O4c-N.Genital ; O4c-B1.Condition ← O4c-O.ReturnValue (et non plus O4c-M directement) ;
  • les 4 Branches (B0, B1, B2, B3) ont leur Condition reliée (sinon true par défaut) ;
  • impasses vérifiées vides : O4c-B0.else, O4c-B2.then, O4c-B3.then, O4c-R.then (aucun lien : un lien accidentel casserait le « passer au suivant ») ; O4c-L.Array Index sans lien ;
  • O4c-C1 et O4c-C2 typés double (A et B « Float (double-précision) », comme en B7a) ; B = 90 / 100 ; O4c-E typé chaîne (A et B).

Comptes O4c : 17 nœuds ; 1 coupure ; 26 liens ; 7 valeurs.

Variantes chiffrées (écartées par les décisions du 2026-10-14, gardées pour mémoire ; recalculées à partir de la version à Genital) :

Variante Effet Nœuds O4c Liens O4c GI:EventGraph (avec O4a)
Retenue garde + IsMale OU Genital == 'Penis' + deux seuils 17 26 6 273
Sans garde IsValid (Q4 = non, écartée) retirer O4c-V et O4c-B0 ; L.LoopBody → B1.execute 15 23 6 271
IsMale seul (Q2 = a, écartée) retirer O4c-N, T, E, O ; M.IsMale → B1.Condition 13 21 6 269
Hommes seuls (Q1 = b, écartée) retirer O4c-C2, O4c-B3, O4c-Pf ; B1.else ⊘ 14 21 6 270
Repli sans OU (si ORBoolean non créable) retirer O4c-O ; ajouter une Branche Bg : M.IsMale → B1.Condition ; B1.else → Bg.execute (Condition ← E.ReturnValue) ; Bg.then → B2.execute ; Bg.else → B3.execute ; B1.then → B2.execute 17 27 6 273

2.4 Comptes et résultat attendu de l'IMPL

O4a O4c Total
Nœuds créés 3 17 20
GI:EventGraph (N0 = 6 253) N0 + 3 N0 + 17 6 273
Coupures 1 1 2
Liens créés 6 26 32
set_pin_value 1 7 8
Gestes d'écriture attendus : 20 create_node + 2 break_pins + 32 connect_pins + 8 set_pin_value = 62, plus ≈ 12 lectures find_node_types et ≈ 8 get_node_infos : à budgéter pour l'IMPL (sk-protocol § 8, opération qui ne doit pas être coupée).
Inchangés (VAL) : toutes les autres fonctions de GI ; isSameAs 11, GetVariable 53, CallFunctionReturnBool 594, Action:EventGraph 363 (repris de ORG4S § 2.4 / H3gV:34, non relus aujourd'hui).

2.5 Comportement avant / après (cas nommés)

« Homme » = IsMale vrai OU Genital == 'Penis' (sans casse). « Non homme » = IsMale faux ET Genital différent de 'Penis' (autre valeur, texte vide compris).

Cas Avant Après
Endsex, homme (IsMale vrai) avec Sex_Orgasm >= 90 scène terminée, aucun bonus bonus (GiveOrgasmReward) puis fin identique ; marqueur … homme ×1
Endsex, personne non IsMale avec Genital == 'Penis' et Sex_Orgasm >= 90 fin, aucun bonus bonus ; marqueur … homme ×1 (V6-S6)
Endsex, homme (au sens de la règle) avec jauge < 90 fin fin identique ; 0 bonus ; 0 marqueur
Endsex, non homme avec jauge >= 100 fin bonus ; marqueur … femme — cas inatteignable en pratique (F4) ; branche écrite par fidélité à la décision (gardée)
Endsex, non homme avec jauge < 100 (cas réel de toute femme sans pénis) fin fin identique ; 0 bonus ; 0 marqueur
Ordre — index 0, puis 1, … de SexPersons (ordre du tableau, éventuellement trié par SortSexPersonsByGender, F12) ; GiveOrgasmReward est synchrone, un participant après l'autre
Un participant non éligible ou invalide — ne bloque pas les suivants : sa branche s'arrête dans une impasse, la boucle passe à l'élément suivant (F6)
SexPersons vide (cas non rencontré) Completed aussitôt → AfterCumSpeed : chemin d'aujourd'hui
Double bonus avec Finish / orgasme à 100 — impossible : (1) ces chemins appellent GI.Cum avec ForceEnd = false (F5b) et n'entrent pas dans la boucle ; (2) Person::Cum remet Sex_Orgasm à 0 avant son propre GiveOrgasmReward (F5), donc la personne n'est pas éligible à un Endsex suivant
Pas d'effet d'orgasme — pas de Person::Cum : pas de remise à 0 de la jauge, pas d'incrément de Sex_OrgasmCounts (F5 : l'incrément n'existe que dans Person::Cum), pas de particule ni de texte CumText, pas de secousse. Note pour ORG5 H1 : le sondage du compteur ne verra pas ce bonus (R7 d'ORG5S, accepté pour l'alpha, ORG5S:294)
Créatures (IsMale vrai, ou Genital de la créature : non lu) — traitées comme un homme si IsMale vrai ou Genital == 'Penis' ; GiveOrgasmReward leur est appliqué comme à un orgasme réel (même événement) ; effet de ModifyStat sur une créature non lu (estimé)
Jauge restée ≥ seuil après Endsex — pas de farm : la scène est défaite et UpdateSexLikes remet Sex_Orgasm à 0 au démarrage de la scène suivante (P-STG:15804-15812 ; ORG4S § 2.5)
PersonCumming None à Endsex 2 avertissements 0 (O4a)

2.6 Règle commune ORG4 / ORG5 (Big Boss, 2026-10-14, ORG4S:265-269) : comment O4c la tient

  1. Orgasme réel (Person::Cum) : GiveOrgasmReward 1× (chemin existant, F5) ; ORG5 1× déclenché par l'incrément de Sex_OrgasmCounts (accroche H1, ORG5S:298). O4c ne s'exécute pas sur ce chemin (ForceEnd = false, F5b) : 0× de plus.
  2. Endsex : GiveOrgasmReward 1× par participant éligible, sans Person::Cum ; Sex_OrgasmCounts inchangé (aucun nœud de GI ne l'écrit : 0 occurrence dans GI-P2, et O4c ne crée aucun nœud qui le nomme ; V5 le reverifie par Grep sur le dump d'après) donc 0 récompense ORG5 à Endsex.
  3. Participant qui vient de jouir : jauge à 0 (F5), donc non éligible à un Endsex suivant : pas de second bonus de base pour le même orgasme.
  4. Contrôle V6 : voir § 7 (S2, S4 et la dernière ligne du tableau) ; limite : le bonus de base d'un orgasme réel ne laisse aucune ligne de journal (Person non modifié, ModifyStat sans trace) : la règle « 1 marqueur de base par orgasme » n'est observable en journal que pour la voie Endsex (marqueurs O4c) ; pour la voie orgasme réel, la preuve est l'absence de marqueur O4c et le texte à l'écran (Q-ORG4c-5, décidée : pas de marqueur à l'orgasme réel).
  5. Condition de validité : toute IMPL d'ORG5 qui déplacerait son accroche vers GiveOrgasmReward (au lieu de l'incrément de Sex_OrgasmCounts) casserait le point 2 : à relire dans ORG5 avant l'IMPL (ORG5S:298-300).

3. Repli

  • Avant écriture : instantané .\Tools\Snapshot.ps1 -Lot STE-ORG4 (P3), MD5 de départ (P2).
  • Aucun save_assets tant que compile_blueprint n'est pas à 0 diagnostic. Échec avant enregistrement : fermer l'éditeur sans enregistrer, contrôler le MD5, rapporter. Aucun correctif improvisé.
  • Après enregistrement, lien relu différent, type_id introuvable (P5), nœud inattendu, impasse reliée par erreur, P0 contraire : arrêt, rapport ; puis, sur décision de l'orchestrateur, éditeur fermé : .\Tools\Restore.ps1 -Lot STE-ORG4 -Only Content\BPs\GI.uasset -WhatIf, puis sans -WhatIf ; MD5 = valeur de P2. Un Restore de GI rend l'état de l'instantané (G16 et B7-a conservés) ; aucune autre écriture de GI intercalée.
  • Repli de conception : (i) P0 contraire, ou Utilities|Array|ForEachLoop introuvable en création → O4a seul (3 nœuds, GI:EventGraph N0 + 3) et retour à l'orchestrateur ; (ii) Classe|Person|ObtenirIsMale, …ObtenirGenital ou …ObtenirSexOrgasm introuvable → arrêt (pas de repli par ObjectTools) ; (iii) le marqueur gêne → l'omettre (retirable, ignoré en Shipping), mais Q-ORG4-3 = oui impose son maintien ; (iv) Inférieurà(<) non créable ici → Supérieuràouégalà(>=) avec Branches inversées, sinon arrêt ; (v) ORBoolean non créable → cascade de deux Branches (variante « Repli sans OU », § 2.3) ; (vi) conversion Texte vers chaîne ou égalité de chaînes introuvables → comparaison de textes EqualEqual_IgnoreCase_TextText (précédent GI-P2:14321-14325, B à poser comme Texte) seulement sur décision de l'orchestrateur (nœud différent du précédent de Person), sinon arrêt.
  • Après commit (gardien) : git revert du commit du ticket. Couplage : GI.uasset est un binaire unique qui porte G16 et B7-a (R-ORG4-2 de ORG4S).

4. Risques R#, questions Q#

  • R-ORG4c-1 : ForceEnd = true de l'appel GI.Cum de SexAction déduit, non lu (ORG4S R-ORG4-1) → P0 bloquant ; V5 passerait même si faux, seul V6-S1 le révèle.
  • R-ORG4c-2 : la branche « non homme » (seuil 100) est sans effet réel (F4, estimé fort) ; V6 ne peut pas la rejouer ; sa justesse se vérifie en V5 (statique) seulement. Q-ORG4c-1 (gardée).
  • R-ORG4c-3 : type_id jamais créés ici (sept, voir l'Annonce) ; indices de la macro repris d'un nœud existant (H3gI:34), à confirmer sur le nœud créé ; type générique de Array Element à relire après le lien 2 (§ 2.1) ; conversion et égalité de chaînes à relever avec contexte (§ 2.1).
  • R-ORG4c-4 : le comportement « impasse dans le corps = élément suivant » est établi par un précédent du même graphe (GI-P2:7097, 11216-11218) mais le code de la macro n'est pas lu dans le moteur (§ 6). Si l'impasse arrêtait la boucle, V6-S5 (personne non éligible en index 0) le révélerait.
  • R-ORG4c-5 : deux ModifyStat affichés (NoDisplay faux, P-STG:16074-16087) à l'image même où EndSex défait la scène : textes éventuellement masqués ; l'effet sur la stat existe (ORG4S R-ORG4-4). Avec deux participants éligibles, deux textes dans la même image.
  • R-ORG4c-6 : GI.uasset partagé : G16, B7-a non commités dans le même binaire (ORG4S R-ORG4-2).
  • R-ORG4c-7 : tableau modifié pendant l'itération : GiveOrgasmReward n'appelle aucun nœud de GI (F11), donc ne touche pas SexPersons (estimé) ; la relecture de la longueur par la macro n'est pas lue (§ 6) : incertain, sans conséquence attendue.
  • R-ORG4c-8 : dumps périmés : PC ( M depuis ORG4S) et Person (dump 14:08, dernière sauvegarde 17:42, ORG4S R-ORG4-8) : P7 et V6 couvrent la chaîne GiveOrgasmReward.
  • R-ORG4c-9 : articulation ORG5 : voir § 2.6 point 5 et R7 d'ORG5S ; si ORG5 ajoute une grille à GiveOrgasmReward (ORG4S R-ORG4-6), elle s'ouvrirait à l'image de la fin de scène, une fois par participant éligible.
  • R-ORG4c-10 : deux libellés de marqueur (homme, femme) au lieu du libellé unique de Q-ORG4-3 ; le préfixe commun ORG4 bonus Endsex est conservé : le motif de V6 d'ORG4S reste valable. homme désigne le groupe du seuil 90 (IsMale OU pénis), pas le sexe d'état civil : une personne non IsMale à pénis écrit un marqueur homme (V6-S6).
  • R-ORG4c-11 : exception à lp-mcp § 1 règle 4 (OU pur O4c-O) : sûre parce que O4c-B0 précède et que les deux opérandes sont des lectures pures sur l'élément validé ; si O4c-B0 était retirée (variante écartée), la règle 4 s'appliquerait de nouveau (lectures IsMale et Genital sur un élément possiblement nul). Repli sans OU prévu (§ 2.3, § 3 v).
  • R-ORG4c-12 : Genital est un Texte relu sans casse ; toute autre valeur que 'Penis' (autre mot, texte localisé, vide) vaut « non homme » : même comportement que « Close to cumming » (F2, F15) ; la valeur réelle de Genital pour les créatures et pour les personnages importés d'un mod n'est pas lue.

Décisions reçues (2026-10-14) et questions restantes

  • Q-ORG4c-1 — seuil « femme = 100 » : décidé : gardé tel quel (branche sans effet en pratique, F4, acceptée). Options écartées : hommes seuls (3 nœuds de moins), autre seuil.
  • Q-ORG4c-2 — définition de « homme » : décidé : IsMale OU Genital == 'Penis', la règle de « Close to cumming » (F2, F13). Intégrée aux § 2.3 à 2.5 et 7 (+4 nœuds : Genital, conversion, égalité, OU). Conséquence assumée : une personne non IsMale à pénis suit le seuil 90 ; une femme sans pénis suit le seuil 100 (donc jamais de bonus à Endsex, F4).
  • Q-ORG4c-3 — « dépasse » : décidé : >= 90 et >= 100, réalisés par < + sortie else (§ 2.1).
  • Q-ORG4c-4 — garde IsValid par élément : décidé : oui (O4c-V, O4c-B0 ; lp-mcp § 1 règle 4 réserve normalement IsValid aux cas où « vide » est normal, la garde est ici prudentielle et sert aussi la sûreté du OU, R-ORG4c-11).
  • Q-ORG4c-5 — observabilité : décidé : deux libellés homme / femme, pas de marqueur à l'orgasme réel (Person non modifié) ; la preuve du bonus de base d'un orgasme réel reste le texte à l'écran.
  • Q-ORG4c-6 (orchestrateur) — UE-GO pour P0 (dump de SexAction), puis pour l'IMPL ; gel annoncé ; ticket du gardien (R-ORG4c-6) ; budget d'IMPL ≈ 62 écritures + lectures (§ 2.4). Reste ouverte.
  • Q-ORG4c-7 (utilisateur, nouvelle, facultative) — existe-t-il, au chargen, un personnage non IsMale avec Genital = 'Penis' rejouable en V6-S6 (F16 : le jeu le prévoit, sa création n'est pas lue) ? Sinon S6 est « non rejoué » et la preuve est statique (V5).

5. Interdits

  • Aucune modification de Person (aucun save_assets de Person), SexAction, PC, GetVariable, CallFunctionReturnBool, isSameAs, Action, C++, scènes et modules ; aucune autre branche de GI::Cum que IfThenElse_875.then ; AfterCumSpeed modifié par O4a seulement (3 nœuds).
  • Pas d'appel de Person::Cum depuis GI ; aucune écriture de Sex_Orgasm, Sex_OrgasmCounts, Genital, IsMale ni PersonCumming par O4c ; aucun FunctionResult créé ; pas de delete_node ; pas de AND / Select purs, ni d'OR pur hors O4c-O (exception décidée, R-ORG4c-11) ; pas de type_id non relu (P5) ; pas d'écriture HyperAIStudio (lp-mcp § 1 règle 1) ; outils Epic seulement.
  • Aucun lien sur les impasses O4c-B0.else, O4c-B2.then, O4c-B3.then, O4c-R.then.
  • Pas d'IMPL sans P0 conforme, sans P1 à P7, ni entrelacée avec une autre écriture sur GI ; pas de commit par l'agent (ticket au gardien, lp-repo).

6. Valeurs moteur lues dans le moteur installé (UE = D:\Game\Launcher\Engine\UE_5.8\Engine\Source\)

Relu aujourd'hui :

  • UKismetSystemLibrary::PrintString(const UObject* WorldContextObject, const FString& InString, bool bPrintToScreen = true, bool bPrintToLog = true, FLinearColor TextColor, float Duration = 2.f, const FName Key) est DevelopmentOnly : UERuntime\Engine\Classes\Kismet\KismetSystemLibrary.h:565-566 (le marqueur est ignoré en Shipping, joué en Development) ; les paramètres de ce fichier correspondent aux broches relevées en H5bC:17-18.
  • UKismetStringLibrary::EqualEqual_StriStri(const FString& A, const FString& B) rend FCString::Stricmp(*A, *B) == 0 (insensible à la casse) : UERuntime\Engine\Private\KismetStringLibrary.cpp:34-37; déclarationmeta=(DisplayName = "Equal, Case Insensitive (String)", CompactNodeTitle = "=="), catégorie Utilities|String:UERuntime\Engine\Classes\Kismet\KismetStringLibrary.h:285-286. Non lu (donc estimé, pas établi) :
  • Le code de la macro ForEachLoop (asset de macros du moteur, binaire) : « un corps qui s'arrête dans une impasse passe à l'élément suivant » n'est établi que par l'usage du graphe de GI (GI-P2:7097, 11216-11218) ; « la longueur du tableau est relue à chaque tour » non lu.
  • Less_DoubleDouble / FClamp : seules les formes de nœuds des dumps sont lues (F3). Conv_TextToString (KismetTextLibrary) : seul le nœud des dumps est lu (F13). Repris d'ORG4S § 6 (relus le 2026-10-13, non relus aujourd'hui) : IsValid(const UObject*) = non nul et non en attente de destruction (KismetSystemLibrary.h:126-128).

7. Critères de VAL (commande → attendu), V5 et V6 mis à jour

V5 — VAL statique (éditeur fermé, .\Tools\UeState.ps1 -Kind Editeur = 0)

  1. Dump : .\Tools\RunCommandlet.ps1 -Lot STE-ORG4V -Commandlet LPDumpFunction -Args '-BP=GI -Fn=EventGraph -Pins -Exec' -EtatDir "D:\Game\LifePlay-master 5.8\Docs\Migration\etat\ST\STE" → en-tête === GI :: EventGraph (6273 noeuds) === (6271 sans garde, 6269 IsMale seul, 6270 hommes seuls : variantes écartées) ; et (Grep en nommant le fichier, les .txt de etat\ étant ignorés par ripgrep) :
    • O4a : critères de ORG4S § 7 V5.1 (première puce) inchangés (CustomEvent_702.then → O4a-B.execute seul, O4a-B.else → O4a-S.execute, Rate = 0.25, VariableGet_720.PersonCumming → 3 cibles, Condition reliée) ;
    • O4c : IfThenElse_875.then → O4c-L.Exec seul ; IfThenElse_875.else → MacroInstance_18.exec inchangé ; CallFunction_11423.execute ← 3 sources (O4c-L.Completed, CallFunction_32955.then, IfThenElse_189.then) ; O4c-L.Array ← VariableGet_3498.SexPersons (qui garde GetArrayItem_1037.Array) ; O4c-L.Array Element → 5 cibles (O4c-V.Object, O4c-M.self, O4c-N.self, O4c-G.self, O4c-R.self) ; O4c-L.LoopBody → O4c-B0.execute ; O4c-B0.then → O4c-B1.execute ; condition du sexe : O4c-N.Genital → O4c-T.InText ; O4c-T.ReturnValue → O4c-E.A ; O4c-E.B = Penis (à l'octet) ; O4c-M.IsMale → O4c-O.A ; O4c-E.ReturnValue → O4c-O.B ; O4c-O.ReturnValue → O4c-B1.Condition ; O4c-B1.then → O4c-B2.execute, O4c-B1.else → O4c-B3.execute ; O4c-C1.A et O4c-C2.A ← O4c-G.Sex_Orgasm ; O4c-C1.B = 90, O4c-C2.B = 100 ; O4c-B2.else → O4c-Ph.execute, O4c-B3.else → O4c-Pf.execute ; O4c-Ph.then et O4c-Pf.then → O4c-R.execute ; O4c-R.self ← O4c-L.Array Element ; impasses O4c-B0.else, O4c-B2.then, O4c-B3.then, O4c-R.then : aucun lien ; les 4 Branches ont leur Condition reliée ; InString des deux marqueurs à l'octet (ORG4 bonus Endsex homme / … femme), bPrintToScreen faux ; O4c-E affiché KismetStringLibrary::EqualEqual_StriStri(), O4c-T KismetTextLibrary::Conv_TextToString(), O4c-O KismetMathLibrary::BooleanOR().
    • Comptes relatifs au dump P1 (mêmes Grep, fichier nommé) : macro 'ForEachLoop' +1 (GI-P2 : 79 lignes, baseline P1 à refaire) ; GiveOrgasmReward 0 → 1 ; PrintString +2 ; variable 'IsMale' +1 (GI-P2 : 25) ; variable 'Genital' +1 (baseline P1) ; Conv_TextToString +1 ; EqualEqual_StriStri +1 ; BooleanOR +1 ; variable 'Sex_Orgasm' 0 → 1 ; Sex_OrgasmCounts 0 → 0 (aucune occurrence dans GI avant, aucune après : règle commune § 2.6 point 2) ; aucun appel …::Cum() nouveau.
    • Non-régression (un par un) : -Fn=isSameAs → 11 ; -Fn=GetVariable → 53 ; -Fn=CallFunctionReturnBool → 594 ; -BP=Action -Fn=EventGraph → 363.
  2. Diff indépendant : python -I Tools\DiffRemplacementNoeuds.py <dump P1> <dump après> <profil> → seuls les nœuds et liens des § 2.2-2.4 ; « pins modifiés sur nœuds communs » = 7 : CustomEvent_702, VariableSet_9760, CallFunction_960, VariableGet_720 (O4a), IfThenElse_875, CallFunction_11423, VariableGet_3498 (O4c) — la chaîne Genital ne touche aucun nœud existant (elle part de O4c-L.Array Element) ; GetArrayItem_1037 n'est plus touché (il l'était avec O4b : 8 nœuds en ORG4S) — et aucun autre.
  3. Compilation : compile_blueprint … warnings_as_errors:true → null, journal de l'éditeur sans Error / Warning pour GI ; CompileAllBlueprints éditeur fermé : 0 erreur (critère requalifié le 2026-10-13, ORG4S § 7) ; LPTestStringCompat 3120 / 0 / 60 (lp-validate).
  4. Empreintes : md5sum Content/BPs/GI.uasset noté ; Person.uasset = 8668a47c627f7a5254910cf0ac33b12a et SexAction.uasset = a8705f7fbe1fde1daba0464bfc9ff9b5 inchangés ; Room et PC : valeur relevée à l'entrée = à la sortie ; git status --short -- Content : aucun fichier de plus que M GI, Person, Room, PC.

V6 — essai en jeu (build Development empaqueté par BUILD, même ligne de commande que HJ : -ScriptStackOnWarnings -LPHitchLog ; UE-GO / BUILD-GO de l'orchestrateur)

Ce que le journal montre / ne montre pas : les marqueurs O4c sont les seules lignes de journal du bonus (ModifyStat ne laisse aucune ligne, ORG4S § 7 V6) ; l'effet sur les stats se voit à l'écran (texte de ModifyStat) et est rapporté par l'utilisateur. Les lignes ORG5 (Bonus : orgasme de <nom> (compteur <n>), ORG5S:134) n'existent que si ORG5-I1 est dans le build ; sinon, les contrôles ORG5 sont sans objet : ORG5-I1 absent du build. Parcours à jouer (une scène avec le joueur ; noter pour chaque participant son IsMale et son Genital, et qui est SexPersons[0]) :

  • S1 (bonus homme) : scène MF ; laisser l'homme (IsMale vrai) entre 90 et 100 (texte rouge « Close to cumming… » visible), la femme sous 100 ; cliquer « Finish having sex ». Attendu : fin dans la même image ; texte de stat du bonus pour l'homme (mood +20 si c'est le joueur, attractiontoplayer sinon), rien pour la femme ; 1 marqueur … homme, 0 … femme.
  • S2 (femme qui vient de jouir) : scène MF ; laisser la femme atteindre 100 (orgasme automatique, jauge remise à 0), l'homme ≥ 90 ; cliquer « Finish having sex » aussitôt. Attendu : 1 marqueur … homme, 0 … femme ; si ORG5 : 1 ligne Bonus : orgasme de <femme> (l'orgasme réel), située avant la ligne Endsex (Animation String) de S2. Remplace le parcours « les deux ≥ seuil » de la fiche : une femme à 100 ne peut pas exister au moment du clic (F4).
  • S3 (témoin sous le seuil) : démarrer une scène, cliquer « Finish having sex » aussitôt (jauges < seuils). Attendu : fin de scène ; 0 marqueur ; 0 ligne ORG5 ; 0 avertissement.
  • S4 (pas de double bonus avec Finish) : homme ≥ 90 ; choisir une animation « Cum on … » (Person::Cum : bonus de base 1×, ORG5 1×), puis « Finish having sex » aussitôt. Attendu : 0 marqueur O4c (jauge remise à 0) ; si ORG5 : exactement 1 ligne Bonus : orgasme de <homme> (celle du Cum), avant la ligne Endsex.
  • S5 (un non-éligible ne bloque pas) : scène où l'index 0 est sous le seuil et l'index 1 au-dessus (par exemple MM, l'un < 90, l'autre ≥ 90) ; cliquer « Finish having sex ». Attendu : 1 marqueur … homme (le second) ; fin de scène normale. Si aucune scène MM n'est disponible : noter « non rejoué » (la preuve statique est V5).
  • S6 (personnage à pénis non IsMale, décision Q2) : scène avec un personnage IsMale faux et Genital = 'Penis' (femme à pénis : scène FF avec l'étiquette Shemale, ou MF dont la partenaire a un pénis ; le jeu le prévoit, F16 ; création au chargen non lue, Q-ORG4c-7) ; l'autre participant est une femme sans pénis, sous 100. Laisser le personnage à pénis entre 90 et 100 (texte « Close to cumming… » visible si c'est l'index 0 d'une scène filtrée FF avec Shemale ou MF, P-STG:17376-17417), cliquer « Finish having sex ». Attendu : 1 marqueur … homme (le personnage à pénis, seuil 90), 0 … femme ; texte de stat du bonus pour lui seul. C'est la seule preuve en jeu que le côté droit du OU (Genital) fonctionne seul, IsMale étant faux. Si le personnage ne peut pas être obtenu : noter « non rejoué » (V5 prouve les liens ; le dump montre Conv_TextToString et EqualEqual_StriStri sur Penis). Greps sur le journal du jeu (mode count, fichier nommé ; base = HJ de ORG4S) :
    Motif Attendu
    Endsex \(Animation String\) 6 (un par scène S1 à S6) — preuve que le parcours est rejoué (sans elle, un 0 ne prouve rien) ; 5 si S6 non rejoué
    ORG4 bonus Endsex homme 4 (S1, S2, S5, S6) ; 3 si S6 non rejoué
    ORG4 bonus Endsex femme 0 (branche non rejouable, R-ORG4c-2)
    ORG4 bonus Endsex (préfixe) 4 (= somme) ; 3 si S6 non rejoué
    Bonus : orgasme de (si ORG5-I1) 2 (S2 femme, S4 homme), et aucune ligne de ce motif après une ligne Endsex (Animation String) avant le début de la scène suivante (Grep -n des deux motifs, comparer les numéros de ligne) : un clic Endsex ne produit jamais de ligne ORG5
    Accessed None trying to read \(real\) property PersonCumming 0 (HJ : 2)
    GiveOrgasmReward|OrgasmIrBoost (piles d'avertissement) 0
    Accessed None avec Genital ou IsMale (nouvelles lectures de O4c) 0
    fatal|Unhandled|Critical|Assertion 0
    LogScript: Warning: Accessed None ≤ 11 (indicatif, HJ : 13)
    Non-régression : .\Tools\LogStats.ps1 -Compare <journal>,<HJ> : aucune famille nouvelle ; G13 et G16 intacts.
    Règle commune (ORG4 / ORG5) : le contrôle est la combinaison de S2, S4 et de la dernière ligne ORG5 du tableau : un clic Endsex = au plus 1 marqueur par personne et 0 ligne ORG5 ; un orgasme réel = 1 ligne ORG5 par personne et 0 marqueur O4c ; le bonus de base d'un orgasme réel n'a pas de marqueur (§ 2.6 point 4) : observé à l'écran seulement.
    Limites : la branche « non homme » (seuil 100) n'est pas rejouée ; l'effet réel des stats n'est vu qu'à l'écran ; le cas « élément invalide dans SexPersons » n'est pas rejoué ; l'ordre des index n'est pas lu (S5 l'observe) ; S6 dépend de la disponibilité d'un personnage à pénis non IsMale.

Fichiers à commiter (dépôt jeu, branche ue5.8, ticket au gardien) :

  • A Docs/Migration/etat/ST/STE/STE-ORG4c-SPEC.md

Tours : 35 / 47 (35 de la fiche + 12 de prolongation demandés par l'orchestrateur ; compte de l'agent : 30 pour la SPEC initiale, 5 pour le complément Q2, remise du compte rendu comprise ; python -I Tools/FicheStats.py --lot STE fait foi)

Constats

  • Lecture seule respectée ; un seul fichier écrit (ce livrable, non suivi). Aucun nom d'utilisateur ni chemin de profil cité. Aucun > dans les commandes Bash ; aucun refus du crochet ecriture-gardien rencontré.
  • Méthode du complément : l'orchestrateur demandait un complément « par Edit, sans réécrire le fichier » ; l'agent lp-cart n'a pas l'outil Edit (sk-protocol § 7 : un seul Write complet, correction = Write complet). Le complément Q2 a donc été fait par un Write complet qui conserve le texte existant (dont la section « Décisions de l'utilisateur » ci-dessous, reprise à l'identique) et ne modifie que : titre, Annonce, F2, F13 à F16, § 1.3, P1, P4, P6, P7, § 2.1, § 2.3 à 2.5, repli § 3 (v, vi), R-ORG4c-2/3/10 à 12, Q#, § 5, § 6, § 7 (V5, V6 : S6 ajouté).
  • Établi : F1 (variable IsMale), F2, F3, F5, F5b, F6 (précédent de corps en impasse), F8, F9 (types créés), F13 (précédent exact de la chaîne Genital dans Person et dans GI), F14 (ORBoolean créé en Room), F15 (insensible à la casse, lu dans le moteur), la règle commune (ORG4S:265-269) et ses points d'appui dans P-STG. Estimé : F4, conclusion « 100 inatteignable à Endsex » (écrivains de Sex_Orgasm lus dans les graphes dumpés seulement ; fonctions annexes de Person et mods non lus) ; comportement des créatures ; ordre d'index. Incertain (essai qui tranche) : création de Utilities|Array|ForEachLoop et des six autres type_id jamais créés (find_node_types en P5 / P7, avec contexte pour la conversion et l'égalité) ; valeur ForceEnd de SexAction (P0) ; relecture de la longueur de tableau par la macro (V6-S5) ; existence rejouable d'un personnage à pénis non IsMale (V6-S6, Q-ORG4c-7).
  • Pièges Grep : les .txt de etat\ sont ignorés par ripgrep même avec le dossier en path : nommer le fichier (rappel, ORG4S « Constats »). Les dumps PC et PASA portent le préfixe LogLPDump: Warning: sur chaque ligne ; un motif non ancré fonctionne. Un dump -Pins -Exec contient deux blocs à en-tête identique : les comptes de lignes d'un Grep portent sur les deux.
  • Hors périmètre, noté : GI::EndSex donne mood +50 / arousal -50 à chaque participant indépendamment de l'orgasme (F-ORG2, ORG4S « Constats »).

Décisions de l'utilisateur (2026-10-14, session STE)

  • Q-ORG4c-1 : seuil femme 100 gardé tel quel (branche sans effet en pratique, accepté).
  • Q-ORG4c-2 : homme = IsMale OU Genital == 'Penis' (même règle que « Close to cumming ») : la SPEC est à compléter (nœuds en plus).
  • Q-ORG4c-3 : >= 90 (et >= 100).
  • Orchestrateur : Q-ORG4c-4 garde IsValid par élément oui ; Q-ORG4c-5 deux libellés, pas de marqueur à l'orgasme réel ; Q-ORG4c-6 IMPL sous UE-GO avec P0.
  • Intégration (agent lp-cart, 2026-10-14) : Q-ORG4c-2 complétée dans les § 1.3, 2.1, 2.3, 2.4, 2.5, 3, 4, 7 ; totaux O4a + O4c = 20 nœuds, 2 coupures, 32 liens, 8 valeurs, GI:EventGraph 6 273.
  • Q-ORG4c-7 (utilisateur, 2026-10-14) : oui, un personnage non IsMale avec pénis peut être créé en jeu : le parcours S6 est rejoué en V6 (attendus : 6 clics Endsex, 4 marqueurs homme, 0 femme).

P0 levé (orchestrateur, 2026-10-14)

  • Dump dumps\SexAction__EventGraph_P0.txt (310 nœuds, SexAction A8705F7F, journal Saved\Logs\portage\STE-ORG4_LPDumpFunction_20261014-015407.log) : SwitchString_0.Endsex → K2Node_CallFunction_8 = GI_C::Cum() avec ForceEnd = 'true' (l. 73, 232-236). Hypothèse établie : O4a + O4c exécutables.