20 KiB
Fiche STB-GIB-DATA — Niveau N1 — Modèle prévu modèle de l'agent lp-inventory (non nommé dans la fiche) | utilisé Sonnet 5.5 (claude-sonnet-5-5) — Agent lp-inventory — Skills sk-protocol, sk-recount, lp-paths
STB-GIB-DATA-INV : lignes de données fautives de Clothes4.txt (K1) et de Modules/MorphTags (K2) (2026-10-09)
Abréviations : EG = D:\Game\LifePlay-master 5.5\Docs\Migration\etat\ST\STA\dumps\GI__EventGraph.txt ; LOG = D:\Game\LifePlay_Build_5.8_Development_U8_essai\Windows\LifePlay\Saved\Logs\LifePlay.log ; MOD = D:\Game\LifePlay-master 5.8\Content\Modules (dépôt local, copie 5.8) ; SP = scratchpad de session (%USERPROFILE%\AppData\Local\Temp\claude\D--Game-LifePlay-master-5-8\87a0d630-8082-4d24-9a2d-960932aa8255\scratchpad, volatil).
1. Commandes exactes
Fichiers lus (identification, preuve dump:ligne) :
- Read
EGoffsets 28080-28171, 28170-28249, 28250-28379, 28680-28819 ; GrepClothes4surEG(-n) ; GrepMorphTags|GetAllFilesFromFolder|PopulateEachMorphTags|Lines_PopEaMorTagsurEG(-n) ; GrepMorphTagFilessur...\etat\ST\STA(1 résultat, le DIAG). - Octets du dump :
python -I SP\dumpbytes.py EG(ligne 28707 et 28150 =Delimiter = '+\r). - Code lu :
Source\LifePlay\LPStringCompat.cpp:5-27(ParseIntoArray) ;Plugins\ModdingExtra\Source\ModdingExtra\Private\ModdingExtraBPLibrary.cpp:181-232(LoadTxt = cacheFLPDataCacheouFFileHelper::LoadFileToString(ProjectContentDir + nom)). - Journal : Grep sur
LOGdeAttempted to access index 3 from array CallFunc_ParseIntoArray_ReturnValue_3 of length 3!,... index 1 ... _29 of length 1!,... _28 of length 1!,GI_C:PopulateAllMorphTags$,STARTUPCHECK - Person BeginPlay(-n, offsets pour premier/dernier). - Disque :
ls -la MOD,ls -la MOD\MorphTags,md5sumdeClothes4.txt(copie 5.8 et build U8 essai). - Script de lecture (SP, python -I, lecture seule) :
analyse.py(charge le fichier comme LoadFileToString : BOM retiré, UTF-8 ; découpe en lignes puis sur': 'avec CullEmpty = true, algorithme deLPStringCompat.cpp:13-24, deux modèles de délimiteur de lignes : A =\n, B =\r\n),k1.py,k1b.py(exporteSP\k1_bad_Clothes4.tsv),k2.py(exporteSP\k2_bad_<fichier>.txt),uasset.py/uasset2.py(recherche de chaînes dansContent\BPs\GI.uasset). - Recomptes par seconde méthode (Grep, regex) :
- K1 lignes à 3 champs : Grep
^(?:[^:]|:[^ ])*: (?:[^:]|:[^ ])*: (?:[^:]|:[^ ])*$count surMOD\Clothes4.txt; lignes à 4 champs ou plus : même motif avec 3:suivis de:; total : Grep^count. - K2 lignes non vides sans
:: Grep^[^:\r\n](?:[^:]|:[^ ])*$count surMOD\MorphTags; contrôle des numéros de ligne en mode content -n surtrueBodies.txtetfalseBodies.txt.
- K1 lignes à 3 champs : Grep
- Contrôle d'intégrité :
git status --porcelaindansMOD(0 ligne) et dans la copie 5.8 (voir § 3).
2. Comptes bruts
2.1 K1 — populateClothes4, fichier lu : Modules/Clothes4.txt
Preuve dump (établi) : EG:28699-28703 ModdingExtraBPLibrary::LoadTxt, FileNameA = 'Modules/Clothes4.txt' (nœud CallFunction_1065, dans l'événement K2Node_CustomEvent_98, EG:28696-28698) → EG:28704-28709 ParseIntoArray (CallFunction_3047) séparateur de lignes (retour à la ligne, voir § 4), CullEmptyStrings = 'true' (EG:28708) → Lines_PopClothes4 (EG:28710) → boucle MacroInstance_71 (EG:28716-28722) → EG:28743-28748 CallFunction_1061 séparateur ': ', CullEmptyStrings = 'true' (EG:28747) → GetArrayItem_62..65 index 0, 1, 2, 3 (EG:28749-28751, 28764-28766, 28773-28775, 28793-28795). Index 0 sert de nom de maillage ('/Game/Heavy/Clothes4/' + nom, EG:28753-28756), index 1 est comparé à 'true' (EG:28768-28772), index 2 est découpé sur ', ' (EG:28777-28782), index 3 est découpé sur ', ' puis testé contre 'sports' et 'formal' (EG:28783-28802). Aucun autre fichier n'est lu par ce nœud (Grep Clothes4 sur EG : 5 lignes, toutes dans ce bloc).
Fichier : MOD\Clothes4.txt, 39931 octets, sans BOM, 956 CRLF = 956 LF = 956 CR (aucun CR ou LF isolé), 957 lignes physiques (la dernière sans fin de ligne), 0 ligne vide (script : 957 lignes après CullEmpty = 957 physiques). Copie du build U8 essai identique (md5 4c14ef29e24e40417290ee0bdf801ab0 des deux).
Répartition par nombre de champs (script, modèles A et B identiques) : {3 champs : 570, 4 champs : 387}, total 957. Recompte Grep : 3 champs = 570, 4 champs ou plus = 387, lignes = 957 (570 + 387 = 957).
Journal : LOG contient 570 avertissements index 3 ... _3 of length 3!, tous de longueur 3 (570 avec « length 3 », 570 avec « index 3 »), en une seule rafale continue LOG:1021-6150 (570 × 9 lignes = 5130 ; 1021 + 5130 = 6151), horodatée 16:43:06.252 à 16:43:06.290, pile Person_C:ReceiveBeginPlay → ExecuteUbergraph_Person → GI_C:populateClothes4 → ExecuteUbergraph_GI (LOG:1021-1028). Aucun avertissement K1 aux 12 Person BeginPlay suivants (LOG:6212-6234, 16:43:17).
Lignes fautives K1 : 570 = 570 lignes à 3 champs × 1 passage = 570 avertissements. Égalité exacte.
Liste exhaustive MOD\Clothes4.txt:<ligne> (numéros de ligne physique, 93 plages ; le contenu de chacune des 570 lignes est dans SP\k1_bad_Clothes4.tsv, colonnes fichier, ligne, nombre de champs, contenu tronqué à 120 caractères) :
3 ; 8-9 ; 12 ; 15-16 ; 18-21 ; 27 ; 30-34 ; 36-44 ; 58 ; 60 ; 64-68 ; 70-72 ; 74 ; 77-78 ; 81 ; 83-87 ; 89-95 ; 97-100 ; 103 ; 106-108 ; 110-114 ; 122-123 ; 127-133 ; 135-142 ; 144-145 ; 147-151 ; 153-156 ; 162-167 ; 169-171 ; 173-177 ; 183 ; 192 ; 194-196 ; 203-205 ; 209-215 ; 217-218 ; 222-223 ; 225-228 ; 237 ; 239-246 ; 248-253 ; 258-261 ; 263 ; 284 ; 287 ; 292-296 ; 304 ; 306-317 ; 323-332 ; 417 ; 442-445 ; 448-449 ; 453-473 ; 475 ; 477 ; 479-483 ; 485-486 ; 488 ; 491-493 ; 496-506 ; 508 ; 510-515 ; 517 ; 520-521 ; 523 ; 525 ; 527-529 ; 531-534 ; 549 ; 552-559 ; 561-563 ; 565-567 ; 576-577 ; 579 ; 585 ; 589-597 ; 599-611 ; 613-620 ; 622-630 ; 632-644 ; 650-656 ; 659-670 ; 672-697 ; 703-726 ; 730-733 ; 736-741 ; 743-767 ; 771-775 ; 780-781 ; 786-788 ; 792-890 ; 897-900 ; 926-957.
Exemples (premières lignes fautives, contenu exact) : 3: London-Look-Vest_1_F: false: Top ; 8: Cutout-Shoulder-Shirt_1_F: false: Top ; 9: Ruffle-Skirt_1_F: false: Bottom ; 12: Summer-Dress_1_F: false: Top, Bottom ; 15: Brynn-Pants_1_F: false: Bottom ; 16: Floral-Fiesta-Panty_1_F: false: Bottom_Under. Toutes ont la forme <nom>: <true|false>: <types> ; la dernière ligne du fichier (957) est fautive.
Structure des 570 : champ 2 = false pour 380, true pour 190 ; champ 3 (types) : une seule valeur pour 527, deux ou plus (, ) pour 43 ; 37 valeurs distinctes de types (Top 133, Bottom 112, Foot 50, Outerwear 40, Neck 37, Wrist 32, Top, Bottom 31, ...). Aucune ligne à 1 ou 2 champs.
Le 4e champ est donc un champ facultatif : les 387 lignes qui le portent donnent 20 jetons distincts (ParUn 163, Sports 93, Uniform 48, Formal 40, Heels 37, 0.8 29, Home 27, Ethnic 21, Asian 13, ...) ; aucun jeton neutre du type « aucun ».
2.2 K2 — PopulateEachMorphTags, fichiers lus : Modules/MorphTags/<Filename>.txt
Preuve dump (établi) : événement K2Node_CustomEvent_91, paramètre Filename (EG:28138-28141) → CallFunction_1031 LoadTxt, FileNameA = concaténation 'Modules/MorphTags/' + Filename + '.txt' (EG:28142-28146, 28153-28158) → CallFunction_1032 ParseIntoArray en lignes, CullEmptyStrings = 'true' (EG:28147-28152) → Lines_PopEaMorTag (EG:28159-28164) → CallFunction_1011 StartsWith(Filename, 'true', IgnoreCase) (EG:28172-28177) → IfThenElse_202 (EG:28178-28182). Branche vraie : MacroInstance_65 (EG:28165-28171) → CallFunction_1016 ': ', CullEmpty true (EG:28183-28188) → GetArrayItem_57 index 0 (EG:28189-28192) et GetArrayItem_58 index 1 (EG:28193-28196) → Map_Add(MorphTags_true) (EG:28200-28206). Branche fausse : MacroInstance_64 (EG:28207-28213) → CallFunction_1012 ': ', CullEmpty true (EG:28214-28219) → GetArrayItem_55 index 0 / GetArrayItem_56 index 1 (EG:28220-28227) → Map_Add(MorphTags_false) (EG:28231-28237).
Appelant : K2Node_CustomEvent_93 (EG:28265-28267) vide les tables puis boucle MorphTagFiles (MacroInstance_66, EG:28268-28277) et appelle PopulateEachMorphTags(Filename) (CallFunction_1022, EG:28278-28282).
Liste des fichiers : le dump ne contient pas le contenu de la variable MorphTagFiles (valeur par défaut). Recherche d'octets dans Content\BPs\GI.uasset : tableau de 6 chaînes consécutives falseBodies, falseFaces, falseSexies, trueBodies, trueFaces, trueSexies à l'offset 28280219 (SP\uasset2.py). Rattachement à MorphTagFiles : estimé (voir § 4) ; il est confirmé par les comptes ci-dessous.
Fichiers MOD\MorphTags\ (9 fichiers, tous sans BOM, CRLF = LF, aucun CR isolé) :
| Fichier | Lu par la boucle | Lignes physiques | Lignes vides physiques | Champs (modèle B) | Lignes à 1 champ |
|---|---|---|---|---|---|
| falseBodies.txt | oui | 28 | aucune | {1 : 12, 2 : 16} | 12 |
| falseFaces.txt | oui | 264 | aucune | {2 : 264} | 0 |
| falseSexies.txt | oui | 29 | 29 | {1 : 28} | 28 |
| trueBodies.txt | oui | 22 | 21, 22 | {1 : 12, 2 : 8} (20 lignes) | 12 |
| trueFaces.txt | oui | 140 | aucune | {2 : 140} | 0 |
| trueSexies.txt | oui | 8 | aucune | {1 : 8} | 8 |
| AllMorphTags.txt, allClothingMorphs.txt, trueTopSimplify.txt | non (hors liste) | 17, 59, 1070 | 11, 12, 17 ; aucune ; aucune | 1 champ partout | sans objet (non lus par ce chemin) |
Recompte Grep (^[^:\r\n](?:[^:]|:[^ ])*$, count) : falseSexies 28, trueSexies 8, trueBodies 12, falseBodies 12, falseFaces et trueFaces absents (0). Égal au script.
Journal : LOG contient 60 avertissements K2, tous « index 1 ... of length 1 » : 40 sur _29 (LOG:6243-6906, 17 lignes chacun, 6243 + 39 × 17 = 6906) puis 20 sur _28 (LOG:6923-7246), contigus, horodatés 16:43:17.377 à 16:43:17.384, pile LoadSettings → PopulateRaws → PopulateAllMorphTags → PopulateEachMorphTags (LOG:6247-6258). GI_C:PopulateAllMorphTags$ = 60 occurrences (une par avertissement), soit une seule exécution de PopulateAllMorphTags.
Rapprochement : fichiers « false » lus en premier dans l'ordre de la liste : falseBodies 12 + falseSexies 28 = 40 ; fichiers « true » : trueBodies 12 + trueSexies 8 = 20 ; 40 puis 20 = ordre du journal, 1 passage. Total 60 = 60.
Lignes fautives K2 (60), MOD\MorphTags\<fichier>:<ligne>:<contenu>, toutes un nom de morph sans ': ' (donc 1 champ) :
- falseBodies.txt (12) : 5
FBMEmaciated; 6FBMThin; 8FBMStephanie8; 19FBMVoluptuous; 20CTRLFitness; 21FBMFitnessSize; 23CTRLBodybuilder; 24FBMBodybuilderSize; 25FBMPearFigure; 26FBMBodySize; 27FBMHeavy; 28CTRLWeight. - trueBodies.txt (12) : 1
CTRLFitness; 2FBMFitnessSize; 10CTRLBodybuilder; 11FBMBodybuilderSize; 13FBMLithe; 14FBMThin; 15FBMEmaciated; 16FBMStocky; 17FBMPortly; 18FBMBodySize; 19FBMHeavy; 20CTRLWeight. - falseSexies.txt (28) : 1
PBMBreastsShape08; 2PBMBreastsShape07; 3PBMBreastsShape06; 4PBMBreastsShape05; 5PBMBreastsShape04; 6PBMBreastsShape03; 7PBMBreastsShape02; 8PBMBreastsShape01; 9PBMBreastsPerkSide; 10PBMBreastsHeavy; 11PBMBreastsGone; 12PBMBreastsDiameter; 13CTRLBreastsNatural; 14CTRLBreastsImplants; 15PBMBreastsSize; 16PBMBreastsSmall; 17PBMBreastsUnderCurve; 18GrowingBreasts; 19sfd_tg_breastsizer; 20Aging Breast Sag; 21PBMNipplesSize; 22sfd_tg_nippsize; 23PBMNipplesLarge; 24PBMNipplesDiameter; 25PBMNipplesDepth; 26PBMAreolaePerk; 27PBMAreolaeDiameter; 28PBMAreolaeDepth. - trueSexies.txt (8) : 1
Penis length; 2Penis size; 3Plums size; 4Plums high-low; 5Foreskin01; 6Foreskin02; 7Foreskin03; 8Foreskin04. Les lignes correctes ont la forme<morph>: <tag>[, <tag>](falseBodies.txt:1sfd_tg_tgbody05a: teen;falseFaces.txt:2Ailene: white, square). Fins de ligne et BOM : aucun BOM dans les 9 fichiers ; les lignes vides (falseSexies.txt:29,trueBodies.txt:21-22) ne produisent aucun avertissement : elles sont éliminées par CullEmpty si le séparateur de lignes est\r\n(modèle B), ce que confirment les comptes (§ 4).
3. Écarts au compte attendu de la fiche
- K1 : attendu « 570 en 1 rafale ? » → 570 lignes à 3 champs × 1 passage = 570, 1 rafale. Pas d'écart. La « cause 3 champs estimée » du GIUBER devient établie : 570 lignes ont exactement 3 champs (index 3 hors bornes, longueur 3).
- K2 : attendu 60 → 60 = 40 + 20, égalité exacte avec 12 + 28 et 12 + 8. La « nature des lignes incertaine » devient établie pour les 60 : noms de morph sans
': ', aucune ligne vide ni CR en cause. L'attribution_28/_29aux branches (incertaine dans le GIUBER) se tranche par les comptes et l'ordre :_29(40, premier) = branche fausse,CallFunction_1012/GetArrayItem_56;_28(20, ensuite) = branche vraie,CallFunction_1016/GetArrayItem_58(estimé fort, voir § 4). - Ce que la fiche ne prévoyait pas : (a) le 4e champ de
Clothes4.txtest facultatif dans les données (387 lignes sur 957 le portent) ; le défaut est la lecture sans test de la longueur, pas une ligne corrompue ; (b) de même, les 60 lignes MorphTags sont des morphs volontairement sans étiquette. - Écarts de méthode (à signaler selon
sk-protocol§ 7) : deux commandes shell de reconnaissance ont utiliséhead/grepen tube (ls ... | head -50,ls ... | grep -i) ; elles ne servent qu'à lister des dossiers, aucun chiffre du livrable n'en dépend (tous recomptés par Grep).git status --porcelainde la copie 5.8 montreM Source/LifePlay/LPStringCompat.cppetM Source/LifePlay/LPStringCompat.h(+5 lignes chacun : ajout deULPStringCompat::GetStringAtOrEmpty) : modification qui n'est pas la mienne (j'ai ouvert ces fichiers en lecture seule ; l'état initial de la session était propre), probablement une autre session ;ParseIntoArray(lignes 5-27) est inchangé. DépôtMOD:git status --porcelain= 0 ligne. Aucun fichier de données ou de projet modifié par cette fiche.
Correction de données proposée (non appliquée)
Règle valable pour chaque ligne listée, car le défaut est le même partout :
- K1 (570 lignes de
Clothes4.txt, liste § 2.1 etSP\k1_bad_Clothes4.tsv) : ajouter un 4e champ non vide: <jeton>en fin de ligne. Un 4e champ vide (:final) ne marche pas : CullEmpty supprime le champ vide final (LPStringCompat.cpp:15, 21), la ligne resterait à 3 champs. Aucun jeton neutre n'existe dans les données (20 jetons, tous porteurs de sens) : le choix du jeton inerte (il serait ajouté au tableau d'étiquettes du vêtement et lu ailleurs) est une décision de conception. Ligne 957 (dernière, sans fin de ligne) : ajouter le jeton sans casser l'absence de fin de ligne. - K2 (60 lignes, liste § 2.2) : ajouter
: <étiquette>en choisissant dans le vocabulaire existant (AllMorphTags.txt: white, asian, latin, arab, indian, black, feminine, teen, old, fantasy, round, oval, square, oblong ; autres valeurs des lignes correctes : ethnic, ...). Chaque ligne exige un choix de sens (que représente un morph de poids ou de taille sans étiquette ?) que je ne peux pas établir. - Avis de l'inventaire (estimé, décision à l'orchestrateur) : modifier 630 lignes de données du dépôt local
Content/Modules(non poussé, joueurs et mods ayant leurs propres fichiers au même format) est plus lourd et moins sûr que la garde côté Blueprint (Length > 3/Length >= 2, ou lecture parGetStringAtOrEmpty, déjà en cours de rédaction dans le jeu 5.8) ; les mods tiers au même format continueraient de déclencher les avertissements. C'est la question Q1 du GIUBER.
4. Établi / estimé / incertain
Établi (source) :
- Fichier lu par K1 =
Modules/Clothes4.txt(EG:28701) ; fichiers lus par K2 =Modules/MorphTags/<Filename>.txt(EG:28155-28158), branche selonStartsWith(Filename, 'true')(EG:28172-28177). CullEmpty est vrai pour les trois niveaux de découpe de chaque chaîne (EG:28151, 28187, 28218, 28708, 28747). - 570 lignes de
Clothes4.txtont exactement 3 champs (scriptk1.py, Grep regex, 570 / 387 / 957) ;LOG570 avertissementsindex 3 ... length 3, 1 rafale (LOG:1021-6150). - 60 lignes de 4 fichiers
MorphTagsn'ont pas de': '(scriptk2.py; Grep 28 + 8 + 12 + 12 = 60 ; numéros de ligne revérifiés en mode content surtrueBodies.txtetfalseBodies.txt) ;LOG60 avertissements, 1 exécution dePopulateAllMorphTags. - Aucun BOM, aucun CR ou LF isolé dans
Clothes4.txtni dans les 9 fichiersMorphTags;Clothes4.txtsans ligne vide ; la copie du build U8 essai est identique pourClothes4.txt(md5). - Bornes :
Attempted to access index N from array ... of length Lest l'effet deGetArrayItem(DIAG 0.6), pas d'un autre nœud.
Estimé (raisonnement) :
- Séparateur de lignes de
CallFunction_1032/3047=\r\n(modèle B), non lisible directement dans le dump (le texte du séparateur contient un saut de ligne et le dump coupe la ligne :EG:28150,28707finissent par'\r). Raison : le modèle B donne 20 + 40 = 60 ; le modèle A (\n, CR en fin de ligne conservé) donnerait 21 + 40 (la lignetrueBodies.txt:21serait un\rnon vide) = 61, contraire au journal. Pour K1, A et B donnent le même résultat (aucune ligne vide). _29= branche fausse (40),_28= branche vraie (20) : seule l'attribution cohérente avec les comptes par fichier et avec l'ordre dansLOG.- La liste de
MorphTagFiles= les 6 noms trouvés à l'offset 28280219 deGI.uasset: appuyé par l'égalité exacte des comptes (12 + 28, 12 + 8, 0 pour les deux fichiers Faces), non par la lecture de la propriété elle-même. Les trois autres fichiers du dossier (AllMorphTags, allClothingMorphs, trueTopSimplify) ne passent pas par ce chemin. populateClothes4=K2Node_CustomEvent_98: le nom d'événement n'est pas dans le dump (DIAG 0.7) ; rattachement par la pile du journal et par'/Game/Heavy/Clothes4/'etLines_PopClothes4.- Une seule exécution de
populateClothes4dans cette session : un seul bloc contigu de 570 ; la raison pour laquelle lesPerson BeginPlaysuivants ne la relancent pas n'est pas établie. - UE4 lisait un index hors bornes sans avertissement et renvoyait la valeur par défaut (chaîne vide) : raisonnement du DIAG, non rejoué ici ; il explique pourquoi les données « tolérantes » n'avaient jamais été signalées.
Incertain (essai qui trancherait) :
- Valeur réelle du séparateur de lignes : lecture du champ
DelimiterdeCallFunction_1032/3047dans l'éditeur (ou dump corrigé, voir Q2 du DIAG qui demande l'impression des noms d'événements) ; les comptes ci-dessus le contraignent déjà. - Valeur par défaut exacte de
MorphTagFiles: dump deGICDO (LPDumpCDOavecProps=MorphTagFiles), commandlet exclu par la fiche. - Mods ou sauvegardes : seuls les modules de base
Content\Modules\ont été lus ; aucunMods\ni autre dossier de modules (fiche : copie 5.8 uniquement). - Les 12 lignes de
Clothes4.txtavec espaces en fin (lignes 62, 193, 225, 295, 369, 437, 623, 711, 731, 746, 835, 855) portent des jetonsSports,ParUn,Asianavec espace final ; hors sujet des avertissements, mais le testArray_Contains 'sports'(EG:28783-28787) peut les manquer : à confirmer avant toute correction de données.
Constats
- Les 630 lignes (570 + 60) ne sont pas des erreurs de saisie : ce sont des lignes à champ final facultatif. Le défaut est la lecture sans test de longueur.
- Aucun fichier du dépôt
Content\Modulesn'a été modifié ; aucun commit ; aucun UE ni commandlet lancé. - Fichiers de travail (hors dépôt, volatils) :
SP\analyse.py,k1.py,k1b.py,k2.py,dumpbytes.py,uasset.py,uasset2.py,k1_bad_Clothes4.tsv(570 lignes),k2_bad_<fichier>.txt.