LifePlay-Revival/Docs/Migration/etat/ST/STE/STE-ORG4-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

45 KiB
Raw Blame History

Fiche STE-ORG4 — Niveau N3 — Modèle prévu (modèle de l'agent lp-cart) | utilisé claude-sonnet-5-5 — Agent lp-cart — Skills lp-mcp (invoqué : § 1, 3, 4), sk-protocol (préchargés avec l'agent : ue-cpp-build, lp-commandlets, lp-paths)

STE-ORG4-SPEC : fin de scène par Endsex — bonus d'orgasme absent et lecture de PersonCumming à None (2026-10-14)

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 = § 1 ; fichiers et ordre, préalables, correctif au geste près, garde, comportement = § 2 (2.0 à 2.5) ; repli = § 3 ; risques et Q# = § 4 ; interdits = § 5 ; critères V5 / V6 = § 7. Lecture seule stricte (Read, Grep, Glob ; Bash pour git rev-parse, md5sum, git status, git log, ls, grep -a -c sur un binaire) ; aucun éditeur, MCP, commandlet, build ni jeu ; un seul fichier écrit : ce livrable.

Annonce en tête (fiche, rubrique 3)

  • Person n'est pas touché par le correctif (aucune écriture, aucun save_assets de Person) : il appelle l'événement existant GiveOrgasmReward de Person (lecture de son nom seulement). Pas d'annonce à Big Boss pour Person.
  • GI est touché (Content\BPs\GI.uasset, graphe EventGraph seul) : le fichier contient déjà deux changements non commités d'autres lots (G16 de STE-H3g, B7-a de STG ; § 2.0). SexAction (UI/SexAction.uasset) n'est pas touché mais sa lecture (P0) est bloquante pour la partie O4b (§ 2.0).
  • Statut : exécutable par MCP en deux parties : O4a (garde PersonCumming, sans changement de comportement) est complète et indépendante ; O4b (bonus à Endsex, changement de comportement voulu) est complète sous la condition P0 (lecture de SexAction) et sous la réponse Q-ORG4-1 de l'utilisateur.

Abréviations (chemins absolus) :

  • E = D:\Game\LifePlay-master 5.8\Docs\Migration\etat\ ; GI-P2 = EST\STE\dumps\GI__EventGraph_P2.txt (2026-10-13 16:36, GI c4817b84, 6 249 nœuds) ; P-STG = EST\STG\dumps\Person__EventGraph.txt (2026-10-13 14:08) ; PC-STE = EST\STE\dumps\PC__EventGraph.txt (2026-10-10 11:33) ; PASA = EST\STA\dumps\GI__PlayAppropriateSexAnimation.txt (préfixe LogLPDump: Warning: sur chaque ligne) ; L6f-G = Eportage55\L6f\L6f_dump_GI.txt (5.5, 2026-09-30).
  • HJ = EST\STE\STE-H3e-J\LifePlay.log (journal H3e, ligne de commande -ScriptStackOnWarnings -LPHitchLog) ; J6 = D:\Game\LifePlay_Build_5.8_STE-J6_Development\Windows\LifePlay\Saved\Logs\LifePlay.log.
  • AUD = EST\STE\STE-ORG-AUDIT.md ; H3fD = STE-H3f-DIAG.md ; H3gS / H3gI / H3gV = STE-H3g-SPEC.md / -IMPL.md / -VAL.md ; H3dI = STE-H3d-IMPL.md (tous dans EST\STE\) ; B7aI = EST\STG\STG-B7a-IMPL.md ; UE = D:\Game\Launcher\Engine\UE_5.8\Engine\Source\.

État relevé à l'entrée de cette SPEC (C9a de la fiche ; Bash, lecture)

Commande Sortie
git rev-parse --short HEAD 0745917
md5sum Content/BPs/GI.uasset e64b5b37c9ef0db7735de0d6e3bd7c1c
md5sum Content/BPs/Person.uasset 8668a47c627f7a5254910cf0ac33b12a
md5sum Content/BPs/Room.uasset 18565365b1195bf2416a1048bf9051b6
md5sum Content/UI/SexAction.uasset a8705f7fbe1fde1daba0464bfc9ff9b5
md5sum Content/BPs/PC.uasset a19510e613f31905437bab48f38c6154
git 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, Person, Room ; SexAction et PC non listés (= HEAD)

Historique de GI (établi) : c4817b84 (dump GI-P2, EventGraph 6 249 nœuds) → G16 de STE-H3g → 0E6AEDCC (EventGraph 6 253 nœuds, H3gV:13, 29 ; G16 ne modifie que 7 nœuds communs, tous dans UpdateDefaultHair, H3gV:32) → B7-a de STG, fonction Show seule (B7aI:9, 104-110) → e64b5b37 (valeur actuelle). Nœuds du chemin Cum qui pourraient avoir changé de nom : aucun (établi : H3gV:32 liste les seuls nœuds modifiés par G16, aucun n'est sur le chemin ; B7a n'a pas touché l'EventGraph) ; le dump GI-P2 reste donc valable pour tout ce qui suit, sauf les noms des nœuds à créer (attribués par l'éditeur : à relever). Exiger tout de même P1 / P2 à l'IMPL (§ 2.0). Dates (établi, ls -l --time-style=long-iso) : Person.uasset modifié le 2026-10-13 à 17:42, après le dump P-STG (14:08) : les nœuds de Person cités ci-dessous (chaîne Cum / GiveOrgasmReward) viennent d'un dump antérieur à la dernière sauvegarde de Person (STG G-B1a, K8-a : B239E103… → 8668A47C…) ; ces écritures visent d'autres fonctions (estimé) ; P7 le re-vérifie en lecture. PC-STE (10-10) précède le commit CAM-B1 qui a touché PC (git log, a08c134) : les lignes de PC citées sont descriptives, elles ne conditionnent pas le correctif.

1. Objectif mesurable

1.1 Cause exacte (chemins Finish, auto-100, Endsex : où ils divergent)

Person::Cum est le seul écrivain de PersonCumming : VariableSet_211 (PersonCumming := self, self du Set = GI) P-STG:17592-17599, suite de l'événement Cum de Person (P-STG:15920-15922). Dans l'EventGraph de GI : 0 écriture, 1 lecteur (Grep PersonCumming sur GI-P2 → VariableGet_720 et ses deux lectures de membres, GI-P2:28040-28062). Autres graphes de GI : non lus (§ 4, L-PC).

