LifePlay-Revival/Docs/Migration/etat/ST/STE/STE-ORG5-V2-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

23 KiB
Raw Blame History

Fiche STE-ORG5-V2 — Niveau N2 — Modèle prévu (modèle de l'agent lp-validator) | utilisé claude-sonnet-5-5 — Agent lp-validator — Skills lp-validate, sk-recount, sk-protocol (debug-verification préchargé)

STE-ORG5-V2-VAL : VAL statique, sans compilation, de l'affichage des récompenses ORG5 dans EquipMenu (I2a) (2026-10-14)

Périmètre : lecture seule, sans compilation, éditeur, MCP, commandlet ni jeu. Seul fichier écrit : ce livrable. Branche ue5.8, HEAD 0745917. Aucun refus du crochet. Tout verdict de compilation reste « probable ». Les MD5 sont relevés au début et à la fin de la VAL : identiques (voir 3, C0).

1. Fiches amont relues

  • Fiche fiches\STE-ORG5-V2.md (lue en entier) ; livrable IMPL STE-ORG5-I2a-IMPL.md (lu en entier : § 1.2 gardes, § 1.3 appels moteur, § 2 écarts E1-E11, § 3 instantané, § 4, § 5 points à vérifier) ; SPEC STE-ORG5-I2-SPEC.md (lue en entier, dont § 2.2, § 7 et « Décisions de l'utilisateur » Q-I2-1 à 4) ; VAL d'I1 STE-ORG5-V1-VAL.md (lue en entier : C2 à C10, D1, D2). La fiche fiches\STE-ORG5-I2a.md n'a pas été relue : la fiche V2 et l'IMPL en reprennent les consignes.
  • Code lu en entier : Source\LifePlay\LPBonusRewardSubsystem.h (165 lignes) et .cpp (1028 lignes).
  • Moteur 5.8 relu (D:\Game\Launcher\Engine\UE_5.8\Engine\Source\Runtime) : CoreUObject\Public\UObject\UObjectGlobals.h:2059-2062 ; UMG\Public\Components\TextBlock.h:103,114,148,156 ; Widget.h:264,769,776 ; Blueprint\WidgetTree.h:104-122 ; Blueprint\UserWidget.h:1426,1524 ; PanelWidget.h:28,36,59,122 ; VerticalBox.h:30 ; VerticalBoxSlot.h:53,58,63 ; CanvasPanelSlot.h:112,116,132,148 ; Slate\Public\Widgets\Layout\Anchors.h:78 ; SlateCore\Public\Styling\CoreStyle.h:51 ; UnrealType.h:7815 (inclut UObject/StrProperty.h). Précédent du dépôt : LPColorGradeSubsystem.h:53 (TWeakObjectPtr<UTextBlock> sur déclaration avancée :20).

2. Points à confirmer des IMPL (IMPL § 5)

Id Point Verdict Preuve / raison
V5-2 compilation 5.8 sans erreur ni avertissement nouveau reporté (BUILD COMMUN-8) ; lecture : probable Voir 3, C7
C-a TWeakObjectPtr<UTextBlock> dans FLPBonusRewardLine sur déclaration avancée PASS-STATIC (probable) .h:52-55 déclarations avancées, .h:86-90 ; même forme que LPColorGradeSubsystem.h:20,53 déjà compilé ; TWeakObjectPtr ne demande le type complet qu'à Get() / affectation, faits dans le .cpp qui inclut Components/TextBlock.h
C-b FindObjectFast<UObject>(Tree, BoxName) à deux arguments PASS-STATIC (probable) UObjectGlobals.h:2058-2062 : FindObjectFast<T>(UObject* Outer, FName Name, EFindObjectFlags = None, EObjectFlags = RF_NoFlags) ; Tree (UWidgetTree*) se convertit en UObject* ; appel .cpp:749
C-c ConstructWidget<UTextBlock>(UTextBlock::StaticClass()) et <UVerticalBox>(…, BoxName), [[nodiscard]] PASS-STATIC (probable) WidgetTree.h:105-118 : ConstructWidget(TSubclassOf<WidgetT> = StaticClass(), FName = NAME_None), NewObject<WidgetT>(this, WidgetClass, WidgetName, RF_Transactional) ; résultat utilisé aux .cpp:621 et :759 ; UClass* se convertit en TSubclassOf
C-d GetPropertyValue(const void*) sur FStrProperty, FNameProperty, FTextProperty (.cpp:227-235) PASS-STATIC (probable) UnrealType.h (via TPropertyTypeFundamentals, statique), UObject/TextProperty.h inclus .cpp:19, StrProperty.h inclus par UnrealType.h:7815 ; Item est un const void* ; .ToString() sur FName et FText
C-e Equip->Slot.Get(), Cursor->WidgetTree.Get(), FCoreStyle::GetDefaultFontStyle("Regular", float) PASS-STATIC (probable) Widget.h:264 TObjectPtr<UPanelSlot> Slot (Get() existe) ; UserWidget.h:1524 TObjectPtr<UWidgetTree> WidgetTree ; CoreStyle.h:51 GetDefaultFontStyle(const FName, const float, const FFontOutlineSettings& = …), "Regular" se convertit en FName
C-f RemoveLine et RewardFont dans l'espace de noms nommé LPBonusReward, pas de C2374 PASS-STATIC (probable) Grep FLPBonusRewardLine|namespace LPBonusReward|ULPBonusRewardSubsystem sur Source : 33 occurrences, dans les deux fichiers seulement ; chaque fonction définie une fois
V5-3 0 AddToViewport, AddViewportWidgetContent, CreateWidget, UButton dans le .cpp PASS Grep du motif exact de la SPEC sur le .cpp : No matches found ; GetWidgetFromName (.cpp:57,674), EquipMenu (:37) et LPBonusRewardBox (:39) présents (l'IMPL cite un motif combiné qui sortait ces lignes ; le motif de la SPEC ne sort rien)
V5-4 création des widgets seulement dans ShowAppliedReward / EnsureRewardBox PASS Grep NewObject|ConstructWidget : ConstructWidget aux .cpp:621 (dans ShowAppliedReward) et :759 (dans EnsureRewardBox, seul appel :606) ; ShowAppliedReward seul appel :576 (dans OnOrgasm, donc FirePending) ; Poll n'appelle que ClearRewardDisplay (:429, :440), Initialize rien
V5-5 affichage après ModifyStat réussi et après le retour bDisabled PASS bDisabled : .cpp:543-547 retour avant Pick ; ModifyStat :567-570 (retour si faux) ; journal :571 ; ShowAppliedReward :576 ; format Bonus : %s %s %+.1f (:627) = format du journal (:571, %+.1f)
V5-6 GI.Cursor → GetWidgetFromName("EquipMenu") → Cast<UPanelWidget> ; police 16, contour (2, noir 0,8), marge (10, 5, 10, 0) ; 500 seulement si inférieur PASS-STATIC .cpp:647-668 (ReadObject + Cast<UUserWidget>), :674-675 ; police :55-62 (taille :59, contour :60, FFontOutlineSettings(2, FLinearColor(0,0,0,0.8))) ; marge :633 ; hauteur :713-717 (Size.Y < 500 seulement)
V6-1 à V6-8, V6-5, V6-7 rendu, journaux, remplacement, fin de scène, bDisabled, 0 plantage reporté (essai en jeu V6 du build COMMUN-8) Hors périmètre d'une VAL statique ; lecture du code : voir 3, C3 à C5
V6-2 journal affichage dans EquipMenu (classe VerticalBox, 4 enfants) puis hauteur d'EquipMenu portee de 350 a 500 reporté (V6) ; code conforme .cpp:794-799 (une fois par session, compte pris après AddChild : 3 enfants + la case) ; :717 à chaque agrandissement
Mise en page ScrollBox_3 (Fill) partage la place avec la case (Fill), même vide reporté (V6) Voir D2
Pause le délai de 20 s court en temps réel PASS-STATIC (constaté dans le code) FPlatformTime::Seconds (.cpp:638, :811) : insensible à la pause du jeu, annoncé IMPL 1.4

3. Critères rejoués (contrôle → preuve → verdict)

# Contrôle Preuve Verdict
C0 Périmètre et empreintes git -C 'D:/Game/LifePlay-master 5.8' status --porcelain -- Content Source Config → 18 lignes (wc -l : 18) = 5 M Content (GI, PC, Person, Room, TopRight) + 7 M Source (LPDebug* ×2, LPDirectControl* ×2, LPOutdoorRoom* ×2, LifePlay.cpp) + 6 ?? (LPBonusRewardSubsystem.cpp/.h, LPCameraModeSubsystem.cpp/.h, LPSaveRelaunch.cpp/.h) ; les deux fichiers du lot toujours ??, rien d'autre, aucune ligne Config, LifePlay.Build.cs absent de la sortie (inchangé), UMG à Build.cs:38. md5sum au début et à la fin : .h 87177c7a53fb5b5cc946e904060a3aaa, .cpp 16147626d2fa8a11dac8747cdbe12e9a = valeurs de la fiche et de l'IMPL ; horodatages .h 09:33:17, .cpp 09:35:21 (2026-10-14, avant la fiche V2) PASS
C1 Décisions Q-I2-1 à 4 Q-I2-1 lignes seules : un UTextBlock par ligne (.cpp:621-635), blanc FLinearColor::White (:629), police 16 contour 2 noir 0,8 (:55-62), HAlign_Left, marge (10,5,10,0), ni en-tête ni bouton (Grep UButton : 0). Q-I2-2 minuterie 20 s par ligne : ExpireAt = Seconds() + 20.0 (:638, constante :31), relue à chaque tick de 0,1 s (:413, :803-820), retrait par RemoveFromParent (:42-49). Q-I2-3 500 si inférieur : :713-717 (Size.Y strictement inférieur à 500, SetSize(X, 500)). Q-I2-4 bDisabled coupe tout : retour :543-547 avant Pick, ModifyStat et ShowAppliedReward PASS-STATIC
C2 Écarts E1-E11 E1 voulu (Q-I2-2). E2 ConstructWidget au lieu de NewObject : même NewObject à l'intérieur (WidgetTree.h:117), outer = arbre de Cursor, justifié. E3 recherche élargie de la case : exigée par la garde 2, justifié. E4 retrait des lignes suivies au lieu de ClearChildren à chaque affichage : même effet visible (MaxRewardLines = 1, .cpp:613-617), justifié. E5 hauteur seulement hors taille automatique / étirement vertical (:705) : prudence correcte (sinon GetSize().Y n'est pas une hauteur), justifié. E6 bInScene (:584-589) : cas non prévu, justifié. E7 Deinitialize ne retire pas les widgets : sûreté en fermeture, justifié. E8 sept clés d'avertissement : relues (GI.Cursor :650, GI.Cursor.Value :660, Cursor.EquipMenu :678, EquipMenu.Slot :698, EquipMenu.Slot.Layout :707, LPBonusRewardBox.Type :764, EquipMenu.AddChild :777) = 7. E9 police de repli (:58), justifié. E10 Poll vide l'affichage si SexOn absent (:428-429), justifié. E11 D1 / D2 d'I1 : voir C6. Aucun écart n'est un défaut ; aucun ne contredit une décision de l'utilisateur PASS-STATIC
C3 Garde 1 : Cursor / EquipMenu introuvable → pas de plantage, un avertissement unique, récompense appliquée L'affichage vient après ModifyStat et le journal (.cpp:567-576) : aucun retour d'affichage ne défait la récompense. Chemin : FindCursor (:643-668) → ReadObject faux : FirstWarning("GI.Cursor") puis nullptr ; Cast<UUserWidget> nul, invalide ou WidgetTree nul : FirstWarning("GI.Cursor.Value") puis nullptr (le test !Cursor->WidgetTree suit IsValid, pas de déréférencement nul) ; FindEquipMenu (:670-686) → Cast<UPanelWidget> nul : FirstWarning("Cursor.EquipMenu") ; GetNameSafe(nullptr) sûr. ShowAppliedReward rend sans effet sur nullptr (:595-604). Clé permanente dans Warned : un seul avertissement par session et par cause, et un Cursor valide plus tard fonctionne (pas d'état bloquant). Hauteur : Slot absent ou pas un UCanvasPanelSlot → FirstWarning("EquipMenu.Slot"), retour, l'affichage continue (:605-606). AddChild nul → FirstWarning, retour nullptr (:774-783). Garde 1 établie (lecture) PASS-STATIC
C4 Garde 2 : aucun ajout en double si EquipMenu est reconstruit EnsureRewardBox (:721-801), ordre : (1) RewardBox faible valide et GetParent() == Equip : retour sans création (:726-730) ; (2) enfant d'EquipMenu nommé LPBonusRewardBox : repris (:735-744, bAttached) ; (3) objet de ce nom dans l'arbre de Cursor par FindObjectFast : repris, RemoveFromParent puis ré-ajout, sans NewObject du même nom (:746-757) ; (4) création seulement si rien n'existe (:757-760). Chaque reprise vide la case et la liste (:791-792). Les lignes sont des enfants de la case : une seule case par EquipMenu. Cas Cursor recréé : nouvel arbre, nouveau nom libre, une case créée, anciennes lignes oubliées (RewardLines.Reset()), sans fuite (ramasse-miettes). Garde 2 établie (lecture) PASS-STATIC
C5 Garde 3 : minuteries nettoyées à la sortie de scène et dans Deinitialize Sortie de scène : Poll → SexOn faux : ClearRewardDisplay(true) (.cpp:434-441), idem propriété absente (:428-429) ; la fonction retire chaque ligne (RemoveLine) et vide RewardLines (échéances = contenu du tableau, aucune autre minuterie : pas de FTimerManager, pas de seconde poignée) (:822-838). Deinitialize (:263-273) : RemoveTicker(TickHandle) d'abord (plus aucun passage de Tick, donc plus de lecture d'échéance), ClearRewardDisplay(false) (échéances vidées, widgets laissés au monde qui se ferme), RewardBox.Reset(). Aucun accès à un widget après Deinitialize. Cas limite : la case vide reste dans EquipMenu après la scène (voir D2). Garde 3 établie (lecture) PASS-STATIC
C6 Non-régression d'I1 (contre STE-ORG5-V1-VAL.md C2-C9) Table .cpp:278-299 : 20 clés dans l'ordre ; tags relus : clés 1, 3, 4 vides (perversion, prone_to_orgasm, attractiontoplayer), masochist / likes_rough / masochist- {Aggressive, AggressiveFM}, fitness / prone_to_orgasm- {Penetration, Foreplay, Cum}, likes_oral 6 tags, likes_handjob 3 tags : identiques à la description de V1 C2. Tirage Pick :358-403 : mélange Fisher-Yates RandRange(i, LastIndex), SetNum(min(20,10)), filtre Overlaps(…, true), règle attractiontoplayer, sortie à 3, - final retiré : inchangé. Formule RewardChange :303-312 : ordre Abs, MapRangeClamped(0,100,0,1.9), 2 - m, ×10, FCeil, /10, signe : inchangé ; CheckFormula :314-338 : 8 cas inchangés. H1 Poll :417-519 : mémorisation au premier passage, hausse = 1 attente (FireAt = +0,2 s), baisse = resynchronisation, oubli des personnes sorties : inchangé hors les ajouts d'affichage (bInScene, ClearRewardDisplay). Règle commune ORG4 / ORG5 : un incrément de Sex_OrgasmCounts = au plus un Pending = au plus une récompense (OnOrgasm, Stats[0]) = au plus une ligne ; Endsex sans Cum : aucun incrément, aucune ligne. D1 corrigé pour le nouveau code et les trois avertissements de Poll (FirstWarning :423, :447, :466, définition :1011-1020, WarnOnce réécrit :1022-1028) ; restent hors correction, comme annoncé IMPL § 4, les WarnOnce(Key, Printf) liés à un orgasme (:489, :847, :858, :886…), appelés une fois par orgasme au plus. D2 corrigé : ReadStrings :205-239 accepte FStrProperty, FNameProperty ou FTextProperty (return false seulement si aucun des trois). Reste d'I1 (AttractionAllowed, IsInterestedIn, QueryStat, ModifyStat, PersonName :840-1009) : appels et signatures conformes à V1 C6. Limite : la version I1 n'existe plus (IMPL § 3, aucune copie) ; la comparaison repose sur la relecture contre V1-VAL et la SPEC, pas sur un diff PASS-STATIC
C7 Compilation probable (lecture) Includes : Blueprint/UserWidget.h, Blueprint/WidgetTree.h, Components/CanvasPanelSlot.h, PanelWidget.h, TextBlock.h, VerticalBox.h, VerticalBoxSlot.h, Styling/CoreStyle.h, UObject/TextProperty.h, UObject/UnrealType.h (.cpp:7-20) ; FSlateChildSize / ESlateSizeRule via Widget.h → SlateWrapperTypes.h ; FSlateFontInfo / FFontOutlineSettings via TextBlock.h. Déclarations avancées .h:52-55 suffisantes (pointeurs et TWeakObjectPtr seulement dans l'en-tête). Signatures relues à la source : GetWidgetFromName(const FName&) const (UserWidget.h:1426), GetFont() const rend const FSlateFontInfo& (TextBlock.h:148), SetFont(FSlateFontInfo) :156, SetColorAndOpacity(FSlateColor) :114, SetText(FText) :103, AddChild(UWidget*) rend UPanelSlot* (PanelWidget.h:59), GetChildAt(int32) const :36, GetChildrenCount() const :28, AddChildToVerticalBox rend UVerticalBoxSlot* (VerticalBox.h:30), SetPadding(FMargin) / SetSize(FSlateChildSize) / SetHorizontalAlignment (VerticalBoxSlot.h:53,58,63), UCanvasPanelSlot::GetSize() const / SetSize(FVector2D) / GetAnchors() const / GetAutoSize() const (CanvasPanelSlot.h:116,112,132,148), FAnchors::IsStretchedVertical() const (Anchors.h:78), RemoveFromParent() virtuelle sur UWidget (Widget.h:776), GetParent() (:769). FindObjectFast deux arguments (UObjectGlobals.h:2059). Expression conditionnelle Sample ? Sample->GetFont() : FCoreStyle::GetDefaultFontStyle(…) (.cpp:58) : lvalue const FSlateFontInfo contre prvalue FSlateFontInfo, résultat prvalue copiée dans Font : valide. UE_LOG : %.0f avec double, %d avec int32, %s avec *FString ou const TCHAR*. Avertissements probables : aucun masquage (C4456 / C4458) relevé (aucun membre nommé Cursor, Box, Line, Equip, Size, Tree, Entry, Font) ; aucun C4996 (aucune API dépréciée citée) ; [[nodiscard]] respecté. Compilation : reportée à BUILD COMMUN-8 PASS-STATIC (probable)
C8 Sûreté UMG Création par Cursor->WidgetTree->ConstructWidget (:621, :759) : outer = arbre de Cursor ; nom fixe LPBonusRewardBox avec FindObjectFast avant création (:749) ; pointeurs faibles seuls (RewardBox, FLPBonusRewardLine::Line) ; IsValid avant chaque accès (:44-45, :658, :676, :727, :752, :762) ; RemoveFromParent seulement si IsValid ; appels depuis FTSTicker sur le thread de jeu (Tick → FirePending / ExpireRewardLines), jamais dans la pile de l'événement Cum (SPEC R3) ; aucun accès après Deinitialize (ticker retiré en premier) ; WidgetTree testé avant ConstructWidget (:658) et Tree non nul pour FindObjectFast. Shipping : aucune macro éditeur, aucun check / ensure, aucun code de débogage ajouté ; Verbose pour le détail. Aucun UFUNCTION, aucun délégué lié à un widget (pas de gestionnaire de clic, pas de rappel après destruction) PASS-STATIC
C9 CR et nom d'utilisateur CR : cat <fichier> | tr -cd '\r' | wc -c → .h 0 (165 lignes par wc -l), .cpp 0 (1028 lignes). Grep d'un nom d'utilisateur et d'un chemin de profil sur LPBonusRewardSubsystem.* (motif non recopié ici) : Found 0 total occurrences across 0 files. ; Grep du même motif sur ce livrable : rejoué après écriture (voir Constats) PASS

4. Diff lu en entier

  • Deux fichiers non suivis (??) : pas de diff contre un tag (STE-ORG5-avant ne couvre rien d'existant ; la version I1 n'a pas été sauvegardée avant I2a, IMPL § 3). Lus en entier : .h 165 lignes, .cpp 1028 lignes (comptes wc -l : 165 et 1028 = valeurs de l'IMPL). Aucun autre fichier de Content, Source ou Config ajouté ou modifié par le lot (C0, comparaison aux 18 lignes de l'état d'entrée de l'IMPL § 1.5).
  • Références .cpp de l'IMPL § 1 contrôlées sur 12 positions tirées : :263-273 Deinitialize, :413 Tick, :417-446 Poll, :574-576 OnOrgasm, :579-641 ShowAppliedReward, :643-668 FindCursor, :670-686 FindEquipMenu, :688-719 EnsureEquipMenuHeight, :721-801 EnsureRewardBox, :803-820 ExpireRewardLines, :822-838 ClearRewardDisplay, :1011-1028 FirstWarning / WarnOnce : toutes exactes. Références du .h (:52-55, :86-90, :132-148, :158-164) exactes.
  • Aucune trace de modification par script (fichiers rédigés avec les outils dédiés, horodatages 09:33 et 09:35). Ajouts hors SPEC : tous annoncés (E1-E11), aucun caché.

5. Verdict

PASS-STATIC : les trois gardes de Big Boss sont établies par lecture (C3, C4, C5), les décisions Q-I2-1 à 4 sont tenues (C1), I1 est non régressé et D1 / D2 corrigés comme annoncé (C6), la compilation est probable (C7). Aucun défaut bloquant. Deux défauts mineurs (D1, D2), une limite de méthode (L1), et les points reportés au build COMMUN-8 et à l'essai V6.

Défauts :

# Gravité Constat Correctif proposé (non appliqué)
D1 mineur (probabilité très faible) FindObjectFast<UObject>(Tree, BoxName) (.cpp:749) n'exclut pas un objet marqué à détruire : si un objet de ce nom est en attente de ramasse-miettes, Cast réussit mais IsValid est faux (:762) ; avertissement unique LPBonusRewardBox.Type (message inexact : il parle d'un objet « sans être une VerticalBox utilisable ») et aucun affichage jusqu'au ramassage. L'objet est un sous-objet de l'arbre : il n'est détruit que si l'arbre l'est, donc avec un Cursor déjà remplacé (estimé, non rejoué) passer EInternalObjectFlags / RF_BeginDestroyed en exclusion, ou accepter pour l'alpha
D2 mineur (rendu, non établi) La case LPBonusRewardBox reste dans EquipMenu après la fin de la scène et l'expiration des lignes (seules les lignes sont retirées, :822-838) ; son slot est Fill comme ScrollBox_3 : la liste de bondage partage la place même quand la case est vide (IMPL § 5 « Mise en page »). Effet visible possible : ScrollBox_3 plus petit à 500 de haut à juger en V6 ; si gênant, mettre la case en Auto ou Collapsed hors ligne (SetVisibility)

Limite L1 (méthode, déclarée par l'IMPL § 3 et § 4) : aucun instantané avant I2a, sk-change-safety non invoqué ; la version I1 ne se récupère plus. Le repli SPEC § 3 git restore est impossible tant que le gardien n'a pas commité I1 + I2a ensemble (SPEC R7). Constat F-I2a-1 de l'IMPL, repris ici.

6. Points à confirmer par l'utilisateur (cases)

  • 1. Build COMMUN-8 : code 0, module LifePlay recompilé, 0 erreur, 0 nouvel avertissement sur les deux fichiers (V5-2, C-a à C-f).
  • 2. Essai V6 : ligne visible menu ouvert sous la grille d'objets, blanche à contour noir, alignée à gauche (V6-1) ; disparition seule à 20 s (V6-8) ; remplacement au second orgasme (V6-3) ; aucune ligne après la fin de scène (V6-4) ; bDisabled=True : ni case ni ligne (V6-5) ; 0 plantage, 0 Accessed None, aucun avertissement Bonus : de widget nouveau (V6-7).
  • 3. Journal V6-2 : une ligne affichage dans EquipMenu (classe …, 4 enfants) et hauteur d'EquipMenu portee de 350 a 500 (le dump de l'arbre de Cursor est antérieur au resave U5, F-I2-6).
  • 4. Mise en page (D2) : liste de bondage (ScrollBox_3) lisible à 500 de haut avec la case vide ; décision si D2 doit être corrigé.
  • 5. Ticket groupé I1 + I2a au gardien avant toute autre fiche touchant les deux fichiers (L1).

Non rejoué par cette VAL : compilation et UHT, LPTestStringCompat, CompileAllBlueprints, comportement en jeu (une ligne vue, durée de 20 s, hauteur 500 effective), type réel de GI.Cursor et d'EquipMenu au chargement, diff contre la version I1 (perdue), texte du fichier Licenses.

Tours : 8 / 35

Constats

  • Fichiers à commiter : A Docs/Migration/etat/ST/STE/STE-ORG5-V2-VAL.md (dépôt du jeu, branche ue5.8). Aucun fichier source modifié par la VAL ; MD5 identiques avant et après.
  • Écart de méthode de ma part : une commande Bash de contrôle des CR contenait une redirection d'entrée vers le fichier nul malgré la consigne « aucun chevron » ; le crochet ne l'a pas refusée, sa sortie a été ignorée et les comptes de CR ont été relevés par la seconde commande de la même exécution (tr -cd '\r' | wc -c). Sans effet sur les fichiers.
  • À verser : lp-validate § 1 — contrôle du périmètre d'une VAL sur fichiers non suivis : git status --porcelain -- Content Source Config puis wc -l (18 ici) et md5sum au début et à la fin ; compter les CR par cat <f> | tr -cd '\r' | wc -c sans aucun chevron. lp-validate § 3 (VAL de code UMG) — le motif de la SPEC (AddToViewport\|…\|UButton) et celui qu'une IMPL cite peuvent différer : rejouer celui de la SPEC.