18 KiB
Fiche U8-T5c — Niveau N1 — Modèle prévu (modèle de l'agent lp-validator) | utilisé claude-sonnet-5-5 — Agent lp-validator — Skills sk-protocol, sk-recount, debug-verification, lp-validate
U8-T5c-VAL : parcours U6 sur l'archive Development U8, comparaison au journal U6, verdict STM-T4c (2026-10-09)
Lecture seule : aucun fichier de jeu, d'archive, de copie d'essai, de journal ou de dépôt n'a été modifié ; ni jeu ni éditeur lancés ; aucun commit. Seuls fichiers écrits : ce livrable et 6 scripts de lecture dans le scratchpad (§ 3, fin). git status --short (copie 5.8) avant et après : les 3 mêmes fichiers Docs/Migration/ déjà modifiés à l'ouverture (27, Journal_Modifications, README), rien d'autre.
Journaux (tailles relues par ls -l) :
- Cible :
D:\Game\LifePlay_Build_5.8_Development_U8_essai\Windows\LifePlay\Saved\Logs\LifePlay.log, 3 281 562 octets, 52 550 lignes, 16:43:02 → 16:46:02 UTC (= 18:43 → 18:46 locale), moteur5.8.3-58210709. Le journal…backup-2026.10.09-16.30.43.logn'a pas été utilisé. - Référence :
D:\Game\LifePlay-master 5.5\Docs\Migration\etat\U58\U6\LifePlay_58_session2.log, 1 656 827 octets, 17 317 lignes, même moteur 5.8.3.
1. Fiches amont relues
U8-TACHES.md(ligne U8-T5c et notes de l'orchestrateur sur T5c, T5b, T3),U8-T1-CART.md§ 1 et tableau ligne 1 (seul changement de contenu cuit depuis2026.10.2.0:Person.uasset, commit6cb8e81),U8-T0-INV.md:88(report R8, STM-T4c).U6-T3-AB.md§ 2 et § 4 (relevé U6 ; la regex deLogStats.ps1citée « 21-22 » est en fait àLogStats.ps1:69-70, voir § Constats G.2).Docs/Migration/29_Projet_Stabilisation_V2.md:251-254(STM-T4c, CHG-263),git show --stat 6cb8e81(Content/BPs/Person.uasset20 672 239 → 20 703 212 octets + 2 docs).- Aucune IMPL dans ce lot au sens du gabarit (le correctif est une écriture par MCP, STM-T4c, hors lot U8) ; le seul point amont est STM-T4c.
- Contrôle de la copie d'essai (lp-validate § 5) :
LifePlay.exeidentique à l'archive…_Development_U8(MD59c732ce88ff905b8b62351737e0dddf5des deux, 330 686 464 octets) ;LifePlay-Windows.ucasidentique (MD54d78d9b6995a955e1f48aa04ab3197d4) ;Content/Saves/Default/Characters/Player.lpcharacterMD55fc99d7f7c644f8beba51777cc81852e(= 5FC99D7F de U6). Établi.
2. Points à confirmer des IMPL amont
| Point | Résultat | Preuve |
|---|---|---|
| STM-T4c (doc 29 § STM) : « reste à prouver en jeu : ContactMenu 63 → 0 » | PASS pour le critère de la fiche (réserve d'exposition, § 6 case 1) | Cible : 0 ligne ContactMenu sur 52 550 (LogStats -Pattern), SPAWN 15 > 0, grep UpdateDailyPose : 0 ligne. Référence : 65 lignes ContactMenu sur 17 317 = 63 événements (tous Function Person_C:UpdateDailyPose, 54 via ExecuteUbergraph_Person, 9 via updateHeelHeight) + 2 lignes du résumé de fin de session du jeu (LogLifePlay: Display: 42 / 21 [...] ContactMenu, lignes 17265 et 17272 ; 42 + 21 = 63). Les 63 sont donc retrouvés à l'identique. Recompté par trois méthodes : LogStats -Pattern, outil Grep (65), script cm.ps1 (65 dont 63 avec UpdateDailyPose dans les 3 lignes suivantes). |
Hitchs MapMarkers_C à compter des deux côtés |
PASS (comptés) | Référence 4 hitchs, cible 2 (§ Constats C). |
Archive Development = cuisson complète contenant 6cb8e81 |
reporté (non rejoué) | Établi par U8-T1-CART.md:10 et U8-TACHES.md T3 (cuisson 18:05, après le commit 16:29:02 git log -1 6cb8e81) ; je n'ai pas relu le contenu cuit de Person. Le 0 observé en est la seule preuve indirecte. |
3. Critères rejoués
Commandes (pwsh 7, depuis D:\Game\LifePlay-master 5.8). Écart à la fiche : -File avec une liste séparée par virgule passe un seul argument (Exception … -Compare attend exactement deux journaux), donc lancé par pwsh -NoProfile -Command "& './Tools/LogStats.ps1' -Compare 'réf','cible'" (même appel pour -Log … -Pattern 'ContactMenu','MapMarkers_C','Gamethread hitch','Error:' -Max 20 -Context 0).
| Critère de la fiche | Attendu | Recompté | Verdict |
|---|---|---|---|
| Cible SPAWN > 0 | > 0 | 15 (index SPAWN, 5 acteurs distincts : Person_C_2147481947/923/899/875/851) ; grep -c : 15 |
OK |
| ContactMenu cible | 0 | 0 ligne (LogStats -Pattern, grep) |
OK |
| ContactMenu référence | 63 événements | 65 lignes = 63 + 2 lignes de résumé | OK |
Hitchs MapMarkers_C des deux côtés |
comptés | réf 4 hitchs (3,45 / 6,07 / 3,14 / 3,43 ms), cible 2 (1,77 / 11,66 ms) | OK |
| Erreur nouvelle côté U8 | listée | aucune (voir ci-dessous) | OK |
Propriété Accessed None nouvelle côté U8 |
listée | 2 (une occurrence chacune, scène de couple) | OK |
| Orchestrateur : cible SPAWN 15, ContactMenu 0, Accessed None 259, MapMarkers_C 3 ; réf 65 / 6 | à recompter | SPAWN 15 confirmé ; ContactMenu 0 et 65 confirmés ; MapMarkers_C 3 et 6 confirmés ; 259 = grep -c 'Accessed None' (toutes formes), alors que le compteur LogStats donne 223 (avec property) : même journal, deux définitions (voir § Constats G.1) |
confirmé / précisé |
Erreurs (: Error: LogStats : réf 5, cible 3 ; Error: motif large : réf 6, cible 4) :
- cible :
LogPlayerController: Error: InputMode:UIOnly - Attempting to focus Non-Focusable widget×3 (lignes 1015, 51359, 52083) +Error: r.MorphTarget.Mode is read only!×1 (ligne 7378) ; - référence : même
Non-Focusable×5 +r.MorphTarget.Mode×1. Aucune signature d'erreur nouvelle ; Fatal / assertion / ensure : 0 des deux côtés (grep -c,LogStatsFatal 0 / 0) ;LogPluginManager: Error: 0 des deux côtés (grep -c).
Scripts de lecture (non conservés au projet, %USERPROFILE%\AppData\Local\Temp\claude\D--Game-LifePlay-master-5-8\24ad9ebb-dd23-4283-9e81-153738063a46\scratchpad\) : props.ps1 (propriétés), idx.ps1 (index hors bornes), sig.ps1 (signatures d'avertissements, hors résumé de fin), burst.ps1 (rafale), stk.ps1 (piles ContactMenu), cm.ps1. À ranger dans Saved/U8/ ou Tools/ si l'orchestrateur les veut.
4. Diff lu en entier
Sans objet : lot de mesure en lecture seule, aucun fichier modifié par ce rôle ni attendu. git status --short inchangé (3 docs, déjà modifiés). Le diff du correctif amont (6cb8e81) est un binaire .uasset : non lisible, relu seulement par git show --stat (§ 1). Fins de ligne, .uproject, build, LPTestStringCompat : sans objet (aucun code ni build dans cette fiche).
5. Verdict
PASS pour le critère d'acceptation de la fiche U8-T5c : ContactMenu 63 événements (65 lignes) → 0 ligne avec 15 SPAWN, hitchs comptés (4 → 2), aucune erreur nouvelle, 2 propriétés Accessed None nouvelles listées. STM-T4c : PASS avec la réserve d'exposition du § 6 case 1 (preuve par absence, non un appel observé). Un point nouveau non expliqué hors périmètre est à décider par l'orchestrateur (§ 6 case 2).
6. Points à confirmer par l'utilisateur
- 1. Exposition du correctif :
UpdateDailyPosene journalise rien quand il réussit, donc le « 0 » est une preuve par absence. Indices d'exposition côté cible (estimé) : 15 SPAWN, 5 acteurs,PlayIdle/standIdleexécutés (42NeardansstandIdle),ShowNpcsHere,OnClickActionButton22 lignes de pile,ContinueScene49 lignes de pile (hors résumé). En revanche les chemins qui produisaient au moins 37 des 63 événements de la référence (PlayFntAnim20,MoveToFnt9,Dress8 ;updateHeelHeightest la feuille de 9 autres, possiblement les mêmes) n'apparaissent pas côté cible (0 ligne) ; leur absence dans les piles s'explique par le correctif lui-même (ils n'étaient visibles qu'à cause de l'avertissement), donc non concluante. Essai qui trancherait : un parcours avec fontaines / habillage de PNJ, ou un journal de la même archive avec le correctif retiré (cycle de non-régression dedebug-verification, non fait ici). - 2. Rafale nouvelle côté U8, hors périmètre de la fiche, non expliquée :
Attempted to access index 0 from array Floats_3_… of length 0×2 591 (hors résumé) en cible contre 18 en référence ; presque tous dansgetBeautyValue(2 505, +getRandomAge56,getRandomEthnicity30), pileGeneratePerson > RandomizeAll > RandomizeFace > pickAppropriateFaces > findAttractiveMorphs > getBeautyValue. Concentrés en 7 s (16:43:38 à 16:43:45 : 167 + 1 664 + 571 + 177 ; puis 12 à 16:44:08) autour des 8 premiers SPAWN (lignes 8071 → 48 674, soit environ 40 600 lignes de journal). Le tableauFloats_3_…est vide aussi en référence (18 occurrencesof length 0), donc l'anomalie de fond existe déjà ; c'est le nombre d'itérations qui explose (estimé : boucle de reprise depickAppropriateFacessans fin utile tant que la valeur de beauté est lue à vide). Cause non établie ; non attribuable àPerson.uasset(autre fonction). Reste à décider : DIAG (rejouer le parcours deux fois pour voir si la rafale est aléatoire) ou report. - 3. Le parcours n'est pas identique à U6 (estimé) : la cible contient une scène de couple (9 lignes
Show coupledont « ancien chemin » ×1 et « branche (PlayerCharacter + Person_C_2147481851) » ×1 ; 3Script Msg called by: SexInterface_C) absente de la référence, alors que la référence passe parCity.LoadCity(14 lignes de pile) /CloseCityMenu(13) et la cible non (0 / 0). Les rapports par personnage (§ Constats B) sont donc indicatifs, 18 contre 15 SPAWN.
Constats
A. LogStats.ps1 -Compare (A = référence U6 session 2, B = cible U8), sortie brute
Mesure A B
Lignes 17317 52550
Personnages 18 15
ActeursDistincts 6 5
AccessedNone 364 223
AccessedNoneMaillage 1 0
NoneMaillageParPerso 0,06 0,00
NoSkeletalMesh 2723 871
IndexHorsBornes 734 3298
LoadTxtOK 0 0
LoadTxtEchec 2 1
LogClassError 0 0
FailedToLoad 0 0
Fatal 0 0
Erreurs 5 3
Avertissements 5015 8056
LogLifePlay 124 157
LogLPAnimMeasure 0 0
TraceModding 16 14
Fichiers enumeres (GetAllFilesFromFolder) qui different : aucun (0 enumerations identiques)
Remarque : « 0 énumérations identiques » signifie qu'aucune énumération n'a été extraite (grep -c GetAllFilesFromFolder : réf 1 ligne hors motif LogStats, cible 0), pas une égalité prouvée.
LoadTxtEchec : réf 2 (Modules/ModLauncher.config, Saves/_session/Characters/OldPlayer.lpcharacter), cible 1 (ModLauncher.config) ; l'OldPlayer n'est pas lu avant la fin de la cible (estimé).
Compteurs bruts et recomptés par une autre méthode : Accessed None toutes formes (grep -c) cible 259, réf 397 ; avec property (LogStats) cible 223, réf 364 ; ces comptes incluent dans chaque journal des lignes du résumé de fin de session du jeu (LogLifePlay: Display:) : 3 en cible, 7 en référence (donc 220 / 357 événements réels).
B. Rapportés au nombre de personnages (SPAWN : réf 18, cible 15)
| Famille | Réf | Réf / perso | Cible | Cible / perso |
|---|---|---|---|---|
| Accessed None (LogStats) | 364 | 20,22 | 223 | 14,87 |
| Accessed None hors ContactMenu (364 − 65) | 299 | 16,61 | 223 | 14,87 |
| NoSkeletalMesh | 2 723 | 151,28 | 871 | 58,07 |
| Index hors bornes (LogStats) | 734 | 40,78 | 3 298 | 219,87 |
Index hors bornes hors résumé et hors Floats_3 (idx.ps1) |
713 | 39,61 | 702 | 46,80 |
| Avertissements | 5 015 | 278,61 | 8 056 | 537,07 |
Le surplus d'« index hors bornes » et d'avertissements en cible est la rafale Floats_3 (§ 6 case 2 : 2 573 événements en plus, à 2 lignes Warning chacun — message et « Script call stack » — soit environ +5 150 lignes ; la différence nette des avertissements est +3 041 (8 056 − 5 015) après −1 852 lignes NoSkeletalMesh et −130 ContactMenu, le reste étant des écarts de parcours). Hors cette rafale, les index hors bornes sont équivalents (713 / 702). NoSkeletalMesh baisse (−68 % brut, −62 % par personnage) : estimé = parcours (GetSocketInfoByName(Head) 978 → 196), à ne pas lire comme un effet du correctif.
C. Hitchs MapMarkers_C (Gamethread hitch : réf 4, cible 2 ; lignes MapMarkers_C : réf 6, cible 3)
| Référence (journal U6) | Cible (U8) | |
|---|---|---|
Hitchs …LPFocusWidgetComponent overwrite took |
3,45 ms (l. 7736) ; 6,07 ms (l. 8321) ; 3,14 ms (l. 9687) ; 3,43 ms (l. 14480) | 1,77 ms (l. 7972) ; 11,66 ms (l. 51241) |
| Total / maximum | 16,09 ms / 6,07 ms | 13,43 ms / 11,66 ms |
Script Msg … 'WidgetComponents' of length 0 in MapMarkers_C |
2 (l. 7451, 8172) | 1 (l. 7380) |
Autres hitchs Gamethread |
0 | 0 |
Le nombre de hitchs ne baisse pas de façon significative (4 contre 2 sur ~3 min chacun, un seul parcours) ; le plus long hitch de la cible (11,66 ms) est presque le double du plus long de la référence : à surveiller, pas un défaut établi (une seule instance MapMarkers_C_2147481658).
D. Accessed None par propriété (texte après property), 20 propriétés ; sommes 364 et 223 vérifiées
| Propriété | Réf | Cible | Écart | Fonction dominante |
|---|---|---|---|---|
| CallFunc_Array_Get_Item | 101 | 79 | −22 | GI_C:clearVariable (94 → 72), MainMenu:Get_SpinBox_0_Value_0 (6 / 6) |
| Near | 31 | 43 | +12 | Person_C:standIdle (30 → 42) |
| currentMatchRace | 35 | 31 | −4 | GI_C:determinePersonVars |
| ContactMenu | 65 | 0 | −65 | Person_C:UpdateDailyPose (63) + 2 lignes de résumé |
| Interacting | 29 | 9 | −20 | GI_C:ExecuteUbergraph_GI |
| OccupyingFnt | 17 | 10 | −7 | Person_C:ExecuteUbergraph_Person |
| CurrentCityExpansion | 16 | 9 | −7 | StreetMap_Static:SearchByAmenitySafe (14 → 9) |
| TintUI | 18 | 5 | −13 | GI_C:ExecuteUbergraph_GI |
| HeadtrackStatic | 10 | 11 | +1 | Person_C:ExecuteUbergraph_Person |
| GI | 10 | 8 | −2 | MainMenu 8 / 8 ; CityMenu 1 → 0 ; CharGen 1 → 0 |
| Companion | 8 | 4 | −4 | GI_C:clearScenePersons |
| BGA | 6 | 5 | −1 | StreetMap_Static:ExecuteUbergraph_StreetMap_Static |
| CallFunc_K2_GetRootComponent_ReturnValue_1 | 6 | 1 | −5 | GI_C:ExecuteUbergraph_GI |
| HeadtrackTarget | 2 | 3 | +1 | Person_C:ExecuteUbergraph_Person |
| CallFunc_K2_GetRootComponent_ReturnValue_2 | 5 | 0 | −5 | GI_C:ExecuteUbergraph_GI |
| Person | 2 | 2 | 0 | GI_C:ReturnStatIfNeeded |
| CallFunc_Array_Get_Item_53 | 2 | 1 | −1 | GI_C:ExecuteUbergraph_GI |
| CallFunc_GetSkeletalMesh_ReturnValue | 1 | 0 | −1 | CharGen:PopulateGenitalSlidersDaz |
| CallFunc_getFirstDick_Person_1 | 0 | 1 | +1 | PC_C:ExecuteUbergraph_PC |
| Actor | 0 | 1 | +1 | GI_C:isCreatureType |
Somme : 364 / 223.
E. Nouveau côté U8 (absent de la référence)
- Propriétés
Accessed None:CallFunc_getFirstDick_Person_1×1 (PC_C:ExecuteUbergraph_PC) etActor×1 (GI_C:isCreatureType), toutes deux liées à la scène de couple (estimé) ; bénignes en apparence, à classer par l'orchestrateur. - Signatures d'avertissements nouvelles (diff de signatures, hors résumé,
sig.ps1) :Attempted to access index # from array 'Texture2dArray_3_…' of length 0 in Te2dArray×6 ;… array 'SexPersons' … GI_C×3 ;Script Msg called by: SexInterface_C×3 ; 9 lignesLogLifePlay: Warning: Show couple : …(boîte de pose ×6, branche ×1, Pawn chambre ×1, « ancien chemin » ×1). La ligne « ancien chemin » (l. 51369) est un repli : à confirmer par l'auteur de R1 que ce n'est pas le chemin attendu. - Rafale
Floats_3(§ 6 case 2) : 2 591 contre 18. - Erreurs : aucune signature nouvelle.
F. Disparu côté U8 (présent en référence, absent en cible)
ContactMenu: 65 lignes (objet du correctif).CallFunc_K2_GetRootComponent_ReturnValue_2×5,CallFunc_GetSkeletalMesh_ReturnValue×1,Accessed None … GI in CityMenu / CharGen×2 : liés à des chemins non joués (ville, création de personnage), estimé.Attempted to access AudioComponent_… via property BGA, but … is not valid×4 ;Divide by zero: Divide_Vector2DVector2D×1 ;LoadTxt ECHEC … OldPlayer.lpcharacter×1 (chemin non joué, estimé).
G. Écarts à la fiche et pièges
Accessed None: le « 259 » de l'orchestrateur et le « 223 » deLogStatssont deux définitions du même journal (voir § 3). À dire dans la clôture pour éviter qu'un 259 soit comparé à un 364 (définitionLogStats). Comparaison cohérente : 223 contre 364, ou 259 contre 397.- La fiche cite
Tools\LogStats.ps1:21-22pour la regex : elle est en réalité àLogStats.ps1:69-70(les lignes 21-22 sont deux exemples d'appel). Citation de ligne à corriger dans le registre. - Piège nouveau :
LogStats.ps1 -Compare 'a','b'lancé parpwsh -Fileéchoue (liste séparée par virgule reçue comme un seul argument) ; utiliserpwsh -Command "& ./Tools/LogStats.ps1 -Compare 'a','b'". À ajouter aux pièges delp-validate§ 5 si l'orchestrateur le retient. - Le résumé de fin de session du jeu (
LogLifePlay: Display: <n> [LogScript Warning] …) est compté parLogStatscomme des lignes ordinaires (propriétés, index hors bornes) ; surcompte de 3 à 7 lignes surAccessedNone. Sans conséquence ici, à connaître. - Non rejoué : relecture du contenu cuit de
Person.uasset; test sans le correctif (cycle de non-régression) ; deuxième parcours de la cible (variabilité aléatoire de la rafale). Un parcours, un journal : « équivalent » reste estimé, comme en U6. Outil Edit absent de cet environnement : le livrable a été réécrit en entier par Write après une relecture (pas de script).