Chemin Séquence (fichier:ligne) Person::Cum appelé ? PersonCumming
Auto 100 UpdateOeChange → Sex_Orgasm == 100.0 → Cum() (P-STG:16030-16043) oui écrit (P-STG:17592)
Finish (« Cum on … ») PC propose les animations Finish si Sex_Orgasm >= 90 de SexPersons[0] (PC-STE:6075-6092, 6123-6142) → PASA : Array_Contains(Tags,'Finish') → Person_C::Cum() sur Persons[0] (PASA:348-361, 85-90) oui écrit
Endsex PC crée le widget d'action avec Animation = 'Endsex' et le libellé SelectString('Finish showering','Finish having sex') (PC-STE:2476-2485, 2668-2673) → clic : SexAction imprime Endsex (Animation String) (HJ:9242) → pile SexAction:BndEvt…OnButtonClicked → ExecuteUbergraph_SexAction → GI_C:cum → ExecuteUbergraph_GI → AfterCumSpeed (HJ:9246-9252) non jamais écrit sur ce chemin
Exhausted Exhausted → StopUpdateOeForSexPersons → SetText → GI.Cum(NoPregCheck true, NoEnd false, NoShake true) (P-STG:15993-16016) non (aucun VariableSet_211 dans cette chaîne) non écrit (même défaut)

