LifePlay-Revival/Docs/Migration/etat/CG/CG2/CG2-SPEC-01.md
edujiro5972 56dfcfc3d2 LifePlay UE 5.8 : état de développement au 2026-10-20
Tickets : PUB-20261020-T1

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 17:35:10 +02:00

225 lines
20 KiB
Markdown

Fiche CG2-SPEC-01 — Niveau N3 — Modèle prévu opus xhigh | utilisé claude-opus-5-5 — Session Medium-xHigh · CG2 — Skills lp-mcp (chargé), lp-lot, sk-protocol
# CG2-SPEC-01 : corrections Blueprint de la build 1 (cœur et option), forme exécutable lp-mcp (2026-10-19)
Base : `CG2-CART-01.md` (accepté). Décisions de l'utilisateur transmises par Big Boss (« CG2 - approuvé de Q1 à Q6 ») :
- **Q1** : retrait complet (texte et morph fixe).
- **Q2** : garde seule en B1.
- **Q5** : refuser `..` et les séparateurs, en option B1.
- **Q6** : garde unique à l'ouverture de l'écran sans personnage.
- **Q3, Q4** : B2.
Rédigée sans copie UE. Les identifiants de nœuds viennent des lectures MCP du lot CGREF1 (addon,
`Docs\etat\CG\CGREF1\CGREF1-T3-MCP.md`, `-T3d-MCP.md`, `-T3e-MCP.md`), à revérifier en tête de session (§ 2, étape 1).
Aucun contenu cité (doc 27) : les noms de boutons et de morphs non neutres restent dans ces fiches de l'addon.
## 1. Objectif mesurable
Sur une build Development de la copie 5.8, avec le scénario S-CG2 du § 7 :
- 0 `Accessed None` venant de `VisualMorph_C`, `CharGen_C` et `CharGenSlider_C` (avant : 378 `property chargen` à
l'ouverture du menu de forme du corps sans CharGen, STE-H3i) ;
- 0 trace de débogage (`Hello`, `test2905`) ;
- le réglage anti-déformation n'applique plus de morph fixe ;
- la liste des races animales revient au premier élément en fin de liste ;
- options faites : un nom de sauvegarde contenant `..`, `/` ou `\` est refusé, et la liste des préréglages n'a plus de
doublon.
Abréviations des graphes (`EventGraph` de chaque Blueprint) :
- `SL` = `/Game/UI/CharGenSlider.CharGenSlider:EventGraph` ;
- `CG` = `/Game/UI/CharGen.CharGen:EventGraph` ;
- `VM` = `/Game/UI/VisualMorph.VisualMorph:EventGraph` ;
- `GI` = `/Game/BPs/GI.GI:EventGraph` ; `GISP` = `/Game/BPs/GI.GI:SavePreset`.
- `refPath` d'un nœud : `<graphe>.K2Node_<Nom>`.
## 2. Fichiers touchés et ordre (agent lp-mcp-bp, éditeur headless, après BUILD-GO)
Fichiers : `Content\UI\CharGenSlider.uasset`, `Content\UI\CharGen.uasset`, `Content\UI\VisualMorph.uasset` ; en option
seulement : `Content\BPs\GI.uasset`.
**Étape 0 : préparation**
- Gel annoncé à toutes les sessions (`ListAgents`).
- Instantané : `.\Tools\Snapshot.ps1 -Lot CG2 -Path Content\UI\CharGenSlider.uasset, Content\UI\CharGen.uasset,
Content\UI\VisualMorph.uasset, Content\BPs\GI.uasset`.
- Éditeur headless (lp-mcp § 2), puis test `list_toolsets`.
- `load_asset` des 4 Blueprints.
- `hyper_blueprint_debug_inspect` de chacun (référence « avant » des diagnostics).
**Étape 1 : lectures de contrôle** (aucune écriture). Tout écart arrête la fiche avec un compte rendu.
- `get_node_infos` sur chaque nœud cité ci-dessous. Le titre et les liaisons doivent égaler les fiches CGREF1.
- `get_connected_subgraph` `CG.K2Node_ComponentBoundEvent_85` : **16 nœuds** attendus.
- `VM` : `find_nodes {graph: VM, title: "CharGen"}`. On attend les lectures de `GI.CharGen` (2 références dans le paquet
d'après STE-H3i § 3.2). Pour chacune, `get_connected_subgraph`, puis noter **E**, le premier nœud à exécution qui
consomme la lecture (directement ou par une chaîne pure), et **E→**, la cible de sa sortie `then`. Plus de 2 consommateurs,
ou un lecteur hors d'`EventGraph` : arrêt, la SPEC est à compléter.
- `SL` : `find_nodes {graph: SL, title: "PlayerCharacter"}`, puis `find_nodes {graph: CG, title: "PlayerCharacter"}`.
Si chaque `CharGenSlider` créé reçoit `PlayerCharacter` à sa création, D23 est sans objet : C2 est alors sauté et ce
saut est noté (lp-mcp règle 4 : pas de garde si « vide » n'est pas un état normal).
**Étape 2 : `CharGenSlider`** (`SL`)
| Id | Défaut | Opérations |
|---|---|---|
| C1 | D19, retrait de la trace | `get_node_infos SL.K2Node_CallFunction_11` (`PrintString`, entrée `execute` ← `IfThenElse_5` sortie else) ; noter **N** = cible de sa sortie `then` (attendu : le `Set` de `SetCC`). `break_pins` (`IfThenElse_5`.else → `_11`.execute) et (`_11`.then → N.execute) ; `connect_pins` (`IfThenElse_5`.else → N.execute) ; `delete_node _11`, puis ses entrées pures (concaténation, conversion) **seulement si** aucune autre liaison ne part de leurs sorties |
| C2 | D23, garde (si l'étape 1 ne l'a pas écartée) | créer `Utilitaires\|ContrôleDeFlux\|Branche` (B23) et `Utilitaires\|IsValid` (entrée ← sortie de `SL.K2Node_VariableGet_44`, `PlayerCharacter`) ; `break_pins` (`IfThenElse_5`.else → N.execute) ; `connect_pins` (`IfThenElse_5`.else → B23.execute), (IsValid → B23.Condition), (B23.then → N.execute). B23.else → nœud suivant les boucles de `SetMorphTarget` (leur `Completed`) s'il existe, sinon rien. `GetComponentsByClass` est pure (§ 6) : la garde se place devant le `Set` qui l'évalue |
Puis `compile_blueprint`, `hyper_blueprint_debug_inspect` (aucun diagnostic nouveau) et `save_assets ["/Game/UI/CharGenSlider"]`.
**Étape 3 : `CharGen`** (`CG`)
| Id | Défaut | Opérations |
|---|---|---|
| C3 | D18 (et D6), Q1 retrait complet | `break_pins` (`ComponentBoundEvent_85`.then → `IfThenElse_37`.execute) ; `delete_node` des 15 autres nœuds du sous-graphe relevé à l'étape 1 (`IfThenElse_37`, `_38`, `CallFunction_59`, `_93`, `_303`, `_305`, `_306`, `_307` et leurs lectures pures). `_85` est gardé, sans suite : le réglage ne fait plus rien |
| C4 | D20, échec du cast | `get_node_infos CG.K2Node_DynamicCast_0` ; créer `PrintString` (P20 : `InString = "CG2 CharGen Construct : cast GI echoue"`, `bPrintToScreen = false`, `bPrintToLog = true`) ; `connect_pins` (`DynamicCast_0`.CastFailed → P20.execute). L'exécution s'arrêtait déjà là : le comportement est inchangé, seule une trace est ajoutée |
| C5 | D20 + D25, Q6 garde unique | `get_node_infos CG.K2Node_IfThenElse_2` ; noter **P**, la source de son entrée `execute` (attendu : l'appel `PopulateFaceTextures`). Créer une Branche (BG) et `IsValid` (entrée ← sortie `GI.CharacterBeingEdited` de `VariableGet_385` ou `_386`, lecture pure réutilisable). `break_pins` (P.then → `IfThenElse_2`.execute) ; `connect_pins` (P.then → BG.execute), (BG.then → `IfThenElse_2`.execute). BG.else → `PrintString` P25 (log seul, `"CG2 CharGen sans personnage edite : boutons d'etat desactives"`) → chaîne de `SetIsEnabled(false)` sur les **9** boutons dont les événements sont `ComponentBoundEvent_179`, `_149`, `_87`, `_24`, `_75`, `_76`, `_34` (`Randomize*`), `_5` et `_10` (`ChangeAnimal`, `ChangeBreed`). Le nom de variable de chaque bouton se relève par `get_node_infos` sur son événement (CGREF1-T3e § 2.1). Avec un personnage valide, rien ne change |
| C6 | D26 | `get_node_infos CG.K2Node_CallFunction_14` et `_15` : l'un est `SelectInt`. `set_pin_value` (broche `B` de ce `SelectInt`) = `0` ; relecture : la valeur `0` s'affiche |
| C7 (option) | D4, Q5 | `get_node_infos` du sous-graphe de `SaveConfirmButton` (`ComponentBoundEvent_1418` → `IfThenElse_366`) ; noter **S**, la chaîne qui alimente `Len` (texte de `FilenameEntry`), et **F**, la cible de `IfThenElse_366`.else (début du chemin « champ rouge »). Insérer entre `IfThenElse_366`.then et `CallFunction_5375` (`GI.SavePreset`) une **cascade** de 3 Branches (pas de `OR` pur, règle 4), chacune sur `Contains(S, x, bUseCase = false)` avec x = `..`, `/`, `\` : vrai → F ; faux → Branche suivante ; la dernière, faux → `CallFunction_5375`. Le `\` saisi par `set_pin_value` doit se relire comme un seul caractère |
| C8 (option) | D21 | a) `break_pins` (`CustomEvent_139`.then → `CallFunction_3001`.execute) ; créer `ClearChildren` (cible ← `LoadScrollBox`) ; câbler `_139` → `ClearChildren` → `_3001`. b) Dans le corps de `MacroInstance_64`, créer une Branche (BS) dont la condition est la sortie `ReturnValue` de `CallFunction_327` (`Split`, pure). Câbler corps de boucle → BS.execute ; BS.then → `CreateWidget_96` ; BS.else non relié (entrée sautée, la boucle continue) |
Puis compiler, inspecter et `save_assets ["/Game/UI/CharGen"]`.
**Étape 4 : `VisualMorph`** (`VM`)
| Id | Défaut | Opérations |
|---|---|---|
| C9 | STE-H3i, Q2 garde seule | Pour chaque E relevé à l'étape 1 : créer une Branche (BV) et `IsValid` (entrée ← sortie de la lecture `GI.CharGen`) ; `break_pins` (source.then → E.execute) ; `connect_pins` (source.then → BV.execute), (BV.then → E.execute), (BV.else → E→). Avec la référence nulle, l'exécution sautait déjà E (Accessed None) et continuait vers E→ : le résultat est le même, sans l'avertissement (lp-mcp § 4, « cas non valide »). « Vide » est un état normal : CharGen non ouvert dans la session (STE-H3i § 3.1) |
Puis compiler, inspecter et `save_assets ["/Game/UI/VisualMorph"]`.
**Étape 5 (option) : `GI`**. À faire seulement si aucun autre ticket de la même vague ne touche `GI.uasset` (§ 4, R2).
| Id | Défaut | Opérations |
|---|---|---|
| C10 | D3 | `get_node_infos` de `GISP` : `VariableSet_10`, `CallFunction_81`, `_88`, `_89`, `_91`, `_0`, `_86`, `_1`. Supprimer seulement un nœud dont l'entrée `execute` n'a aucune liaison et dont les sorties ne vont qu'à d'autres nœuds supprimés. Un nœud relié à un chemin atteignable est gardé et noté |
| C11 | D27 | `GI.K2Node_CallFunction_20748` (toutes broches libres attendues) : `delete_node`. `GI.K2Node_CallFunction_13122` (`PrintString`, entrée libre, `then` → `_340`) : `break_pins` (`_13122`.then → `_340`.execute), puis `delete_node _13122` et ses entrées pures exclusives. `_340` est gardé |
Puis compiler (long), inspecter et `save_assets ["/Game/BPs/GI"]`.
**Étape 6 : clôture**
- `git status --short -- Content/`, puis fermeture de l'éditeur (ou éditeur laissé ouvert si la file MCP continue,
lp-mcp § 2).
- Éditeur fermé : `.\Tools\RunCommandlet.ps1 -Lot CG2 -Commandlet CompileAllBlueprints` (journal archivé).
- Livrable `CG2-IMPL-01.md` : lien relu de chaque opération, MD5 avant / après, diagnostics avant / après.
## 3. Repli
Toute réponse qui n'est pas un succès explicite arrête la fiche (lp-mcp § 3). Retour à l'octet du Blueprint en cause par
`Restore.ps1 -Lot CG2`, éditeur fermé, ou par le gardien (git) sur ticket. Les Blueprints déjà enregistrés et validés
restent ; le compte rendu dit lesquels.
## 4. Risques et questions
- **R1** : nœuds renumérotés depuis les lectures CGREF1 du 2026-10-16. Parade : contrôle de l'étape 1, arrêt au premier
écart.
- **R2** : `GI.uasset` est partagé par beaucoup de lots ; les options C10 et C11 l'alourdissent (binaire, compilation
longue). Parade : les faire seulement si `etat\REPO\FILE.md` n'a aucun ticket sur `GI.uasset` dans la vague ; sinon
elles passent en B2.
- **R3 (correction de la CART)** : `PrintString` n'imprime rien en Shipping ni en Test
(`KismetSystemLibrary.cpp:458`, § 6). Les traces de D18 et D19 ne se voient donc qu'en Development : la CART les disait
« visibles du joueur ». En Shipping, l'effet réel de D18 est le **morph fixe** appliqué à chaque changement, retiré par
C3. Les Accessed None interrompent aussi l'exécution en Shipping : les gardes gardent leur valeur sans journal.
- **R4** : C5 désactive 9 boutons dans un état jamais observé (D20 et D25 : déclenchement estimé). Aujourd'hui, ce même
état produit un Accessed None à chaque clic.
- **R5** : la preuve en jeu demande une build Development empaquetée (lp-mcp règle 5 : pas de PIE pour un parcours
d'interface).
- **Q7** : après C3, le champ anti-déformation reste affiché sans effet. Faut-il le masquer en B2 ?
- **Q8** : en B2, après lecture de `GI.CloseCharGen` (non lu), fermer l'écran au lieu de désactiver les boutons ?
- **Q9** : CART et référentiel parlent de 8 boutons ; T3e § 2.1 en liste 9 (`RandomizeTattoo` compris). C5 les prend
tous les 9.
## 5. Interdits
- Aucun nœud ni Blueprint hors de cette liste ; aucun C++ ; aucun `AND` / `OR` / `Select` pur pour une garde
(cascades de Branches seulement).
- Aucune avance d'initialisation de widget (ERR-057, lp-mcp § 4).
- Aucune PIE comme preuve ; aucun commandlet ni build éditeur ouvert ; aucun git qui écrit ; aucun autre asset enregistré.
- Traces ajoutées en journal seul (`bPrintToScreen = false`), en ASCII.
## 6. Valeurs moteur lues (moteur installé 5.8, `Engine\Source\Runtime\`)
- `UKismetSystemLibrary::PrintString` : signature `Engine\Classes\Kismet\KismetSystemLibrary.h:566` (`bPrintToScreen`,
`bPrintToLog`, `Duration`). Corps vide en Shipping et en Test sauf `USE_LOGGING_IN_SHIPPING` :
`Engine\Private\KismetSystemLibrary.cpp:456-458`.
- `UKismetStringLibrary::Contains(SearchIn, Substring, bUseCase = false, bSearchFromEnd = false)` :
`KismetStringLibrary.h:353`.
- `UKismetStringLibrary::Split(…)` rend un `bool` : `KismetStringLibrary.h:524`.
- `UKismetSystemLibrary::IsValid` : `KismetSystemLibrary.h:128`.
- `AActor::K2_GetComponentsByClass` est `BlueprintCallable` et `const`, donc pure en Blueprint :
`Engine\Classes\GameFramework\Actor.h:3806-3807`.
- `UWidget::SetIsEnabled(bool)` : `UMG\Public\Components\Widget.h:544-545`.
## 7. Critères de VAL (commande → attendu)
| # | Commande | Attendu |
|---|---|---|
| V1 | `git status --short -- Content/` | `M` sur `Content/UI/CharGenSlider.uasset`, `CharGen.uasset`, `VisualMorph.uasset` (+ `Content/BPs/GI.uasset` si C10 ou C11), rien d'autre |
| V2 | `get_node_infos` de chaque nœud créé ou relié (IMPL § liens) | liaisons conformes au § 2 ; `SelectInt.B = 0` ; `PrintString` ajoutés : écran faux, journal vrai |
| V3 | `compile_blueprint` + `hyper_blueprint_debug_inspect` par Blueprint | succès ; aucun diagnostic nouveau par rapport à la référence de l'étape 0 |
| V4 | `RunCommandlet.ps1 -Commandlet CompileAllBlueprints`, éditeur fermé | 0 erreur ; aucun avertissement nouveau sur les 3 (ou 4) Blueprints |
| V5 | MD5 des `.uasset` contre le manifeste `D:\Game\LifePlay_Backup_5.5\CG2\manifest.csv` | « avant » = manifeste ; « après » ≠ avant pour les seuls fichiers de V1 |
| V6a | jeu Development, menu principal → menu de forme du corps **sans** ouvrir CharGen ; `LogStats.ps1 <journal> -Pattern 'property chargen'` | 0 (avant : 378) |
| V6b | ouvrir CharGen, bouger 3 curseurs de morph et le réglage anti-déformation ; `-Pattern 'Hello\|test2905'` | 0 ; le visage ne change pas par le réglage anti-déformation |
| V6c | cliquer les 9 boutons ; `ChangeBreed` jusqu'à la fin de la liste | retour au premier élément ; `-Pattern 'Accessed None.*(CharGen_C\|CharGenSlider_C\|VisualMorph_C)'` → 0 |
| V6d (option) | enregistrer sous `a/b`, `..x`, `a\b`, puis sous un nom normal | 3 refus (champ rouge), aucun nouveau fichier sous `Content\Modules\` pour eux ; le nom normal est écrit |
| V6e (option) | ouvrir et fermer la liste de chargement deux fois | aucune entrée en double |
| V7 | PubCheck et fins de ligne des livrables | 0 constat ; LF |
V6 est joué par l'utilisateur sur une build Development (`Tools\BuildDebug.ps1 -Config Development`). Le journal est
archivé dans `etat\CG\CG2\`.
## 8. Demande de jeton (BUILD-DEMANDE, envoyée à Big Boss)
Une session MCP d'écriture (agent `lp-mcp-bp`, N3, `maxTurns` 75) dans la file de la copie UE après STM1 :
- étapes 0 à 6, environ 5 h pour le cœur et 2 h pour les options ;
- puis `CompileAllBlueprints` éditeur fermé ;
- puis une build Development pour V6, qui peut être mise en commun avec les autres lots du J3.
Fichiers gelés pendant la session : les 4 `.uasset` du § 2.
## 9. Révision 2 (2026-10-20), après l'arrêt de `CG2-IMPL-01` à l'étape 1
`CG2-IMPL-01.md` § 0.1 et § 2 (E1 à E8) ont relevé 4 écarts de la SPEC sur la copie inchangée (`CharGen.uasset` au
commit `71511a2` ; MD5 des 4 assets égaux au manifeste `CG2`). Aucune écriture n'a eu lieu. Les points ci-dessous
remplacent le § 2 pour les opérations citées ; le reste du § 2 vaut toujours. Les étapes 0 et 1 sont acquises (IMPL
§ 0.1) : la reprise commence à l'étape 2.
| Op | Correction | Motif |
|---|---|---|
| outils | `hyper_blueprint_debug_inspect` est absent du serveur. Après chaque `compile_blueprint {warnings_as_errors: true}` (succès = `returnValue` sans erreur), lire le journal de l'éditeur par `EditorToolset.LogsToolset`, filtré sur le nom du Blueprint : aucune ligne `Error` ni `Warning` nouvelle. `type_id` en anglais : `Utilities\|FlowControl\|Branch`, `Utilities\|IsValid`, `Development\|PrintString` | IMPL E4, E7 |
| C1 | pas de nœud de concaténation : supprimer `_11`, puis `SL.K2Node_CallFunction_6` (`ToString(Float)`, sortie vers `_11` seulement). `VariableGet_25` n'est supprimé que si `get_node_infos` montre qu'il n'a pas d'autre liaison | IMPL E6 |
| C2 | **sauté** : les deux créations de `CharGenSlider` dans `CG` renseignent `PlayerCharacter` (`VariableSet_10`, `VariableSet_42`). D23 est sans objet (lp-mcp règle 4) | IMPL § 0.1 C2 |
| C3 | sous-graphe de 14 nœuds : `break_pins` (`ComponentBoundEvent_85#1` → `IfThenElse_37#0`), puis `delete_node` des **13** autres : `IfThenElse_37`, `CallFunction_59`, `VariableGet_280`, `IfThenElse_38`, `CallFunction_93`, `VariableGet_281`, `VariableGet_282`, `CallFunction_303`, `CommutativeAssociativeBinaryOperator_28`, `CallFunction_305`, `CallFunction_306`, `CommutativeAssociativeBinaryOperator_29`, `CallFunction_307` | IMPL E1 : le 16 de T3d est une erreur de compte (estimé). `CallFunction_307` n'a pas de liaison d'exécution : la trace de D18 ne s'exécutait pas. L'effet réel de D18 est le seul morph fixe (`CallFunction_303`), en Development comme en Shipping |
| C8 a (option) | insérer `ClearChildren` (cible ← `LoadScrollBox`) entre `CG.K2Node_CustomEvent_139#1` (then) et `VariableSet_508#0` ; `CallFunction_3001` est pure et reste inchangée | IMPL E2 |
| C9, lecture 1 | `VM.VariableGet_16` alimente la condition de la Branche `IfThenElse_1`. Insérer BV1 entre `VariableSet_1#0` (then) et `IfThenElse_1#0` : `IsValid` ← sortie de `VariableGet_16` ; BV1.then → `IfThenElse_1#0` ; **BV1.else → `Knot_0#0`**, la cible de `IfThenElse_1`.else. Avec la référence nulle, la condition valait faux et l'exécution suivait ce else : le comportement est identique | IMPL E3 ; règle ajoutée : une garde devant une Branche relie son else au else de cette Branche |
| C9, lecture 2 | modèle d'origine : BV2 entre `Knot_1` (← `DynamicCast_1` CastFailed) et `CallArrayFunction_0#0` ; `IsValid` ← sortie de `VariableGet_27` ; BV2.then → `CallArrayFunction_0#0` ; BV2.else → `CallFunction_16#0` | IMPL § 0.1 C9 |
| C10, C11 | **retirées de B1, reportées en B2** avec les autres corrections de `GI` (D2, D9, D17), pour une seule révision de `GI.uasset` (52,7 Mo). D3 et D27 sont du code non exécuté, sans effet en jeu. La règle stricte de C10 ne retient d'ailleurs aucun nœud (IMPL E5) ; en B2, seuls `GISP.CallFunction_0` et `_1` (`PrintString`, entrée d'exécution libre) seront supprimables. Le gel de `GI.uasset` peut être rendu | coût d'un binaire de 52,7 Mo pour un gain nul en jeu |
Hors champ, noté pour B2 : dans `VM`, la condition de `IfThenElse_1` lit aussi `VariableGet_15` (`IsMale` du personnage
édité) sans garde, par un `AND` pur (IMPL E3).
Périmètre de la reprise :
- cœur : C1, C3, C4, C5, C6 et C9 (2 lectures) ;
- options : C7 et C8 ;
- fichiers : `CharGenSlider`, `CharGen` et `VisualMorph` (.uasset) ;
- V1 attendu : ces 3 fichiers seulement.
## 10. Révision 3 (2026-10-20), après l'arrêt de la reprise v2
Constats de `CG2-IMPL-01` v2 :
- C1 est faite et enregistrée : `CharGenSlider.uasset`, MD5 `CBE53469FC73E7829A00710126095C7E`, compilé, journal propre.
- C3 a été faite en mémoire seulement. `CharGen` n'est **pas** enregistré : l'éditeur a été fermé sans enregistrer, et
le MD5 sur disque égale l'instantané.
- Arrêt : le mode auto de Claude Code a refusé deux fois un `create_node` dans `CharGen`. Ce refus attend le geste de
l'utilisateur ; il ne se contourne pas.
**F2, décision de la SPEC.** Le `type_id` `Utilities|IsValid` crée la **macro** `IsValid`. Cette macro a une entrée
d'exécution, une entrée objet et deux sorties d'exécution, `Is Valid` et `Is Not Valid`. Elle remplace le couple
« Branche + fonction `IsValid` » partout dans le § 2 et le § 9 (C5, C9 lectures 1 et 2) :
- l'exécution entrante est câblée sur l'entrée de la macro ;
- `Is Valid` remplace la sortie then ;
- `Is Not Valid` remplace la sortie else.
Le comportement est le même, avec un seul nœud et sans pure ; la règle 4 de lp-mcp (pas de pure composée) est
respectée.
Reprise à faire, sur le fichier de l'instantané : C3, C4, C5, C6, puis les options C7 et C8 dans `CharGen` ; C9 dans
`VisualMorph`. Elle n'aura lieu qu'après le geste de l'utilisateur sur le refus du mode auto, et avec un nouveau
BUILD-GO de Big Boss.