12 KiB
Fiche CAM-B2j-VAL — Niveau N1 — Modèle prévu sonnet | utilisé Sonnet 5.5 (claude-sonnet-5-5) — Agent lp-validator — Skills sk-protocol, sk-recount, debug-verification, lp-validate
CAM-B2j-VAL : témoin « touche C », validation statique (2026-10-13)
Copie D:\Game\LifePlay-master 5.8, branche ue5.8 (git branch --show-current : ue5.8). Sans UE, sans compilation, sans
build : lecture et diff seulement. Seul fichier écrit : ce livrable.
1. Fiches amont relues
- Spécification :
Docs\Migration\etat\CAM\CAM-COMMUN4-DIAG.md§ 5 point 2 (l. 164-174) et complément (l. 180-198). - Aucune fiche
CAM-B2j-*ni IMPL B2j dansDocs\(Glob**/*B2j*: 0 résultat). Il n'y a donc pas de « point à confirmer » d'IMPL à reprendre (voir § 2).CAM-B2i-IMPL.mdetCAM-B2i-VAL.mdexistent (hors périmètre du diff B2j, non relus en détail). - Avant :
D:\Game\LifePlay_Backup_5.5\CAM-B2j\Source\LifePlay\(2 fichiers) ; après :Source\LifePlay\. - État git :
git status --shortdonne??pour les deux fichiers (non suivis dans la copie 5.8, donc pas de<lot>-avantexploitable) ; la comparaison se fait pargit diff --no-indexsur la sauvegarde.
2. Points à confirmer des IMPL
| Point | Verdict |
|---|---|
| Aucune IMPL B2j écrite, donc aucun point listé | sans objet : aucun livrable IMPL (Glob 0 résultat) ; les points de compilation et de comportement sont traités en § 3 |
| Compilation réelle (C2xxx, C4996) | reporté (BLOCKED-pas-de-build : non demandé) : à confirmer par la fiche BUILD de B2j |
Ligne Touche C effectivement émise en jeu |
reporté : exige un essai en jeu (passage CharGen en C1, appui sur C) |
3. Critères rejoués
3.1 Empreintes
Commande : md5sum des 4 fichiers.
d8981529e3773fbf50bb7fc1c91bc91f *Source/LifePlay/LPCameraModeSubsystem.cpp
2e1e245883960c2affc667a9a48fd96d *Source/LifePlay/LPCameraModeSubsystem.h
61fb558202e9bb3f567bceaa4bf241d3 *…/CAM-B2j/Source/LifePlay/LPCameraModeSubsystem.cpp
84f9ba303e1abd171c506dfbb4ed9f63 *…/CAM-B2j/Source/LifePlay/LPCameraModeSubsystem.h
Attendus : D8981529…, 2E1E2458…, 61FB5582…, 84F9BA30…. Verdict : PASS (4 sur 4).
3.2 Diff lu en entier
git diff --no-index --stat : .cpp 72 lignes (71 ajouts, 1 suppression), .h 10 ajouts. Diff complet lu (2 fichiers).
La seule ligne supprimée est la condition de tête de Tick (if (Label.IsEmpty() || MenuOnScreen(...))), remplacée par
une version à bMenu calculé en amont (.cpp:196 : même condition). Aucun Blueprint ni asset dans le diff.
Verdict : PASS-STATIC.
3.3 Conformité à la spécification (§ 5 point 2)
| Exigence | Preuve | Verdict |
|---|---|---|
Second FTSTicker à intervalle 0, ajouté dans Initialize |
.cpp:163 AddTicker(... TickSwitchKey), 0.f) dans SwitchKeyHandle |
PASS-STATIC |
Retiré dans Deinitialize |
.cpp:167 RemoveTicker(SwitchKeyHandle) avant TickHandle |
PASS-STATIC |
Lecture des ActionMappings d'UInputSettings, action SwitchCamera |
.cpp:224-228 (GetInputSettings(), boucle GetActionMappings()), .cpp:230 Map.ActionName == SwitchCameraAction (FName("SwitchCamera"), .cpp:45) |
PASS-STATIC |
PlayerInput->IsPressed |
.cpp:230 |
PASS-STATIC |
| Front montant uniquement | .cpp:237 bDown && !bSwitchKeyDown, puis .cpp:241 bSwitchKeyDown = bDown |
PASS-STATIC |
Champs de la ligne Touche C : BuilderOn, SpaceOn, SexOn, CamC1On, CamC3On, C1Hidden, entree PC, regard ignore, viewport ignore, vue (classe), Room, PC, indicateur |
.cpp:254-258 ; variables : GIBuilderOn, GISpaceOn (nouveau, .cpp:43), GISexOn, RoomCamC1On, RoomCamC3On, RoomC1Hidden (nouveau, .cpp:44) |
PASS-STATIC |
Ligne Indicateur de camera : aucun (vue …, classe …) hors menu quand le libellé est vide |
.cpp:182-195 : branche else if (!bMenu) ; texte "%s, classe %s" inséré dans (vue %s) |
PASS-STATIC |
| Une seule ligne par changement de vue | .cpp:189 ViewText != LastEmptyView ; LastEmptyView remis à zéro dès qu'un libellé non vide existe (.cpp:178-181) |
PASS-STATIC |
ShownLabel remis à zéro au changement de vue vide, donc libellé suivant journalisé de nouveau |
.cpp:192 ShownLabel.Reset() ; test .cpp:205 Label != ShownLabel puis log .cpp:209 |
PASS-STATIC |
| Aucun changement de comportement de l'indicateur affiché | remarques R1, R2 ci-dessous | PASS-STATIC |
| Aucun Blueprint touché | le diff ne porte que sur 2 fichiers C++ | PASS-STATIC |
Remarques (non bloquantes) :
- R1.
MenuOnScreenest désormais évalué à chaque tick de 0,1 s même quand le libellé est vide (avant : court-circuit parLabel.IsEmpty() ||). La fonction est sans effet de bord (lecture,TObjectIterator<UUserWidget>) et déjà exécutée à la même cadence quand le libellé est non vide ; l'effet (SetShown(false)puis retour) est le même. Estimé : surcoût négligeable à 10 Hz. - R2.
ShownLabel.Reset()au changement de vue vide force seulement la réécriture du même texte à la reprise d'un libellé non vide, sans effet visible. Estimé. - R3 (limite du témoin, estimé).
UGameViewportClient::InputKeyrend la main avantPlayerInputsiIgnoreInput()est vrai (Engine\Private\GameViewportClient.cpp:767-770). Avecviewport ignore=1, la touche n'atteint donc pasPlayerInput->IsPressedet aucune ligneTouche Cne sortira : l'absence de ligne est alors elle-même un indice (H4 côté viewport). Les casentree PC=0etregard ignore=1restent journalisés.
3.4 Compilation probable (en-têtes D:\Game\Launcher\Engine\UE_5.8\Engine\Source\Runtime\Engine\Classes\…)
| Élément | Source | Verdict |
|---|---|---|
Includes GameFramework/InputSettings.h (.cpp:13) et GameFramework/PlayerInput.h (.cpp:15) |
ajoutés en ordre alphabétique autour de PlayerController.h |
PASS-STATIC |
UInputSettings::GetInputSettings() statique ; GetActionMappings() const |
GameFramework/InputSettings.h:248, :316 |
PASS-STATIC |
UPlayerInput::IsPressed(FKey) const |
GameFramework/PlayerInput.h:745 |
PASS-STATIC |
PC->PlayerInput est un TObjectPtr<UPlayerInput> : via const APlayerController* le pointé reste non const, IsPressed const appelable de toute façon |
GameFramework/PlayerController.h:370 |
PASS-STATIC |
APlayerController::InputEnabled() const |
PlayerController.h:2142 |
PASS-STATIC |
AController::IsLookInputIgnored() const (virtuelle) |
GameFramework/Controller.h:383 |
PASS-STATIC |
GetViewTarget() const |
Controller.h:253, PlayerController.h:1911 |
PASS-STATIC |
UGameViewportClient::IgnoreInput() non const |
Engine/GameViewportClient.h:773 (virtual bool IgnoreInput() override, sans const) |
PASS-STATIC |
UGameInstance::GetGameViewportClient() const rend un pointeur non const, d'où UGameViewportClient* ViewportClient |
Engine/GameInstance.h:295 ; .cpp:252 |
PASS-STATIC |
UWorld::GetFirstPlayerController() rend APlayerController*, converti en const APlayerController* |
Engine/World.h:2781 |
PASS-STATIC |
GetNameSafe(const UObjectBaseUtility*) accepte const AActor*, const UObject*, const APlayerController* |
Runtime\CoreUObject\Public\UObject\UObjectBaseUtility.h:893 |
PASS-STATIC |
LogSwitchKey(...) const n'appelle que du const : GetGameInstance(), ReadObject / ReadBool (fonctions libres), IsValid, GetViewTarget, InputEnabled, IsLookInputIgnored, GetClass, GetGameViewportClient ; IgnoreInput passe par un pointeur non const local |
.cpp:245-259 |
PASS-STATIC |
TickSwitchKey (non const) appelle LogSwitchKey (const) |
.cpp:239 |
PASS-STATIC |
UE_LOG « Touche C » : 14 spécificateurs (9 %d puis 5 %s) pour 14 arguments (3 + 3 Flag en int, 3 ternaires ? 1 : 0, puis *GetNameSafe(View), View ? *…GetName() : TEXT("-") (const TCHAR*), *GetNameSafe(Room), *GetNameSafe(PC), *ShownLabel) |
.cpp:254-258 |
PASS-STATIC |
UE_LOG « aucun » : 1 %s pour *ViewText ; Printf("%s, classe %s") : *GetNameSafe(View) et const TCHAR* |
.cpp:188, .cpp:193 |
PASS-STATIC |
Lambda Flag : [](const UObject* Container, FName Name) { return ReadBool(...) ? 1 : 0; }, sans capture ; ReadBool qualifiée, accepte un conteneur nul ; reçoit const UGameInstance* (conversion vers const UObject*) ; définie hors de la macro UE_LOG |
.cpp:253 ; ReadBool .cpp:77-81 |
PASS-STATIC |
class APlayerController; avant usage en signature |
.h:17, usage .h:45 |
PASS-STATIC |
.h : FTSTicker (Containers/Ticker.h déjà inclus), FString via CoreMinimal.h |
.h:12-13 |
PASS-STATIC |
LogLifePlay déclaré (LifePlay.h inclus .cpp:17) |
LifePlay.h:9 |
PASS-STATIC |
Espace nommé LPCameraModeLocal (pas anonyme) ; nouvelles constantes dans cet espace ; appels qualifiés ; commentaire de tête de l'espace |
.cpp:24-45 |
PASS-STATIC |
DeltaTime non utilisé : (void)DeltaTime; |
.cpp:242 |
PASS-STATIC |
Membres initialisés : SwitchKeyHandle, bSwitchKeyDown = false, LastEmptyView |
.h:48-52 |
PASS-STATIC |
Verdict du bloc : PASS-STATIC (aucune erreur de compilation décelée par lecture ; compilation non rejouée).
Incertain : avertissement d'ombre de nom éventuel (PC, World locaux dans Tick ou LogSwitchKey) ; aucun membre
homonyme dans le .h, estimé sans risque.
3.5 Coût
Le ticker à intervalle 0 exécute, à chaque image : GetFirstPlayerController, GetInputSettings (CDO), une boucle sur
GetActionMappings() (une centaine d'entrées au plus, comparaison d'FName = comparaison d'entiers) et IsPressed
seulement pour les entrées nommées SwitchCamera. Pas d'allocation en régime normal (le FString de LogSwitchKey
n'existe que sur front montant). Estimé : de l'ordre de la microseconde par image, acceptable pour un témoin de
diagnostic. Verdict : PASS-STATIC (non mesuré). Le témoin est à retirer après le diagnostic.
3.6 Fins de ligne, BOM
Commande : pwsh -NoProfile -Command '& "D:\Game\LifePlay-master 5.8\Tools\FileCheck.ps1" -Path "Source\LifePlay\LPCameraModeSubsystem.cpp","Source\LifePlay\LPCameraModeSubsystem.h"', code 0 :
LF 0 456 0 - D8981529E3773FBF50BB7FC1C91BC91F Source\LifePlay\LPCameraModeSubsystem.cpp
LF 0 62 0 - 2E1E245883960C2AFFC667A9A48FD96D Source\LifePlay\LPCameraModeSubsystem.h
fichiers=2 LF=2 alertes=0 introuvables=0
Recoupé par tr -cd '\r' | wc -c : CR = 0 pour les deux fichiers (et 0 pour le .cpp d'avant) ; head -c3 | xxd -p :
2f2f20 (« // »), donc sans BOM. Piège noté : -Path 'a','b' passé par pwsh -File est lu comme un seul chemin
(« introuvable ») ; passer par -Command. Verdict : PASS.
3.7 Chemins de profil Windows
Grep C:\\Users|AppData|<nom du compte> sur LPCameraModeSubsystem.* : 0 occurrence. Le présent livrable n'en contient pas
(chemins du moteur et de la copie seulement). Verdict : PASS.
4. Diff lu en entier
- Fichiers :
Source\LifePlay\LPCameraModeSubsystem.cpp(+71 −1),Source\LifePlay\LPCameraModeSubsystem.h(+10). - Recompté :
git diff --no-index --statdonne72 …+++++++++++++++++++++-et10 ++++++++++. Toutes les lignes ajoutées relèvent de la spécification (constantes, includes, ticker,Tick,TickSwitchKey,LogSwitchKey, membres) : aucun ajout non demandé.
5. Verdict
PASS-STATIC : conforme à la spécification et compilable à la lecture, empreintes attendues, LF sans BOM, aucun chemin de profil. Non rejoué : compilation, émission de la ligne en jeu (§ 6). Aucun écart bloquant ; 3 remarques (R1 à R3).
6. Points à confirmer par l'utilisateur (cases)
- Compilation
LifePlayEditor5.8 sans erreur nouvelle (fiche BUILD B2j, puisBuild.ps1 -FromLog). - Essai en jeu : passage CharGen en C1, appui sur C, lecture de la ligne
Touche C : …dansSaved\Logs\LifePlay.log. - Lecture de R3 : si aucune ligne
Touche Cn'apparaît après l'appui, la touche n'atteint pasPlayerInput(viewport ignore ou coupure en amont) ; ce n'est pas un défaut du témoin. - Retrait du témoin (ticker image par image) après le diagnostic.
Fichiers à commiter : aucun par cette VAL (livrable Docs\Migration\etat\CAM\CAM-B2j-VAL.md à verser par le gardien avec le
lot ; les deux fichiers C++ sont ?? dans la copie 5.8 et relèvent du ticket du lot).
Tours : 12 / 40