LifePlay-Revival/Docs/Migration/etat/ST/STG/STG-M1e-VAL.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

14 KiB

Fiche STG-M1e-VAL — Niveau N1 — Modèle prévu (agent lp-validator) | utilisé claude-sonnet-5-5 — Agent lp-validator — Skills sk-protocol, sk-recount, debug-verification, lp-validate

STG-M1e-VAL : validation statique de la mesure M1e (2026-10-14)

VAL statique : sans UE, sans compilation, rien écrit hors de ce livrable. Copie D:\Game\LifePlay-master 5.8, branche ue5.8. Moteur lu : D:\Game\Launcher\Engine\UE_5.8\Engine\Source\Runtime (5.8.3, lp-env). Instantané : D:\Game\LifePlay_Backup_5.5\STG-M1e\.

1. Fiches amont relues

Fiche Relue
STG-M1e-IMPL.md (toute la fiche, 74 lignes) oui
STG-M1e.diff (224 lignes, en entier) oui
manifest.csv de l'instantané STG-M1e oui (4 fichiers, MD5 avant concordants avec IMPL § 2)
STG-COMMUN6-DIAG.md non relu en entier : motif repris de IMPL § 1 et § 4 (la VAL porte sur le code, pas sur le diagnostic)

2. Points à confirmer des IMPL

L'IMPL n'a pas de section « Points à confirmer » (voir écart E1). Les sept contrôles de la fiche VAL en tiennent lieu.

Id Point Résultat
P1 MD5 actuels = IMPL § 5 ; Keyboard inchangé PASS
P2 Diff = IMPL § 3, rien d'autre PASS-STATIC
P3 Marche inchangée, MenuReason = ancien MenuOnScreen PASS-STATIC
P4 Témoin sans consommation, enregistré / retiré PASS-STATIC
P5 Compilabilité par lecture (en-têtes UE 5.8) PASS-STATIC, aucune erreur probable trouvée
P6 Fins de ligne, ASCII PASS
P7 Livrable de l'IMPL (en-tête complet, LF, pas de C:\Users) PASS partiel : LF et chemins conformes, en-tête et sections hors gabarit (E1)

3. Critères rejoués

P1 — MD5 (établi)

Commande : md5sum LPDirectControlSubsystem.cpp LPDirectControlSubsystem.h LPKeyboardSubsystem.cpp LPKeyboardSubsystem.h (dans Source/LifePlay)

ad60a24fb3e3075299c1f4ec5f087011 *LPDirectControlSubsystem.cpp
979ae0ada261655cbbe9aefd6969e833 *LPDirectControlSubsystem.h
5d60d3f8ffe721698820fe68e55f938c *LPKeyboardSubsystem.cpp
eed95e9860b26c5a7327ce4e3f90d8c8 *LPKeyboardSubsystem.h

Recoupé par Tools\FileCheck.ps1 : AD60A24F…5F087011, 979AE0AD…E969E833, 5D60D3F8…8E55F938C, EED95E98…C8D3, identiques à IMPL § 5 et § 2. Les copies de l'instantané donnent baaa3982583b70a56602cbfe95bf4fa4 (.cpp), 77ae7007c77403f05c6697771029cc8c (.h), 5d60d3f8… et eed95e98… (Keyboard) = IMPL § 2 et manifest.csv. diff -q instantané contre copie sur LPKeyboardSubsystem.cpp et .h : aucune sortie, code 0 (identiques).

P2 — diff contre l'instantané (établi pour la concordance, estimé pour l'absence d'autre changement)

