23 KiB
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 IMPLSTE-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) ; SPECSTE-ORG5-I2-SPEC.md(lue en entier, dont § 2.2, § 7 et « Décisions de l'utilisateur » Q-I2-1 à 4) ; VAL d'I1STE-ORG5-V1-VAL.md(lue en entier : C2 à C10, D1, D2). La fichefiches\STE-ORG5-I2a.mdn'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(inclutUObject/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-avantne couvre rien d'existant ; la version I1 n'a pas été sauvegardée avant I2a, IMPL § 3). Lus en entier :.h165 lignes,.cpp1028 lignes (compteswc -l: 165 et 1028 = valeurs de l'IMPL). Aucun autre fichier deContent,SourceouConfigajouté ou modifié par le lot (C0, comparaison aux 18 lignes de l'état d'entrée de l'IMPL § 1.5). - Références
.cppde l'IMPL § 1 contrôlées sur 12 positions tirées ::263-273Deinitialize,:413Tick,:417-446Poll,:574-576OnOrgasm,:579-641ShowAppliedReward,:643-668FindCursor,:670-686FindEquipMenu,:688-719EnsureEquipMenuHeight,:721-801EnsureRewardBox,:803-820ExpireRewardLines,:822-838ClearRewardDisplay,:1011-1028FirstWarning / 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
LifePlayrecompilé, 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, 0Accessed None, aucun avertissementBonus :de widget nouveau (V6-7). - 3. Journal V6-2 : une ligne
affichage dans EquipMenu (classe …, 4 enfants)ethauteur d'EquipMenu portee de 350 a 500(le dump de l'arbre deCursorest 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, brancheue5.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 Configpuiswc -l(18 ici) etmd5sumau début et à la fin ; compter les CR parcat <f> | tr -cd '\r' | wc -csans 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.