LifePlay-Revival/Docs/Migration/etat/REL/GIREV/GIREV-MCP-01.md
2026-10-21 09:36:04 +02:00

24 KiB
Raw Blame History

Fiche GIREV-MCP-01 — Niveau N1 — Modèle prévu non précisé par la fiche | utilisé claude-sonnet-5-5 — Agent lp-mcp (lecture seule) — Skills sk-protocol, lp-mcp, sk-change-safety

GIREV-MCP-01 : lecture MCP de GI pour GQ1 (garde D2 de SavePreset) et GQ4 (message de F6 / C11) (2026-10-21)

Lecture seule par unreal-mcp (éditeur headless pid 21652, port 8000, jeton de Big Boss ; non lancé, non fermé). Aucune écriture, aucune sauvegarde, aucune compilation. Seul ce fichier est écrit. Préalable : GIREV-PRE.md § 3.2 M2, M4, § 5 points 1 et 4, § 6 GQ1 et GQ4. Décisions de l'utilisateur citées par l'ordonnateur : GQ1 « oui » (établir le rôle de la garde avant de décider), GQ4 « on le rebranche et on évalue ».

Notation : EG = /Game/BPs/GI.GI:EventGraph, SP = /Game/BPs/GI.GI:SavePreset.

Résumé (à lire en premier)

  1. GQ1 : la garde D2 est inerte aujourd'hui et redondante (établi pour l'inertie, estimé pour le rôle). Le littéral est Characters\0.lpcharacter (un antislash, une extension) ; aucun des 11 appelants lus ne passe un File de cette forme (tous : séparateur /, pas d'extension, ou nom saisi par le joueur). Le rôle voulu probable : ne jamais écrire le fichier du « slot 0 ». Cette protection existe déjà, effective, en amont : SaveSlot > 0 dans DestroyPerson (IfThenElse_436) et dans SavePerson (IfThenElse_18). Recommandation : (a) laisser (0 écriture) ; (b) supprimer reste neutre ; (c) corriger le littéral change le comportement du seul appelant non gardé (ContactMenu) et n'a pas de rôle prouvé.
  2. GQ4 : le message n'est pas du code mort (établi). K2Node_CallFunction_20748 (ShowTutorial, String) et K2Node_CallFunction_13122 (PrintString) sont bien orphelins (execute sans liaison), mais K2Node_CallFunction_340 (ShowTutorialTxt, même titre, même contenu, Force et Warning à true) est atteint par IfThenElse_2861.else : le message « missing crucial *.lpcharacter files » s'affiche déjà quand le chargement d'une partie ne lit rien dans Player.lpcharacter. La prémisse de GIREV-PRE M2 (« le message deviendrait atteignable ») est donc fausse pour le texte visible ; elle est vraie seulement pour le PrintString de journal.
  3. Conséquence pour « on le rebranche » : rebrancher _20748 ferait afficher le message deux fois (établi par les liaisons). Les trois voies utiles sont au § B.5 ; recommandation : supprimer _20748 et _13122 (C11) et réécrire le texte de _340 (2 set_pin_value sur des broches Text, faisabilité à confirmer).

1. Appels MCP (tous en lecture, dans l'ordre)

# Appel (toolset / outil) Arguments Résultat
1 list_toolsets — liste complète, editor_toolset.toolsets.blueprint.BlueprintTools présent : connexion établie
2 AssetTools.load_asset /Game/BPs/GI /Game/BPs/GI.GI
3 BlueprintTools.get_node_infos SP.K2Node_IfThenElse_2970, SP.K2Node_CallFunction_19325 liaisons et littéral (§ A.1)
4 BlueprintTools.find_nodes EG, titre SavePreset _104, _16676, _8085
5 get_node_infos ces 3 nœuds broches File, Var, StatOnly, IncludeStat
6 get_node_infos EG Concat_12, _2523, _827 littéraux de File
7 get_node_infos EG Concat_698, VariableGet_87, CallFunction_105, VariableGet_19305, CallFunction_8086 Saves/ + Slot + /Characters/, Prefix, ToString(SaveSlot)
8 get_graphs (outil inexistant : « Unknown tool get_graphs ») puis ObjectTools.list_properties (refusé : paramètre instance manquant) — rien utilisé ; la liste des graphes de GI est tirée des dumps (§ A.2)
9-11 find_nodes titre SavePreset GI:GeneratePerson, GI:GenerateCreature, GI:saveOldPlayer 2, 1, 1 appelants
12-13 get_node_infos saveOldPlayer.CallFunction_1, GeneratePerson _20437, _684, GenerateCreature _684 ; leurs Concat_2411 / _827 File
14 get_node_infos GeneratePerson.CallFunction_4486, puis MacroInstance_1386 ToString d'un IncrementInt
15-19 find_nodes titre SavePreset /Game/UI/StatMenu, /Game/UI/ContactMenu, /Game/BPs/Room, /Game/UI/CharGen, /Game/UI/Builder (graphe EventGraph) 1, 1, 1 (événement), 1, 1
20 get_node_infos les 5 nœuds ci-dessus Room et Builder = événement SavePreset de Room, pas celui de GI
21-22 get_node_infos StatMenu/CharGen CallFunction_5136, _5135 ; ContactMenu Concat_827, CallFunction_8086 File = texte du champ (StatMenu, CharGen) ; Saves/_session/Characters/ + VariableGet_4523 + ToString (ContactMenu)
23 get_node_infos EG.IfThenElse_436, _4453, _39 garde SaveSlot > 0 de DestroyPerson
24 get_node_infos EG _20748, _13122, _340, IfThenElse_2861 broches du message (§ B.1)
25 get_node_infos EG CallFunction_177, IfThenElse_2377, CallFunction_213 condition Len(...) > 0, branche Load
26 get_node_infos EG CallFunction_176, CustomEvent_17, Concat_15 événement DuplicateCharacters(Load, Slot), chemin Player.lpcharacter
27 get_node_infos EG CallFunction_173, _408, _13784, VariableSet_541 LoadTxt (ModdingExtra), LoadPreset, SaveTxt
28 find_nodes EG, titre DuplicateCharacters CustomEvent_17, CallFunction_14865, CallFunction_14866
29 get_node_infos CallFunction_14865, _14866 ; CustomEvent_955, _16 appelants : événements LoadGame et SaveGame

Lectures hors MCP : Read GIREV-PRE.md ; rg -a -l sur Content, Source, Plugins, Saved ; rg --no-ignore -a sur les dumps STE-ORG4cV_LPDumpFunction_20261014-103731.txt (« GEV »), STE-H10V_…20261013-071350.txt, L6f_dump_GI.txt (5.5) ; Read STE-H10-SPEC.md:160-200.

A. GQ1 : garde D2 de SavePreset

A.1 Liaisons et valeur exacte (appels 3, établi)

  • SP.K2Node_IfThenElse_2970 : execute ← FunctionEntry_799.then ; Condition ← CallFunction_19325.ReturnValue ; then : aucune liaison (la fonction s'arrête) ; else → IfThenElse_10253.execute.
  • SP.K2Node_CallFunction_19325 (Utilities|String|EndsWith) : SourceString ← FunctionEntry_799.pin 1 (File) ; InSuffix = Characters\0.lpcharacter (le dump JSON montre "Characters\\0.lpcharacter", soit un seul antislash) ; SearchCase = IgnoreCase.
  • Conclusion de lecture : la garde ne vaut que pour un File finissant littéralement par Characters\0.lpcharacter, c'est-à-dire avec antislash et extension.

A.2 Appelants de SavePreset de GI et valeur de File (appels 4-7, 9-22, établi)

Recherche : find_nodes titre SavePreset sur le graphe de chaque BP, plus rg -a -l SavePreset Content (BP contenant la chaîne : GI, StatMenu, ContactMenu, Room, CharGen, Builder ; aucun dans Person, PC, MainMenu). Les graphes de fonction de GI viennent du dump 5.5 (L6f_dump_GI.txt:17470, :17701, :36223, :37957 → GeneratePerson ×2, GenerateCreature, saveOldPlayer) puis relus par MCP. Les graphes de fonction de StatMenu, ContactMenu, CharGen n'ont pas été énumérés (aucun outil de liste de graphes trouvé, appel 8) : un appelant dans une fonction de ces trois BP reste possible (incertain).

# Appelant (nœud) File Extension / séparateur Garde D2 déclenchée ?
1 EG.CallFunction_104 (dans DestroyPerson, CustomEvent_3172) Saves/_session/Characters/ + Prefix + ToString(SaveSlot) (Concat_12) /, sans extension non
2 EG.CallFunction_8085 (événement SavePerson, CustomEvent_32) idem (Concat_827) idem non ; précédé de IfThenElse_18 ← Greater_IntInt(SaveSlot, 0) (CallFunction_2016, dump STE-ORG4cV:18040) : jamais pour le slot 0
3 EG.CallFunction_16676 (dans DuplicateCharacters, branche Load = faux) Saves/ + Slot + /Characters/ + Player (Concat_698 puis _2523) /, sans extension non
4 GeneratePerson.CallFunction_20437 Saves/_session/Characters/ + ToString(IncrementInt) (Concat_2411, CallFunction_4486, MacroInstance_1386) / non ; compteur incrémenté donc ≥ 1 (estimé : valeur initiale non lue)
5 GeneratePerson.CallFunction_684 Saves/_session/Characters/F + chaîne (Concat_827) / non
6 GenerateCreature.CallFunction_684 Saves/_session/Characters/C + chaîne / non
7 saveOldPlayer.CallFunction_1 littéral Saves/_session/Characters/OldPlayer / non
8 StatMenu.EventGraph.CallFunction_5375 texte du champ TextBox (GetText → ToString), StatOnly = vrai libre (saisie du joueur) non, sauf saisie volontaire du suffixe exact
9 CharGen.EventGraph.CallFunction_5375 idem, StatOnly = faux, IncludeStat ← EnumEquality_0 libre idem
10 ContactMenu.EventGraph.CallFunction_509 Saves/_session/Characters/ + VariableGet_4523 + ToString(…) (Concat_827, CallFunction_8086 ← VariableGet_3021) / non ; seul appelant non gardé par SaveSlot > 0 identifié : la valeur de VariableGet_3021 et la condition CallFunction_72 n'ont pas été relues (incertain)
— Room.CustomEvent_15 et Builder.CallFunction_27 n'appellent pas GI.SavePreset : événement SavePreset(Path) propre à Room — sans objet

Aucun appelant ne passe un File avec antislash ni avec l'extension : le suffixe de la garde ne peut correspondre qu'à une saisie volontaire (et CG2 C7 filtre déjà .., /, \ côté CharGen, GIREV-PRE.md § 3.2 M5).

A.3 Qui crée, lit ou utilise Characters/0.lpcharacter (établi pour les absences, estimé pour le sens)

  • Existence sur disque : Content/Saves/ contient Default/Characters/Player.lpcharacter et _session/Characters/{1,2,3}.lpcharacter ; aucun 0.lpcharacter (find sur Content/Saves). Saved/Saves absent de ce dépôt. Aucun fichier *0.lpcharacter ailleurs : rg -a -l "0\.lpcharacter" sur Content, Source, Plugins, Saved/Saves, Docs ne répond que GI.uasset et des dumps/fiches (STE-H10-SPEC.md:176, dumps STE-H10V, STE-D9, L6f). Aucune occurrence dans Content/Modules pour ce nom (la seule mention de lpcharacter y est vin_Interracial/scenes/set_stereotypes.lpscene) ; Source : seule mention LPStringCompat.h:9 (commentaire sur les 141 préréglages).
  • Journal du build COM21 (COMMUN-21-BILAN.md:40) : après une session, Saved\Saves\_session\Characters\1.lpcharacter créé ; relevé à 3 fichiers, aucun 0.
  • Le joueur n'est pas le slot 0 : le joueur est enregistré sous …/Characters/Player (appelant 3, Concat_15 ajoute Player.lpcharacter : EG.CommutativeAssociativeBinaryOperator_15.B = Player.lpcharacter) et Default/Characters/Player.lpcharacter ; l'ancien joueur sous OldPlayer (appelant 7). Le slot 0 (Prefix vide, SaveSlot 0) est donc une personne sans emplacement attribué (estimé : l'unité de test STA-T2b-PERSON-DIAG.md:203 lie Len(Prefix) == 0 aux « numérotés » 1, 2, 3…).
  • Qui écrirait 0.lpcharacter : un appel de SavePreset avec Prefix vide et SaveSlot 0 (cas des appelants 1, 2, 10) ; SP.Append_762 ajoute .lpcharacter après la garde (GIREV-PRE.md § 3.2 M5), donc le fichier produit serait bien Saves/_session/Characters/0.lpcharacter. Les appelants 1 et 2 sont fermés au slot 0 par SaveSlot > 0 : DestroyPerson — EG.IfThenElse_436 (Condition ← CallFunction_106, A ← VariableGet_86.SaveSlot dans le dump STE-ORG4cV:6474) : then → IfThenElse_39 (chaîne vers la sauvegarde), else → IfThenElse_4453 → IfThenElse_1766 (suite après RestoreCbe, STE-H10-SPEC.md:172) ; la seule liaison d'exécution vers CallFunction_104 vient de IfThenElse_216.then et VariableSet_393.then (appel 5, établi). Que CallFunction_106 soit bien Greater_IntInt(SaveSlot, 0) n'a pas été relu (estimé d'après STE-H10-SPEC.md:168).
  • Qui lit 0.lpcharacter : aucun lecteur trouvé. Les lectures de personnage passent par LoadPreset (CallFunction_213, _408, chemin …/Player.lpcharacter) ; aucun chemin Characters/0 dans les dumps.

A.4 Conclusion GQ1

  • Rôle voulu probable (estimé) : empêcher l'écriture d'un fichier « slot 0 » par SavePreset. La forme du littéral (antislash, extension complète) évoque une version ancienne où File était un chemin complet de fichier Windows ; la fonction a ensuite reçu l'extension en interne (Append_762), ce qui a rendu la garde inopérante.
  • Se déclenche-t-elle aujourd'hui ? Non : établi pour les 10 appelants lus (§ A.2) ; incertain pour d'éventuels appelants dans des fonctions de StatMenu/ContactMenu/CharGen non énumérées et pour la valeur de SaveSlot côté ContactMenu.
  • Effets :
    • (a) laisser : aucun changement ; la garde reste un code inerte de 2 nœuds ; 0 écriture MCP. Le slot 0 est déjà protégé par SaveSlot > 0 (appelants 1, 2).
    • (b) supprimer : comportement inchangé tant que la garde est inerte (établi par A.2) ; coût estimé 5 écritures (break_pins ×2 sur IfThenElse_2970, connect_pins FunctionEntry_799 → IfThenElse_10253, delete_node ×2) ; perte d'une défense dormante si un appelant futur passe cette forme.
    • (c) corriger le littéral (par exemple Characters/0 sans extension) : change le comportement pour tout File finissant ainsi, c'est-à-dire pour l'appelant 10 (ContactMenu) s'il passe un slot 0 avec préfixe vide : il n'écrirait plus 0.lpcharacter. Effet inconnu faute de preuve que ce cas se présente ; set_pin_value seul ne marque pas le paquet (GIREV-PRE.md § 3.9). Non recommandé.
  • Recommandation : (a), éventuellement (b) si l'utilisateur veut supprimer le code mort ; (c) seulement si un test montre qu'un 0.lpcharacter est produit en jeu (essai : build Development, parcours ContactMenu sur une personne de slot 0, relevé de Saved\Saves\_session\Characters\).

B. GQ4 : message de F6 / C11

B.1 Broches lues (appel 24, établi)

Nœud execute then Valeurs
EG.K2Node_CallFunction_20748 (` ShowTutorial`, String) aucune liaison aucune
EG.K2Node_CallFunction_13122 (`Development PrintString`) aucune liaison → CallFunction_340.execute
EG.K2Node_CallFunction_340 (` ShowTutorialTxt`, Text) ← 13122.then et IfThenElse_2861.else aucune

Code mort : _20748 et _13122 (aucun execute entrant). Pas code mort : _340, atteint par 2861.else ; ShowTutorialTxt convertit ses deux Text en String et appelle ShowTutorial avec Force et Warning (STE-ORG4cV…:18487-18516, CustomEvent_33, CallFunction_136/137/138). Donc l'écran du message est identique à celui que produirait _20748.

B.2 Contexte amont (appels 24-29, établi)

Fonction : événement personnalisé DuplicateCharacters(Load: bool, Slot: string) (EG.CustomEvent_17), appelé par :

  • CallFunction_14865 avec Load = true, Slot ← CustomEvent_955 (événement LoadGame(Name, Index)) ;
  • CallFunction_14866 avec Load = false, Slot ← CustomEvent_16 (événement SaveGame(Name, Index, Notes)).

Chaîne (Load = vrai) : IfThenElse_2377 (Condition ← CustomEvent_17.Load) then → IfThenElse_2861 (Condition ← CallFunction_177 = Len(...) > 0, B = 0 ; A ← CallFunction_176 = Len(S) ; S ← CallFunction_173.SaveTextA = LoadTxt(FileNameA = Append_15) ; Append_15 = Saves/<Slot>/Characters/ + Player.lpcharacter) :

  • then (texte non vide) → CallFunction_213 (LoadPreset, même Path, Blend = faux) → CallFunction_408 (LoadPreset, Blend = vrai) ;
  • else (texte vide : fichier absent ou illisible) → CallFunction_340 : le message. 2377.else (Load = faux) → CallFunction_16676 (SavePreset du joueur).

Sens de la condition « personnages manquants » (établi pour la lecture, estimé pour l'intention) : le chargement d'une partie ne rend aucune lecture de Saves/<Slot>/Characters/Player.lpcharacter. Seul le fichier du joueur est testé, pas les numérotés 1.lpcharacter, F…, C… (le texte dit « missing crucial *.lpcharacter files » au pluriel : estimé, c'est le fichier crucial qui sert de témoin).

B.3 Le message est-il déjà vu aujourd'hui ?

  • Oui, sur un chargement dont Player.lpcharacter est absent de toutes les racines : atteignable (établi par les liaisons). Aucune preuve qu'il se soit présenté : le journal COM23 ne porte ni son texte ni Missing characters (GIREV-PRE.md n° 23) ; le bilan COM21 n'a relevé aucun LoadTxt ECHEC autre que OldPlayer et ModLauncher.config (COMMUN-21-BILAN.md:53, :66), donc Player.lpcharacter a été lu.
  • Avec F6 (FIX1-F6-SPEC.md:33) la lecture de Saves/<Slot>/… prend <Saved>/Saves/<Slot> si le dossier existe, sinon <Content>/Saves/<Slot>, sinon <Saved> : un ancien emplacement de Content/Saves est donc toujours lu (repli). Le message n'apparaît qu'en l'absence du fichier dans ces racines.

B.4 Faux positifs et fréquence (estimé, aucun essai)

  • Une partie enregistrée par ce jeu écrit toujours Player.lpcharacter : SaveGame → DuplicateCharacters(Load=false) → SavePreset (appelant 3). Pas de faux positif pour une partie créée par la build courante (non essayé en jeu).
  • Un LoadGame de partie « neuve » : la nouvelle partie utilise Content/Saves/Default/Characters/Player.lpcharacter (présent au dépôt) ; que la nouvelle partie passe par LoadGame("Default") n'est pas établi (appelants de LoadGame non lus). Pas de faux positif si Default est lu avec repli.
  • Partie sans personnage : le message se déclenche, comme voulu (le texte parle de fichiers manquants).
  • Fréquence attendue : rare (partie copiée d'une autre version sans Characters, dossier supprimé, ou slot renommé). Le jeu écrit déjà LoadTxt ECHEC | '<chemin>' au journal dans ce cas (COMMUN-21-BILAN.md:66) : le PrintString ajouterait une seconde trace.

B.5 Où « rebrancher » et ce que cela donnerait (propositions, estimé)

Voie Écritures MCP Effet visible Remarque
V1. Relier _20748 (la demande littérale) 2 (connect_pins d'un execute vers _20748, par exemple 2861.else, puis rupture de 2861.else → _340) le même message deux fois si les deux restent reliés ; une fois si _340 est coupé n'apporte rien : _340 est déjà ce nœud. Non recommandé.
V2. Relier seulement le PrintString _13122 2 : break_pins (2861.else → _340.execute) et connect_pins (2861.else → _13122.execute) ; _13122.then → _340 déjà relié message à l'écran inchangé + ligne de journal Missing characters from save (Development) + texte bleu 2 s à l'écran (PrintString n'imprime rien en Shipping, CG2-SPEC-01.md:115) trace redondante avec LoadTxt ECHEC ; Key = None : s'empile
V3 (recommandée). Supprimer _20748 et _13122, réécrire le texte de _340 2 delete_node (+ 1 break_pins implicite) puis 2 set_pin_value (broches Text Title, Content de _340) message corrigé au prochain chargement manquant ; aucune autre différence la clé NSLOCTEXT ([3787EBBA…], F9D9C9AF…) peut être perdue ou conservée selon le comportement du MCP sur une broche Text : incertain (essai éditeur sur une copie). Les suppressions marquent le paquet ; set_pin_value seul ne le ferait pas (GIREV-PRE.md § 3.9).

Nouveau texte proposé (à valider, adapté à la redirection F6 vers Saved/Saves, FIX1-F6-SPEC.md:32-33) :

  • Title : conserver Save Missing Character Data!.
  • Content : The save you just loaded is missing crucial *.lpcharacter files. Saves are now kept in LifePlay\Saved\Saves. If this save comes from an older version, copy its folder from your old LifePlay\Content\Saves (the folder named like the save) into LifePlay\Saved\Saves of the current version, then try to load the save again. You can Alt Tab and do this copying (no need to exit the game).
  • Force = true, Warning = true : inchangés (valeurs actuelles de _340) ; aucune raison établie de les modifier.

Évaluation chiffrée (estimé) : V3 = 4 à 5 écritures, risque très faible (suppression de nœuds sans exécution entrante), une seule différence visible pour le joueur : le texte, uniquement dans le cas où le message s'affiche déjà. Preuve : relecture get_node_infos de _340 et compilation ; en jeu, un chargement volontairement sans Player.lpcharacter (copie d'essai d'un slot, fichier renommé) lit l'écran et le journal (LoadTxt ECHEC attendu).

C. Établi / estimé / incertain

Établi (appels MCP cités) : littéral, liaisons et then vide de la garde (appel 3) ; File de 10 appelants (appels 5-7, 12-14, 21-22) ; Room/Builder n'appellent pas GI.SavePreset (appel 20) ; _20748 et _13122 sans execute entrant, _340 atteint par 2861.else, textes et valeurs (appel 24) ; condition Len(LoadTxt(Saves/<Slot>/Characters/Player.lpcharacter)) > 0 et appelants LoadGame / SaveGame (appels 25-29) ; ShowTutorialTxt = ShowTutorial après conversion (dump STE-ORG4cV:18487-18516) ; aucun 0.lpcharacter dans les dossiers et sources cherchés.

Estimé : rôle de la garde (écriture du slot 0 interdite) ; slot 0 sans emplacement attribué ; CallFunction_106 = SaveSlot > 0 ; compteur de GeneratePerson ≥ 1 ; fréquence et faux positifs du message ; nombre d'écritures.

Incertain (essai qui trancherait) : appelants de SavePreset dans les fonctions de StatMenu, ContactMenu, CharGen (lister leurs graphes, rg --no-ignore sur de futurs dumps LPDumpFunction -Fn=*) ; valeur de SaveSlot et condition CallFunction_72 côté ContactMenu (lire VariableGet_3021, _4523) ; conservation de la clé NSLOCTEXT par set_pin_value (essai sur une copie) ; si la nouvelle partie passe par LoadGame("Default") (lire les appelants de CustomEvent_955) ; fin de la chaîne IfThenElse_1766 (non suivie).

D. Écarts à la fiche et à GIREV-PRE

  • GIREV-PRE M2 est à corriger : _20748 n'est pas « le message affiché » mais un doublon mort de _340 (qui l'est). « Le message deviendrait atteignable » (§ 3.2 M2) est faux pour l'écran ; la décision GQ4 « on le rebranche » repose sur cette prémisse : à re-soumettre à l'utilisateur avec V1/V2/V3.
  • GIREV-PRE M4 écrit que le suffixe a un antislash : confirmé (un seul).
  • Appel 8 : get_graphs n'existe pas et list_properties demande instance ; la liste des graphes n'a pas été obtenue par MCP (sans conséquence sur les chiffres de GI, tirés des dumps puis relus).

Fichiers

  • Écrit : D:\Game\LifePlay-master 5.8\Docs\Migration\etat\REL\GIREV\GIREV-MCP-01.md.
  • À commiter : A Docs/Migration/etat/REL/GIREV/GIREV-MCP-01.md (par le gardien, sur ticket). Aucun autre fichier écrit ; éditeur laissé ouvert (pid 21652).

Tours : 36 / 40 (comptés à la main ; python -I Tools/FicheStats.py --lot GIREV fait foi)

À verser : lp-mcp § 3 — dans un BP, find_nodes {graph:{refPath:"/Game/UI/X.X:EventGraph"}, title} fonctionne sans load_asset préalable ; get_graphs n'existe pas ; un événement personnalisé et un appel peuvent porter le même nom (ex. Room.SavePreset ≠ GI.SavePreset) : lire le type_id du nœud (Presets|SavePreset pour GI, AddEvent|Custom|SavePreset ou |SavePreset pour Room). Avant de déclarer un nœud de message « mort », chercher son jumeau de type Text (ShowTutorialTxt) : il peut porter le même texte et être vivant.