Je régénère le diff moi-même (diff -u <instantané> <copie> | tail -n +3 | tr -d '\r' | md5sum) et le compare au fichier STG-M1e.diff (mêmes lignes, sans les deux lignes d'en-tête horodatées) :

CPP  bccf14a6ed29181e35a57aaa9f7f7d2a *-   (régénéré)   |  bccf14a6ed29181e35a57aaa9f7f7d2a *-   (STG-M1e.diff l. 3-201)
H    fa35a50f8e2b5c9ccccc2c23c649f9ab *-   (régénéré)   |  fa35a50f8e2b5c9ccccc2c23c649f9ab *-   (STG-M1e.diff l. 204-224)

Le fichier .diff livré est donc exactement le diff réel. Comptes : .cpp 111 lignes ajoutées, 8 retirées (grep -c '^+[^+]' et '^-[^-]'). Seuls deux fichiers changent par rapport à l'instantané ; le diff est lu en entier (§ 4). Les lignes du diff correspondent à IMPL § 3 : include, MenuReason, IsMoveKey / SlateMoveKeys / FMoveKeyWitness, Initialize / Deinitialize, appel dans Tick, WitnessMoveKeys, déclarations du .h. Un seul ajout non cité dans § 3 : le commentaire de ScenePlaying (l. 459) qui renomme MenuOnScreen en MenuReason (commentaire, sans effet).

P3 — comportement de la marche (établi par lecture)

  • Ordre des tests (.cpp l. 622-666), identique à l'ancien : (1) GI nul ; (2) ULPKeyboardSubsystem::IsMenuOpen() ; (3) boucle TObjectIterator<UUserWidget> avec les mêmes filtres (CDO, autre GameInstance, hors viewport, Collapsed / Hidden) et comparaison à MenuClasses ; (4) Slate non initialisé ; (5) widget focalisé « Editable ». Les lignes de contexte du diff (non modifiées) le montrent ; seules les lignes de retour changent.
  • Retours : false devient FString() aux étapes 1 et 4 et en fin de fonction ; true devient TEXT("clavier") (étape 2), ClassName (étape 3), "focus " + type (étape 5).
  • Vide ⇔ false : les trois retours non vides sont non vides par construction. ClassName égale un élément de MenuClasses (l. 54-58 : dix littéraux non vides) ; "clavier" et "focus "+… sont non vides. Toutes les sorties qui valaient false sont vides. Donc bMenuBlocks = !MenuWhy.IsEmpty() (l. 810) vaut exactement l'ancienne valeur, dans la même branche MenuDelay >= 0.25f (cadence inchangée).
  • Plus aucun appel à MenuOnScreen dans ce fichier : Grep MenuOnScreen dans LPDirectControlSubsystem.cpp = 0 résultat. Les lecteurs de bMenuBlocks (l. 825, 998) sont inchangés.
  • Hors du fichier : LPCameraModeSubsystem.cpp:120 a sa propre copie LPCameraModeLocal::MenuOnScreen (espace de noms nommé, non modifié) et LPDebugSubsystem.cpp:433 ne cite le nom que dans un commentaire. Aucun appel croisé.
  • Effets de bord ajoutés : WitnessMoveKeys ne modifie ni bMenuBlocks, ni l'entrée, ni le contrôleur ; il lit et journalise (UE_LOG Display). IsPressed, InputEnabled, IsMoveInputIgnored, IgnoreInput sont des lectures.

P4 — témoin FMoveKeyWitness (établi par lecture)

  • HandleKeyDownEvent et HandleKeyUpEvent : return false sur tous les chemins (.cpp l. 696-709 du diff) ; Tick est vide. Jamais d'évènement consommé.
  • Enregistrement : Initialize (l. 772-776), une fois, si FSlateApplication::IsInitialized() ; RegisterInputPreProcessor(MoveWitness) avec un TSharedPtr<IInputProcessor> (surcharge à un argument, sans ambiguïté).
  • Retrait : Deinitialize (l. 793-798) : UnregisterInputPreProcessor si valide et Slate initialisé, puis MoveWitness.Reset() et SlateMoveKeys().Reset(). Aucun retour anticipé dans Deinitialize avant ce bloc.
  • Pas de double enregistrement : Initialize n'est appelé qu'une fois par instance de sous-système, un seul témoin par instance (le membre MoveWitness). Fuite : le TSharedPtr est le seul propriétaire côté jeu, libéré au Reset. Cas Slate déjà détruit à Deinitialize : pas de désinscription (inutile), le Reset libère quand même le témoin.
  • Établi : le moteur inscrit les pré-processeurs dans une liste qu'il possède ; aucun test d'exécution (PIE, double Initialize) n'a été rejoué. Réserve : pas de preuve par l'exécution (estimé).
  • État statique SlateMoveKeys() partagé par toutes les instances (une seule GameInstance en jeu) ; remis à zéro au Deinitialize et à la perte d'activité de la fenêtre.

P5 — compilabilité par lecture, en-têtes UE 5.8 (établi pour chaque signature, compilation non rejouée)

Élément Moteur 5.8 Usage dans le code Verdict
IInputProcessor::Tick IInputProcessor.h:23 virtual void Tick(const float, FSlateApplication&, TSharedRef<ICursor>) = 0; override identique, corps vide conforme (seule pure virtuelle)
HandleKeyDownEvent / HandleKeyUpEvent IInputProcessor.h:26, 29 virtual bool …(FSlateApplication&, const FKeyEvent&) override identique conforme
RegisterInputPreProcessor SlateApplication.h:1544 bool …(TSharedPtr<IInputProcessor>) (non const) Get().RegisterInputPreProcessor(MoveWitness) conforme
UnregisterInputPreProcessor SlateApplication.h:1574 void …(TSharedPtr<IInputProcessor>) idem conforme
IsActive SlateApplication.h:1611 virtual bool IsActive() const override Get().IsActive() conforme
GetKeyboardFocusedWidget SlateApplication.h:1653 TSharedPtr<SWidget> … const affecté à const TSharedPtr<SWidget> conforme
APlayerController::InputEnabled PlayerController.h:2142 bool InputEnabled() const appelé sur const APlayerController* conforme
IsMoveInputIgnored Controller.h:368 virtual bool … const (hérité par le contrôleur) idem conforme
PlayerInput PlayerController.h:370 TObjectPtr<UPlayerInput> PlayerInput PC->PlayerInput->IsPressed(Key) conforme
UPlayerInput::IsPressed PlayerInput.h:745 bool IsPressed(FKey) const idem conforme
UGameViewportClient::IgnoreInput GameViewportClient.h:773 virtual bool IgnoreInput() override (non const) Viewport pointeur non const (GetGameViewportClient() const rend UGameViewportClient*, GameInstance.h:295) conforme (le commentaire du code le dit)
FKey::ToString InputCoreTypes.h:90 FString ToString() const *Key.ToString() conforme
UInputSettings::GetAxisMappings InputSettings.h:318 const TArray<FInputAxisKeyMapping>& … const boucle const FInputAxisKeyMapping& conforme
APlayerController::GetViewTarget PlayerController.h:1911 AActor* … const GetNameSafe(PC->GetViewTarget()) conforme

Includes présents (.cpp l. 22, 26-27, 31-33) : Engine/GameViewportClient.h, Framework/Application/IInputProcessor.h (ajouté), SlateApplication.h, GameFramework/InputSettings.h, PlayerController.h, PlayerInput.h. ForwardAxis / RightAxis (l. 50-51) et ScenePlaying (l. 461) sont déclarés avant leur usage, dans le même espace de noms anonyme (ouvert l. 48, fermé l. 766). LogLifePlay vient de LifePlay.h. TArray::IsEmpty, Last, AddUnique, Remove, Reset existent. Le .h déclare TSharedPtr<class IInputProcessor> avec déclaration avancée : valable, le suppresseur est capturé à la création du TSharedPtr dans le .cpp. Expression ternaire des Why : trois FString, type homogène ; PC ? *GetNameSafe(…) : TEXT("-") : deux const TCHAR*, temporaire vivant jusqu'à la fin de l'expression de UE_LOG. Collisions de noms (build unity) : Grep sur Source de IsMoveKey|SlateMoveKeys|FMoveKeyWitness|MenuReason|MoveWitness|MenuWhy|MoveLogDelay|WitnessMoveKeys : toutes les occurrences sont dans LPDirectControlSubsystem.cpp/.h. MenuOnScreen subsiste seulement dans LPCameraModeSubsystem.cpp (espace de noms LPCameraModeLocal) : sans collision. Aucun nom nouveau n'est partagé avec un autre fichier du module. Signalé, non bloquant : TSharedRef<ICursor> en paramètre dans le Tick du témoin repose sur ICursor déclaré par IInputProcessor.h / SlateApplication.h (inclus) ; estimé sans risque, seule la compilation tranchera.

P6 — fins de ligne et ASCII (établi)

Tools\FileCheck.ps1 -Path … : LPDirectControlSubsystem.cpp CRLF 1416, LF seul 0, CR seul 0 ; .h CRLF 88, LF 0, CR 0 ; Keyboard .cpp CRLF 958 / LF 0, .h CRLF 68 / LF 0 ; sans BOM ; alertes=0. git ls-files --eol : i/crlf w/crlf pour les deux fichiers modifiés. Non ASCII : grep -cP '[^\x00-\x7F]' donne 2 lignes dans le .cpp actuel et 2 dans le .cpp de l'instantané (l. 450 et l. 509, préexistantes), 0 dans le .h ; grep -nP '^\+.*[^\x00-\x7F]' STG-M1e.diff : 0 ligne. Aucun caractère non ASCII ajouté.

P7 — livrable de l'IMPL (établi)

FileCheck : STG-M1e-IMPL.md LF 74, CRLF 0 ; STG-M1e.diff LF 224, CRLF 0 (le diff, sans CR : cohérent avec la comparaison faite après tr -d '\r'). grep -c 'C:.Users' : 0. L. 1 : « Fiche STG-M1e-IMPL — Niveau N3 — Modèle prévu … | utilisé … » présente. Écarts de gabarit : voir E1.

4. Diff lu en entier

STG-M1e.diff lu en entier (224 lignes) : .cpp 6 blocs (include ; commentaire ScenePlaying ; MenuReason et témoin ; Initialize / Deinitialize ; Tick ; WitnessMoveKeys), .h 2 blocs (déclaration, membres). 111 lignes ajoutées et 8 retirées au .cpp. Régénéré indépendamment contre l'instantané (§ P2). LPKeyboardSubsystem : 0 différence. Remarques de lecture, sans écart de code : la ligne touche … vue par Slate utilise Key = SlateMoveKeys().Last() seulement ; MenuWhy est rafraîchi toutes les 0,25 s (les lignes de transition peuvent arriver jusqu'à 0,25 s après le menu, normal) ; le commentaire de LPDebugSubsystem.cpp:433 cite encore MenuOnScreen (commentaire, hors périmètre, fichier non touché par M1e).