Cause (établi pour les nœuds, estimé pour la valeur des broches de l'appel de SexAction) : GI::Cum (événement K2Node_CustomEvent_4245, GI-P2:10803-10809) n'est pas l'événement d'orgasme : c'est le traitement d'après-orgasme / de fin de scène que Person::Cum appelle lui-même (GI.Cum(NoEnd = true), P-STG:15936-15973) ; le bouton Endsex l'appelle directement, sans passer par Person::Cum. Ni GiveOrgasmReward ni l'écriture de PersonCumming ne sont donc atteintes. Les 22 nœuds atteints depuis GI::Cum (AUD § 2, parcours d'exécution) ne contiennent ni Person::Cum ni GiveOrgasmReward ; relu aujourd'hui, seul appelant de Person_C::Cum / GiveOrgasmReward dans GI-P2 : aucun (Grep appel [A-Za-z_?]+::(Cum|EndSex|AfterCumSpeed|GiveOrgasmReward)\(\) → GI-P2:10840 ?::Cum() (ancien modèle), 10905 AfterCumSpeed, 14564 EndSex seulement). Même pile en 4.27 (H3fD:74) : ce n'est pas une régression de portage, c'est la conception d'origine : Endsex n'est pas un orgasme.

Valeur de PersonCumming à Endsex (estimé) : None si personne n'a joui depuis le début de la partie (HJ:9243, 9262 : 2 avertissements pour 1 clic) ; périmée mais valide (dernier jouisseur) sinon, car aucune écriture de remise à zéro dans l'EventGraph de GI (explique J6:2849 : un Endsex, aucune ligne PersonCumming — le Grep de J6 sur Endsex|PersonCumming|Accessed None ne rend aucune ligne PersonCumming).

Chemin Endsex dans GI, avec l'hypothèse ForceEnd = true (estimé fort, § 4 R-ORG4-1) : CustomEvent_4245 → IfThenElse_172 (CondomBroke, GI-P2:27020-27024 ; else → VariableSet_329, 27003-27008) → IfThenElse_98 (SexOn, 22660-22667 ; else vide) → IfThenElse_875 (Condition = ForceEnd, then → CallFunction_11423, else → MacroInstance_18, 14554-14558) → CallFunction_11423 = appel de l'événement AfterCumSpeed (10905-10908) → CallFunction_76765 StopDirtyTalkAndDescription → 32952 DirtyTalkEnd → 32953 DescriptionEnd (10810-10821) → IfThenElse_188 (BooleanOR(ForceEnd, NoPregCheck, NoShake), 27663-27667, 27914-27919 ; vrai → saute CheckConceived) → CallFunction_38905 PC::StopUpdateSpeed (10825-10828) → IfThenElse_876 (ForceEnd, then → CallFunction_4939 EndSex(), 14559-14567). AfterCumSpeed (événement CustomEvent_702, 10896-10898) : VariableSet_9760 Rate ← SelectFloat(A = 0.0, B = 0.25, bPickA = StartsWith(Race(PersonCumming),'Dog') AND IsMale(PersonCumming)) (10899-10904 ; 28034-28062) puis CallFunction_960 UpdateOeDisplayOnly(Feedback = false) (27658-27662) puis la boucle MacroInstance_806 sur SexPersons (7094-7100). Preuves que Endsex suit cette branche : (a) aucun appelant dumpé (GI 5.8 et 5.5, Person 5.8 et 5.5, PC, SexInterface, Scène 5.5, Room) ne passe ForceEnd = true : GI-P2:10844 (false) ; L6f-G:58598 (false) ; Person 5.5 : false ×3 (Eportage55\L6f\L6f_dump_Person.txt:37160, 37168, 37202) ; PC, SexInterface, Scène, Room : 0 occurrence ; (b) la scène se termine dans la même image que le clic (HJ:9281-9296, image 883 : remise en place des personnes et des meubles), alors que le chemin à minuterie (NoEnd faux) retarde EndSex de 10 s (GI-P2:10829-10839) ; (c) SexAction.uasset contient la chaîne Endsex (2 lignes), ForceEnd (1), NoPregCheck (1), PlayAppropriateSexAnimation (1) (grep -a -c) : le widget compare l'animation à Endsex, appelle Cum et PlayAppropriateSexAnimation. Ce qui n'est pas lu : les valeurs des broches de l'appel GI.Cum dans SexAction (aucun dump de SexAction n'existe : Glob E**\*SexAction* → aucun fichier). D'où P0.

1.2 Objectifs mesurables (deux parties)

  • O4a — garde PersonCumming (sans changement de comportement) : les 2 lignes LogScript: Warning: Accessed None trying to read (real) property PersonCumming in /Game/BPs/GI.GI_C par clic Endsex (HJ:9243, 9262) → 0. GI:EventGraph : N0 → N0 + 3 nœuds (N0 attendu 6 253, H3gV:29).
  • O4b — bonus à Endsex (changement de comportement voulu, Q-ORG4-1) : à Endsex, SexPersons[0] reçoit GiveOrgasmReward si et seulement si sa jauge Sex_Orgasm ≥ 90 (même éligibilité que l'animation Finish, PC-STE:6128-6142) ; personne d'autre, rien en dessous de 90, pas d'effet d'orgasme (pas de Person::Cum). GI:EventGraph : + 8 nœuds (+ 1 marqueur de trace si Q-ORG4-3 = oui).
  • Total attendu : GI:EventGraph N0 + 11 (6 264) sans marqueur, N0 + 12 (6 265) avec ; 2 coupures ; 22 liens (23) ; 2 valeurs posées (4) ; MD5 de Person et de SexAction inchangés.

2. Fichiers touchés, ordre

Un seul fichier : Content\BPs\GI.uasset, graphe EventGraph (événements AfterCumSpeed et Cum). Ni Person, ni SexAction, ni PC, ni le C++, ni les scènes, ni les modules. Ordre : P0 à P7 → O4a → O4b → compile_blueprint → save_assets unique → fermeture de l'éditeur. O4a et O4b dans une seule session MCP, un seul instantané, un seul save_assets (comme H3g § 2). Si P0 contredit l'hypothèse ForceEnd, ou si Q-ORG4-1 = (a), exécuter O4a seul (§ 3).

2.0 Préalables

  • P0 (bloquant pour O4b ; lecture, UE-GO de l'orchestrateur) — dump du gestionnaire de clic de SexAction (lecture L1 de AUD § 5, jamais faite), é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" (le résolveur de -BP a trouvé Action sous UI/ pour Action__EventGraph_P2.txt ; pour SexAction : non essayé). Attendu : sur le chemin de la comparaison avec 'Endsex', un nœud d'appel GI_C::Cum avec ForceEnd = 'true', et aucun appel direct de GI_C::EndSex. Écart (ForceEnd faux, ou EndSex appelé par le widget, ou plusieurs appels) : arrêt, rapport ; O4b n'aurait aucun effet (V5 passerait, V6-S1 échouerait) ; ancre de repli à spécifier d'après ce dump.
  • P1 (dump à l'entrée) : MD5 de GI à l'entrée. Si e64b5b37… : le dump GI-P2 + H3gV:32 suffisent pour les liens du chemin Cum, mais refaire le dump pour fixer N0 et relever les noms : .\Tools\RunCommandlet.ps1 -Lot STE-ORG4 -Commandlet LPDumpFunction -Args '-BP=GI -Fn=EventGraph -Pins -Exec' -EtatDir "D:\Game\LifePlay-master 5.8\Docs\Migration\etat\ST\STE" (éditeur fermé ; 61 s en H3g, H3gV:29) → en-tête === GI :: EventGraph (6253 noeuds) === attendu. Autre MD5 ou autre N0 : arrêt, rapport.
  • P2 : MD5 de GI relevé juste avant l'IMPL (attendu e64b5b37…) = valeur de repli.
  • P3 : gel annoncé à toutes les sessions (lp-mcp § 1 règle 7) ; .\Tools\Snapshot.ps1 -Lot STE-ORG4 (Content\BPs\GI.uasset ; l'instantané contient donc G16 et B7-a, non commités) ; é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 ; liens = GI-P2 ; relever les indices de broches ; tout écart : arrêt) :
    1. CustomEvent_4245, IfThenElse_172, IfThenElse_98, IfThenElse_875, CallFunction_11423, CustomEvent_702, VariableSet_9760, CallFunction_960, VariableGet_720, VariableGet_3498 ;
    2. GetArrayItem_1037, CallFunction_6681, VariableGet_721, VariableGet_722, IfThenElse_188, IfThenElse_189, CallFunction_38905, CallFunction_4939. Liens attendus : IfThenElse_875.then → CallFunction_11423.execute seul ; CallFunction_11423.execute ← IfThenElse_875.then, CallFunction_32955.then, IfThenElse_189.then (GI-P2:10906) ; CustomEvent_702.then → VariableSet_9760.execute (10898) ; VariableSet_9760.then → CallFunction_960.execute (10901) ; VariableGet_720.PersonCumming → VariableGet_721.self, VariableGet_722.self (28041) ; VariableGet_3498.SexPersons → GetArrayItem_1037.Array ; GetArrayItem_1037.Output → CallFunction_6681.self, Dimension 1 = 0 (10879-10888).
  • P5 : avant chaque create_node, find_node_types {graph, type_id_filter, context_pins:[]} ; le type_id attendu doit figurer dans la réponse ; après création, get_node_infos du nœud (indices). Pas de type_id improvisé.
  • P6 : P0 lu et conforme (O4b) ; Q-ORG4-1 répondue (O4b) ; Q-ORG4-3 répondue (marqueur).
  • P7 (lecture, sans écriture) : find_node_types avec le filtre GiveOrgasmReward doit rendre Classe|Person|GiveOrgasmReward (Person MD5 8668a47c… à l'entrée ; sinon arrêt) ; relever la broche self. Aucun enregistrement de Person.

2.1 Conventions (reprises de H3gS § 2.1, H3dI § 1.2, lp-mcp § 3-4)

  • type_id déjà relus en 5.8 : Branche Utilitaires|ContrôleDeFlux|Branche (execute 0, Condition 1 = true par défaut ; then 0, else 1 ; H3dI:69) ; Utilitaires|Tableau|IsValidIndex (TargetArray 0, IndexToTest 1 = 0 par défaut, ReturnValue 0 ; H3dI:68, 187-188) ; Utilitaires|IsValid (pur, Object 0, ReturnValue 0 ; H3gI:45) ; appel d'un événement de Person depuis GI Classe|Person|<Nom> (exemple créé : Classe|Person|MovetoPersonStand, B7aI:37-38 ; Classe|Person|RevertStripAll, STE-H10-GI1-IMPL.md:48) ; lecteur d'une variable de Person depuis GI Classe|Person|Obtenir<Var> (exemple : Classe|Person|ObtenirValid, self entrée 0, STE-H10-GI1-IMPL.md:47) — le tiret bas disparaît du nom (Vol_BGA → ObtenirVolBGA, STF-T3-IMPL.md:59) ; setter d'une variable de GI Variables|<Catégorie>|Définir<Var> (catégorie Pardéfaut, H3dI:70 ; catégorie Sex pour SexOn, B7aI:34) ; opérateur promotable Utilitaires|Opérateurs|Inférieurà(<) (créé en B7a : B7aI:32 ; typé en reliant A d'abord, puis B posé par set_pin_value, B7aI:44) ; Math|Flottant|float<float n'est pas créable (B7aI:31).
  • Pas de Person::Cum appelé depuis GI::Cum (décision de conception, § 2.3 et R-ORG4-5). Cascades de Branche ; ni AND, ni OR, ni Select purs. delete_node interdit. Positions libres.
  • Compilation et enregistrement : compile_blueprint {blueprint:{refPath:"/Game/BPs/GI.GI"}, warnings_as_errors:true} → null, journal de l'éditeur lu (aucune ligne Error / Warning liée à GI) ; puis save_assets {asset_paths:["/Game/BPs/GI"]} ; hyper_blueprint_debug_inspect absent du serveur (mémoire du projet ; H3dI:156) : repli = compilation stricte + journal ; fermeture de l'éditeur, .\Tools\UeState.ps1 = 0, MD5 relevé.

2.2 Garde PersonCumming — O4a (graphe /Game/BPs/GI.GI:EventGraph, événement AfterCumSpeed)

Avant (GI-P2:10896-10904, 28034-28062) : CustomEvent_702.then → VariableSet_9760.execute ; VariableSet_9760.Rate ← CallFunction_1002.ReturnValue (pur) ← CallFunction_1005 (StartsWith) et VariableGet_722.IsMale, tous deux avec self ← VariableGet_720.PersonCumming. Deux lectures de membres sur PersonCumming = deux avertissements par clic si None. « Vide » (None) est un état normal de ce chemin (aucun jouisseur) : l'IsValid est donc justifié (lp-mcp § 1 règle 4).

Nœuds créés (3) :

ID Nœud type_id (P5) Broches (P4 / get_node_infos)
O4a-V IsValid (pur) `Utilitaires IsValid`
O4a-B Branche `Utilitaires ContrôleDeFlux
O4a-S Définir Rate `Variables <catégorie>

Coupure (1) : break_pins CustomEvent_702.then (sortie 0) / VariableSet_9760.execute (entrée 0). Liens (6), un appel par message :

  1. VariableGet_720.PersonCumming → O4a-V.Object (0) (les liens vers VariableGet_721.self et VariableGet_722.self restent) ;
  2. CustomEvent_702.then (0) → O4a-B.execute (0) ;
  3. O4a-V.ReturnValue (0) → O4a-B.Condition (1) ;
  4. O4a-B.then (0) → VariableSet_9760.execute (0) ;
  5. O4a-B.else (1) → O4a-S.execute (0) ;
  6. O4a-S.then (0) → CallFunction_960.execute (0) (celui-ci garde VariableSet_9760.then). Valeur (1) : set_pin_value O4a-S.Rate (entrée 1) = 0.25 (relire la valeur par défaut avant et après). Relecture : CustomEvent_702.then → O4a-B.execute seul ; VariableSet_9760.execute ← O4a-B.then seul ; CallFunction_960.execute ← VariableSet_9760.then, O4a-S.then ; VariableGet_720.PersonCumming → 3 cibles ; O4a-B.Condition relié (sinon true par défaut = garde inopérante). Comptes O4a : 3 nœuds ; 1 coupure ; 6 liens ; 1 valeur.

Pourquoi Rate = 0.25 explicite sur else (et non un saut direct vers CallFunction_960) : avec PersonCumming = None, les deux lectures rendent la valeur par défaut (Race vide → StartsWith('Dog') faux ; IsMale faux), bPickA = faux et SelectFloat rend B = 0.25 (« If bPickA is true, A is returned, otherwise B is », UERuntime\Engine\Classes\Kismet\KismetMathLibrary.h:3850-3852 ; sémantique d'une lecture Accessed None : H3fD:86-88, estimé). Le else pose donc exactement la valeur d'aujourd'hui, y compris pour le chemin Exhausted (qui laisse 10 s avant EndSex et pour lequel Rate sert encore, estimé).

2.3 Bonus à Endsex et ses gardes — O4b (même graphe, événement Cum, branche ForceEnd)

Principe (Q-ORG4-1 option b, recommandée) : sur la branche ForceEnd vrai de GI::Cum, avant l'appel de AfterCumSpeed, donner GiveOrgasmReward à SexPersons[0] si Sex_Orgasm ≥ 90. Le bonus est lu avant EndSex (qui vide la scène) : SexPersons, PlayerCharacter et SexOn sont encore valides. Le bonus ne comprend que ce que fait GiveOrgasmReward (P-STG:16059-16106, 19071-19101 d'après AUD § 1) : OrgasmIrBoost, puis mood +20 (joueur) ou attractiontoplayer +3 / +6 (PNJ avec le joueur dans la scène), rien sinon. Pourquoi bonus seul et non Person::Cum : (1) Person::Cum rappelle GI.Cum (P-STG:15958-15973) ; appelé depuis GI::Cum, il ré-entrerait dans le même événement dont les paramètres (ForceEnd, NoEnd…) sont, en Blueprint, des variables de la trame de l'ubergraph partagée ; l'appel interne écraserait ForceEnd à false et la fin de scène (IfThenElse_188, IfThenElse_876, CallFunction_4939) lirait la valeur écrasée (estimé fort, non lu dans le moteur : raison suffisante pour s'en abstenir) ; (2) fumée, texte, secousse et son d'orgasme seraient joués à l'image même où la scène est défaite ; (3) l'événement GiveOrgasmReward n'appelle aucun nœud de GI (AUD § 1 : 6 nœuds) donc aucune ré-entrée.

Nœuds créés (8, + 1 si Q-ORG4-3 = oui) :

ID Nœud type_id (P5) Broches
O4b-I IsValidIndex `Utilitaires Tableau
O4b-B1 Branche `Utilitaires ContrôleDeFlux
O4b-V IsValid (pur) `Utilitaires IsValid`
O4b-B2 Branche idem idem
O4b-G Lecteur de Sex_Orgasm (Person) `Classe Person
O4b-C Comparateur < `Utilitaires Opérateurs
O4b-B3 Branche idem idem
O4b-M (option) PrintString (marqueur de trace) filtre PrintString InString, bPrintToScreen, bPrintToLog (défaut vrai) ; execute 0, then 0
O4b-R Appel de Person_C::GiveOrgasmReward `Classe Person
Repli de type pour O4b-C si la création échoue : `Utilitaires Opérateurs Supérieuràouégalà(>=)` (listé, non créé : B7aI:24) avec Branche inversée ; sinon arrêt, rapport.

Coupure (1) : break_pins IfThenElse_875.then (sortie 0) / CallFunction_11423.execute (entrée 0). Liens (16 ; 17 avec le marqueur), un appel par message, dans cet ordre (relier O4b-G → O4b-C.A avant de poser B) :

  1. IfThenElse_875.then (0) → O4b-B1.execute (0) ;
  2. VariableGet_3498.SexPersons → O4b-I.TargetArray (0) (le lien vers GetArrayItem_1037.Array reste) ;
  3. O4b-I.ReturnValue (0) → O4b-B1.Condition (1) ;
  4. O4b-B1.then (0) → O4b-B2.execute (0) ;
  5. GetArrayItem_1037.Output → O4b-V.Object (0) ;
  6. O4b-V.ReturnValue (0) → O4b-B2.Condition (1) ;
  7. O4b-B2.then (0) → O4b-B3.execute (0) ;
  8. GetArrayItem_1037.Output → O4b-G.self (0) ;
  9. O4b-G.Sex_Orgasm (0) → O4b-C.A (0) ;
  10. O4b-C.ReturnValue (0) → O4b-B3.Condition (1) ;
  11. O4b-B3.else (1) → O4b-R.execute (0) — avec le marqueur : O4b-B3.else → O4b-M.execute, puis O4b-M.then → O4b-R.execute (lien 11 en deux liens) ;
  12. GetArrayItem_1037.Output → O4b-R.self (1) ;
  13. O4b-R.then (0) → CallFunction_11423.execute (0) ;
  14. O4b-B1.else (1) → CallFunction_11423.execute ;
  15. O4b-B2.else (1) → CallFunction_11423.execute ;
  16. O4b-B3.then (0) → CallFunction_11423.execute (jauge < 90 : pas de bonus). Valeurs : set_pin_value O4b-C.B = 90.0 (après le lien 9) ; marqueur : O4b-M.InString = ORG4 bonus Endsex, O4b-M.bPrintToScreen = false. Relecture : IfThenElse_875.then → O4b-B1.execute seul ; CallFunction_11423.execute ← 6 sources (CallFunction_32955.then, IfThenElse_189.then, O4b-B1.else, O4b-B2.else, O4b-B3.then, O4b-R.then) ; GetArrayItem_1037.Output → 4 cibles (CallFunction_6681.self, O4b-V.Object, O4b-G.self, O4b-R.self) ; VariableGet_3498.SexPersons → 2 cibles ; les 3 Condition des Branches reliés ; IfThenElse_875.else → MacroInstance_18.exec inchangé. Comptes O4b : 8 nœuds (9) ; 1 coupure ; 16 liens (17) ; 1 valeur (3).

Gardes : IsValidIndex(SexPersons, 0) puis IsValid(SexPersons[0]) avant la seule lecture de membre (Sex_Orgasm) et avant l'appel de l'événement (format G13 / G16, H3gS § 2.1) ; chaque else rejoint AfterCumSpeed, c'est-à-dire exactement le chemin d'aujourd'hui. Le test de valeur (Sex_Orgasm < 90) n'est pas une garde Accessed None mais la condition d'éligibilité.

2.4 Comptes et résultat attendu de l'IMPL

sans marqueur avec marqueur
Nœuds créés (O4a 3 + O4b 8 (+1)) 11 12
GI:EventGraph (N0 = 6 253) 6 264 6 265
Coupures 2 2
Liens créés 22 23
set_pin_value 2 (Rate, 90.0) 4 (+ InString, bPrintToScreen)
Inchangés (VAL) : toutes les autres fonctions de GI ; isSameAs 11, GetVariable 53, CallFunctionReturnBool 594, Action:EventGraph 363 (H3gV:34).

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

Cas Avant Après
Endsex, SexPersons[0].Sex_Orgasm ≥ 90 scène terminée, aucun bonus ; 2 avertissements PersonCumming si None bonus (O4b) : OrgasmIrBoost + mood +20 si SexPersons[0] est le joueur, sinon attractiontoplayer +3 (+6 si « Vaginal » et WantsBabies) si le joueur est dans la scène, sinon rien ; puis fin identique ; 0 avertissement → changement voulu
Endsex, jauge < 90 fin ; 2 avertissements si None fin identique ; 0 avertissement ; pas de bonus
Endsex, SexPersons vide ou [0] invalide (cas non rencontré) else → chemin d'aujourd'hui
Finish (« Cum on … ») puis Endsex 1 bonus (Finish) ; Endsex sans bonus idem : Person::Cum remet Sex_Orgasm à 0 (P-STG:17282-17287) → jauge < 90 → pas de double bonus
Orgasme automatique à 100, puis Endsex idem idem (même remise à 0)
Scène suivante, Endsex aussitôt — jauge remise à 0 au démarrage de la scène par UpdateSexLikes (P-STG:15804-15818 ; appelé en boucle sur SexPersons, GI-P2:27418-27421, 12385-12391, avec SexOn := true voisin, 6896-6899 ; estimé : événement propriétaire de la boucle non nommé) → pas de bonus gratuit en boucle
Endsex après un orgasme antérieur (PersonCumming périmé mais valide) Rate selon le dernier jouisseur inchangé (garde vraie)
PersonCumming détruit, en attente de ramasse-miettes (IsValid faux, pointeur non nul) lit les champs périmés Rate = 0.25 (écart théorique, très rare ; seul cas de O4a qui change une valeur)
Exhausted → GI.Cum (minuterie 10 s) avec PersonCumming None 2 avertissements, Rate = 0.25 0 avertissement, Rate = 0.25
Bonus sans orgasme non oui, par conception : terminer à ≥ 90 compte comme une jouissance ; sans effet d'orgasme (pas de remise à 0, pas de particule, pas de texte) → Q-ORG4-1
Persons autres que [0] (partenaire, scènes à plusieurs) pas de bonus pas de bonus (comme Finish, qui ne vise que Persons[0]) → option (c) de Q-ORG4-1
Le cas « tous ceux à 100 » est vide : l'orgasme à 100 se déclenche dans le même appel que la mise à jour de la jauge (FClamp puis == 100.0 → Cum(), P-STG:15896-15901, 16030-16043), donc aucune jauge ne vaut 100 au moment d'un clic (établi par la lecture ; AUD § 2).

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 (le .uasset reste l'instantané), contrôler le MD5, rapporter. Aucun correctif improvisé.
  • Après enregistrement, lien relu différent, type_id introuvable (P5), nœud inattendu, 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 (déjà dans le fichier à l'entrée) sont conservés, aucune autre écriture de GI ne doit être intercalée.
  • Repli de conception : (i) P0 contraire ou Q-ORG4-1 = (a) → O4a seul (3 nœuds, EventGraph N0 + 3) ; (ii) O4b-C non créable → inverser avec >= (§ 2.3) ou arrêt ; (iii) le marqueur gêne → l'omettre (il est retirable et ignoré en Shipping : DevelopmentOnly, § 6).
  • Après commit (gardien) : git revert du commit du ticket STE-ORG4. Couplage de commit : GI.uasset est un binaire unique qui porte déjà G16 (commit différé jusqu'au verdict COMMUN-2, STE-TACHES.md:31) et B7-a (STG) ; ces trois changements partent dans le même fichier, donc dans un même commit ou dans l'ordre imposé par le gardien (R-ORG4-2).

4. Risques R#, questions Q#

  • R-ORG4-1 : la valeur ForceEnd = true de l'appel GI.Cum de SexAction est déduite (§ 1.1 a-c), pas lue. Si elle est fausse, O4b ne s'exécute jamais : la VAL statique (V5) passe quand même, seul l'essai en jeu (V6-S1) le révèle. → P0 bloquant avant O4b.
  • R-ORG4-2 : GI.uasset partagé : G16 (STE-H3g) et B7-a (STG) non commités dans le même binaire ; instantané à l'entrée ; commit conjoint ou ordonné ; ne jamais restaurer GI depuis un instantané antérieur à l'un d'eux.
  • R-ORG4-3 : noms et indices de broches des nœuds à créer inconnus (Classe|Person|ObtenirSexOrgasm, catégorie de DéfinirRate, GiveOrgasmReward) : P5 / P7 ; type_id non relu = arrêt.
  • R-ORG4-4 : GiveOrgasmReward affiche ses ModifyStat (NoDisplay faux, P-STG:16070-16087) à l'image même où EndSex défait la scène (bascules d'interface, STE-H8-DIAG) : le texte peut s'afficher très brièvement ou être masqué ; l'effet sur la stat existe quand même. V6 le fait constater (observation) ; aucune trace de journal n'existe (§ 7, V6).
  • R-ORG4-5 : ré-entrée de l'événement Cum si l'on appelait Person::Cum depuis GI::Cum (§ 2.3) ; écartée par conception.
  • R-ORG4-6 : articulation avec STE-ORG5 (reconstruction de la grille v5.26) : O4b appelle le même GiveOrgasmReward ; si ORG5 y ajoute PopulateBonusRewards (AUD § 9.3), une grille s'ouvrirait à l'image de la fin de scène. À traiter dans la SPEC ORG5 (sauter la grille depuis Endsex, ou accepter) ; pas de double bonus tant que O4b ne s'ajoute qu'à Endsex (jauge ≥ 90) et non à Finish.
  • R-ORG4-7 : PersonCumming lu ailleurs que dans l'EventGraph de GI (autres fonctions de GI, UI) : non lu (§ 2.0 : P4 peut ajouter find_nodes {graph, title:"PersonCumming"} si l'outil le permet) ; O4a ne garde que les deux lectures connues.
  • R-ORG4-8 : le dump de Person (14:08) précède la dernière sauvegarde de Person (17:42) : la chaîne GiveOrgasmReward a pu changer ; P7 et la VAL (V6) le couvrent.
  • R-ORG4-9 : autre appelant inconnu de GI.Cum avec ForceEnd = true (widget non dumpé) : il recevrait aussi le bonus à jauge ≥ 90 (souhaitable : fin de scène).
  • Q-ORG4-1 (utilisateur, avant O4b) : qui reçoit le bonus quand on termine par Endsex ?
    Option Description Pour Contre
    (a) personne O4a seul conception d'origine (Endsex ≠ orgasme) ; aucun bonus gratuit l'utilisateur reste sans bonus à Endsex
    (b) SexPersons[0] si jauge ≥ 90 (recommandée) O4a + O4b même éligibilité que Finish (PC-STE:6128-6142) ; bonus seul ; pas de double bonus ni de farm (jauge remise à 0 par Cum et par le démarrage de scène) « bonus sans orgasme » ; la partenaire (index 1) n'est pas servie
    (c) chaque participant à ≥ 90 boucle ForEachLoop sur SexPersons (macro vue en MacroInstance_806, GI-P2:7094-7100 ; type_id à relever) plus juste pour deux jouisseurs +5 nœuds environ, non spécifié ici ; autre SPEC
    (d) Person::Cum complet avant GI.Cum côté SexAction (illisible) effets complets ré-entrée si fait dans GI ; SexAction non dumpé
    Recommandation : (b). Question jumelle, Q-ORG4-2 : seuil 90 (celui du message rouge, P-STG:17363-17367, et de Finish) ou autre ?
  • Q-ORG4-3 (orchestrateur) : marqueur de trace ORG4 bonus Endsex (1 nœud, ignoré en Shipping) : oui (recommandé : V6 n'a aucune autre preuve de journal, § 7) ou non.
  • Q-ORG4-4 (orchestrateur) : UE-GO pour P0 (dump de SexAction) puis pour l'IMPL, gel annoncé, ticket du gardien (R-ORG4-2).
  • Q-ORG4-5 (orchestrateur) : O4a seul pour l'alpha si Q-ORG4-1 tarde (3 nœuds, sans changement de comportement, supprime F2).

5. Interdits

  • Aucune modification de Person (aucun save_assets de Person), de SexAction, de PC, de GetVariable, CallFunctionReturnBool, isSameAs, Action, du C++, des 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 ; aucun FunctionResult créé ; pas de delete_node ; pas de AND / OR / Select purs ; pas de type_id non relu (P5) ; pas d'écriture HyperAIStudio (lp-mcp § 1 règle 1) ; outils Epic seulement.
  • Pas d'IMPL de O4b sans P0 conforme et Q-ORG4-1 répondue ; pas d'IMPL sans P1 à P7 ; pas d'IMPL 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 est DevelopmentOnly : UERuntime\Engine\Classes\Kismet\KismetSystemLibrary.h:565-566 (le marqueur est ignoré en Shipping, joué en Development).
  • UKismetMathLibrary::SelectFloat(double A, double B, bool bPickA) : « If bPickA is true, A is returned, otherwise B is » : UERuntime\Engine\Classes\Kismet\KismetMathLibrary.h:3850-3852. Repris de H3gS § 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) ; GenericArray_IsValidIndex sans message (KismetArrayLibrary.cpp:583-595) ; GenericArray_Get hors plage → message Attempted to access index … et valeur par défaut (KismetArrayLibrary.cpp:459-482) ; Accessed None trying to read … (ScriptCore.cpp:3213-3216, valeur effacée 3234-3245). Non lu (estimé) : le stockage des paramètres d'un événement personnalisé dans la trame de l'ubergraph (raison de ne pas ré-entrer dans Cum, § 2.3) — à lire avant de s'en servir comme preuve, hors besoin de cette SPEC.

7. Critères de VAL (commande → attendu)

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 (6264 noeuds) === (6265 avec marqueur) ; et :
    • CustomEvent_702.then → O4a-B.execute seul ; O4a-B.then → VariableSet_9760.execute seul ; O4a-B.else → O4a-S.execute ; O4a-S.Rate = 0.25 ; O4a-S.then → CallFunction_960.execute ; CallFunction_960.execute ← VariableSet_9760.then, O4a-S.then ; VariableGet_720.PersonCumming → VariableGet_721.self, VariableGet_722.self, O4a-V.Object ; O4a-B.Condition ← O4a-V.ReturnValue ;
    • IfThenElse_875.then → O4b-B1.execute seul ; IfThenElse_875.else → MacroInstance_18.exec inchangé ; CallFunction_11423.execute ← 6 sources (§ 2.3) ; O4b-I.TargetArray ← VariableGet_3498.SexPersons ; IndexToTest = 0 ; O4b-V.Object, O4b-G.self, O4b-R.self ← GetArrayItem_1037.Output ; O4b-G.Sex_Orgasm → O4b-C.A ; O4b-C.B = 90 ; O4b-B3.else → O4b-R.execute (ou O4b-M) ; O4b-B3.then, O4b-B2.else, O4b-B1.else, O4b-R.then → CallFunction_11423.execute ; les 4 Branches de O4a / O4b ont leur Condition reliée. Non-régression (un par un) : -Fn=isSameAs → 11 ; -Fn=GetVariable → 53 ; -Fn=CallFunctionReturnBool → 594 ; -BP=Action -Fn=EventGraph → 363 (H3gV:34).
  2. Diff indépendant : python -I Tools\DiffRemplacementNoeuds.py <dump P1> <dump après> <profil> → seuls les nœuds et liens du § 2.2-2.4 ; « pins modifiés sur nœuds communs » = CustomEvent_702, VariableSet_9760, CallFunction_960, VariableGet_720, IfThenElse_875, CallFunction_11423, VariableGet_3498, GetArrayItem_1037 (8) et aucun autre.
  3. Compilation : compile_blueprint … warnings_as_errors:true → null, journal de l'éditeur sans Error / Warning pour GI ; CompileAllBlueprints éditeur fermé : BP /Game/ du projet 0 erreur (critère requalifié le 2026-10-13, CC_Shaders à part ; ligne de référence de H3gV, citée par STE-TACHES.md:31 : « 25/3/55/420 ») ; LPTestStringCompat 3120 / 0 / 60 (lp-validate).
  4. Empreintes : md5sum Content/BPs/GI.uasset noté ; md5sum Content/BPs/Person.uasset = 8668a47c627f7a5254910cf0ac33b12a et Content/UI/SexAction.uasset = a8705f7fbe1fde1daba0464bfc9ff9b5 (inchangés) ; Room : valeur relevée à l'entrée = à la sortie ; git status --short -- Content : aucun fichier de plus que M GI, Person, Room.

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

Ce que le journal ne montre pas : ModifyStat ne laisse aucune ligne. Dans HJ, un Endsex a eu lieu (HJ:9242) et GI::EndSex applique arousal -50 et mood +50 à chaque participant (GI-P2:7803-7811) ; Grep attractiontoplayer|\bmood\b sur HJ → aucune ligne ; Grep \barousal\b sur HJ → aucune ligne (contrôle positif : Endsex|ORG4 sur HJ → 1 ligne). Le critère « trace mood / attractiontoplayer » de la fiche n'est donc pas tenable par le journal : preuve = marqueur O4b-M (Q-ORG4-3) et observation à l'écran (texte de stat de ModifyStat, NoDisplay faux) rapportée par l'utilisateur. Parcours à jouer (une scène MF avec le joueur ; noter qui est SexPersons[0] : l'homme / la personne au pénis, joueur ou PNJ) :

  • S1 (bonus) : laisser monter la jauge de SexPersons[0] entre 90 et 100 (texte rouge « Close to cumming… » visible, seuil P-STG:17363-17367), puis cliquer « Finish having sex » (pas une animation « Cum on … »). Attendu : la scène se termine dans la même image ; texte de stat du bonus à l'écran (mood +20 si c'est le joueur ; attractiontoplayer +3 / +6 sur le PNJ si le joueur est dans la scène), en plus de ceux de EndSex ; marqueur dans le journal.
  • S2 (témoin sous le seuil) : démarrer une scène, cliquer « Finish having sex » aussitôt (jauge < 90). Attendu : fin de scène, aucun texte mood +20 / attractiontoplayer, aucun marqueur, 0 avertissement.
  • S3 (pas de double bonus) : jauge ≥ 90, choisir une animation « Cum on … » (bonus 1 par Person::Cum), puis cliquer « Finish having sex » aussitôt. Attendu : pas de second bonus, aucun marqueur pour ce clic, 0 avertissement.
  • S4 (orgasme à 100) : laisser la jauge atteindre 100 (orgasme automatique), puis « Finish having sex ». Attendu : comme S3. Greps sur le journal du jeu (mode count, fichier nommé ; base = HJ) :
    Motif HJ (1 clic Endsex) Attendu
    Endsex \(Animation String\) 1 = nombre de clics (S1 à S4 : 4 si une scène par cas) — preuve que le parcours est rejoué (sans elle, un 0 ne prouve rien)
    Accessed None trying to read \(real\) property PersonCumming 2 0
    ORG4 bonus Endsex (si marqueur) 0 1 (S1 seul)
    GiveOrgasmReward|OrgasmIrBoost (piles d'avertissement) 0 0
    fatal|Unhandled|Critical|Assertion 0 0
    LogScript: Warning: Accessed None 13 ≤ 11 (indicatif : −2 pour F2 ; le reste dépend du parcours)
    Non-régression : .\Tools\LogStats.ps1 -Compare <journal>,<HJ> : aucune famille nouvelle ; G13 et G16 intacts (isCreatureType → 0).
    Limites : l'effet réel des stats n'est vu qu'à l'écran ; le cas PersonCumming périmé mais valide (un Endsex après un orgasme) est couvert par S3 et S4 (0 avertissement avant comme après, Rate inchangé) ; le cas « détruit en attente de ramasse-miettes » n'est pas rejoué.

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

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

Tours : 29 / 45 (compte de l'agent, écriture comprise ; python -I Tools/FicheStats.py --lot STE fait foi)

Constats

  • Lectures qui manquent pour O4b (commandes données, non lancées) : P0 (SexAction EventGraph) ; facultatives : refresh du dump de PC (-BP=PC -Fn=EventGraph, celui de 10-10 précède CAM-B1) ; autres fonctions de GI lisant PersonCumming (R-ORG4-7).
  • Commandes de lecture (Grep / Read sauf mention) et comptes bruts :
    • Grep ForceEnd sur le dossier E\ST\STE\dumps → No matches found alors que GI-P2 contient la chaîne (GI-P2:10806) : les .txt de etat\ sont ignorés par ripgrep même avec le dossier en path ; il faut nommer le fichier (piège déjà noté, H3fD « Constats »). Les Grep ci-dessus nomment tous le fichier.
    • Grep ForceEnd (fichier nommé) : PC-STE → 0 ; EST\STA\dumps\SexInterface__EventGraph.txt→ 0 ;L6f_dump_Scene.txt→ 0 ;EST\STE\dumps\Room__EventGraph_V5.txt → 0 ; L6f-G → 58572, 58574, 58598, 61588, 61590, 72019, 72237 ; L6f_dump_Person.txt → 37160, 37168, 37202 (false).
    • Grep appel [A-Za-z_?]+::(Cum|EndSex|AfterCumSpeed|GiveOrgasmReward)\(\) sur GI-P2 → 10840, 10905, 14564 ; sur P-STG (Cum|EndSex|GiveOrgasmReward) → 15958, 15966, 16000, 16040, 16107 ; sur PC-STE → 0.
    • Grep variable 'Sex_Orgasm' sur GI-P2 → 0 ; sur P-STG (VariableSet_N) → 15807, 15873, 17282 ; UpdateSexLikes : P-STG:15804 (définition) ; GI-P2:27418 (seul appelant) ; PersonCummedOn : 4 lectures, 0 écriture dans GI-P2 (18952-18975).
    • Grep Endsex|ORG4 sur HJ → 1 ; attractiontoplayer|\bmood\b → 0 ; \barousal\b → 0 ; J6 Endsex|PersonCumming|Accessed None → 1 ligne Endsex (J6:2849), 0 ligne PersonCumming.
    • Bash grep -a -c sur Content/UI/SexAction.uasset : Endsex 2 ; ForceEnd 1 ; NoPregCheck 1 ; PlayAppropriateSexAnimation 1 (comptes de lignes contenant la chaîne ; présence d'un nom, pas valeur d'une broche).
  • Le résumé .txt d'un RunCommandlet rangé sous etat\ (ex. STE-H3gV_LPDumpFunction_*.txt) n'est pas le dump complet (compteurs de lignes d'avertissement dédoublonnées) ; le dump complet est dans Saved\Logs\portage\ ou dans un fichier __EventGraph_*.txt produit à part.
  • Hors périmètre, noté : F-ORG2 (AUD) GI::EndSex donne mood +50 / arousal -50 à chaque participant indépendamment de l'orgasme (GI-P2:7803-7811) ; l'« ancien modèle ToCum » (AUD § 6 P5) n'est pas concerné.
  • Lecture seule respectée ; un seul fichier écrit (ce livrable, non suivi). Aucun nom d'utilisateur ni chemin de profil cité.

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

  • Q-ORG4-1 : chaque participant, l'un après l'autre, reçoit un bonus à Endsex quand sa jauge dépasse 90 pour un homme et 100 pour une femme (réponse libre de l'utilisateur ; la réponse « 90 » à Q-ORG4-2 vaut pour les hommes). Option (c) avec seuil selon le sexe : SPEC complémentaire O4c à écrire (boucle sur SexPersons, test du sexe, seuils 90 / 100), en remplacement de O4b.
  • Q-ORG4-3 (orchestrateur) : marqueur de trace oui. Q-ORG4-5 : O4a peut partir seul si O4c tarde.

Règle commune ORG4 / ORG5 (Big Boss, 2026-10-14)

  • Pour un même orgasme, une personne reçoit au plus une fois le bonus de base (GiveOrgasmReward) et au plus une fois les récompenses ORG5 (3 au plus) ; le cumul base + ORG5 est voulu, le même bonus deux fois non.
  • Orgasme réel (Person::Cum, jauge à 100 ou choix « Cum on … ») : GiveOrgasmReward une fois (chemin existant) ; ORG5 une fois, déclenché par l'incrément de Sex_OrgasmCounts (accroche H1).
  • Endsex (O4c) : GiveOrgasmReward une fois par participant éligible (homme > 90, femme = 100), sans Person::Cum : Sex_OrgasmCounts inchangé, donc pas de récompense ORG5 à Endsex ; un participant qui vient de jouir a sa jauge remise à 0 par Cum et n'est pas éligible : pas de second bonus de base.
  • Toute IMPL qui change l'un de ces déclencheurs relit cette règle et la VAL la contrôle (V6 : un orgasme = 1 marqueur de base + au plus 1 ligne ORG5 par personne).