5. Verdict

PASS-STATIC. Points 1 à 6 conformes avec preuve ; la compilation n'a pas été rejouée (consigne du GO), le comportement à l'exécution non plus. Point 7 conforme sur LF et chemins ; écart documentaire E1 sur le gabarit de l'IMPL (n'affecte pas le code).

Écarts :

  • E1 (documentaire, mineur) : STG-M1e-IMPL.md ne suit pas le gabarit IMPL de lp-doc/gabarits.md : pas de seconde ligne d'en-tête « Agent … Skills … » (sk-protocol § 4), pas de ligne # STG-M1e-IMPL : titre (date), sections propres (1 à 7) au lieu de « 1. Fichiers modifiés, 2. Écarts à la SPEC, 3. Instantané, 4. Ce qui n'a pas été fait, 5. Points à confirmer en VAL, 6. Fichiers à commiter » ; ni « Points à confirmer » ni ligne Tours : n / budget (Grep Tours : 0). Le contenu de l'écart au DIAG (§ 1) et de la fiche existe mais hors des intitulés. À corriger par l'auteur ou à accepter par l'orchestrateur.
  • N1 (information) : un commentaire modifié (ScenePlaying, .cpp l. 459) n'est pas listé dans IMPL § 3.

Non rejoué : compilation (consigne), LPTestStringCompat, exécution en éditeur ou en jeu, comportement réel du témoin (touche vue par Slate, absence de consommation constatée à l'exécution, Deinitialize en PIE).

6. Points à confirmer par l'utilisateur

  • Accepter ou faire reprendre le gabarit de l'IMPL (E1).
  • Compilation au prochain build commun : le résultat tranche P5 (la lecture ne la remplace pas).
  • À l'essai : relever les lignes M1e : selon le tableau de IMPL § 4 ; vérifier au journal que le témoin ne perturbe pas la marche (comparaison avec un essai sans M1e, non faite ici).

Fichiers à commiter : Docs/Migration/etat/ST/STG/STG-M1e-VAL.md (A). Fichiers modifiés par cette VAL : ce seul livrable.

Tours : 9 / 30