19 KiB
Fiche FIX1-MZ — Niveau N2 — Modèle prévu sonnet | utilisé claude-sonnet-5-5 — Agent lp-impl — Skills sk-protocol, ue-cpp-build
FIX1-MZ-IMPL : instrumentation de la ligne de journal M-Z (HeelHeight, currentAnimation, −90 + 12 × HeelHeight) (2026-10-20)
Décision citée par la fiche : l'ordre de l'utilisateur, recopié mot pour mot dans la fiche : « Oui : F7a, F7c et F8b en build 2 ; en build 1, ajoute la hauteur de talons et l'animation à la trace M-Z, et prépare la séance de mesure -LPPersonsLog=2. » La fiche ne donne ni la session ni l'heure (sk-protocol § 2) : je la traite comme une consigne de fiche, sans en tirer d'autre décision. Ma part se limite à l'instrumentation C++ ; la séance de mesure n'est pas dans cette fiche (voir § 4).
Hors gabarit : les deux compilations, CopieEtat, PubCheck et la preuve de présence de la chaîne dans les binaires sont rendus dans ## Constats (notes TRACE).
Écart de skills : la fiche cite sk-protocol, ue-cpp-build ; lp-build et lp-ue-compat sont aussi chargés dans mon contexte (utilisés pour les commandes de build et la liste des lignes connues).
Niveaux de preuve : établi (fichier:ligne ou sortie de commande), estimé (raisonnement donné), incertain (essai nommé).
1. Fichiers modifiés
Un seul fichier de source : D:\Game\LifePlay-master 5.8\Source\LifePlay\LPDirectControlSubsystem.cpp. Comportement inchangé (établi par lecture du diff : la correction Body->SetRelativeLocation(…) :1255 et MeshZScans.Remove(Person) :1256 sont intactes ; seules des lectures et le texte du UE_LOG ont changé).
| Mesure | Valeur | Commande |
|---|---|---|
MD5 avant (exigé 5f9d7e00) |
5f9d7e00402688822687e7eb32979bd1, conforme ; identique à l'instantané |
certutil -hashfile Source/LifePlay/LPDirectControlSubsystem.cpp MD5 avant la première édition ; colonne MD5 de D:\Game\LifePlay_Backup_5.5\FIX1-MZ\manifest.csv |
| MD5 après | 687c63d85395888b8a334cb537c16a53 (inchangé après les deux builds) |
certutil -hashfile … après les 2 éditions, puis après les 2 builds |
| Taille avant, après | 62 510 o, 64 858 o | manifeste de l'instantané ; ls -la |
| Fins de ligne | i/crlf w/crlf attr/-text ; 1818 CR = 1818 LF (aucune fin de ligne mixte) |
git ls-files --eol Source/LifePlay/LPDirectControlSubsystem.cpp ; tr -cd '\r' < … | wc -c et tr -cd '\n' < … | wc -c |
| Bilan du diff | 1 file changed, 49 insertions(+), 2 deletions(-) |
git diff --stat -- Source/LifePlay/LPDirectControlSubsystem.cpp |
Autres fichiers de Source modifiés |
Source/LifePlay/LPCameraModeSubsystem.cpp (déjà modifié avant ma fiche : F8a, FIX1-F8a-IMPL.md) ; aucun autre |
git status --short -- Source Tools |
Les deux éditions (outil Edit, sans script) ; le premier essai du second Edit a échoué (indentation à 5 tabulations au lieu de 4, aucune écriture), repris à 4 tabulations.
@@ -151,6 +151,47 @@ namespace
return Prop ? Cast<AActor>(Prop->GetObjectPropertyValue_InContainer(Object)) : nullptr;
}
+ // FIX1-MZ (instrumentation de la ligne M-Z, lecture seule) : formule de Person::updateHeelHeight, Z relatif du maillage =
+ // -90 + 12 x HeelHeight (L6f_dump_Person.txt:19818-19827, A='-90.000000', B='12.000000').
+ constexpr double MZHeelBaseZ = -90.0;
+ constexpr double MZHeelFactor = 12.0;
+
+ // Variable Blueprint numerique lue par reflexion (HeelHeight est un double : Conv_StringToDouble, L6f_dump_Person.txt:19774-19781).
+ // Faux si la variable est introuvable ou non numerique : aucun journal, l'appelant ecrit "?".
+ bool MZReadNumber(const UObject* Object, const TCHAR* Name, double& OutValue)
+ {
+ const FNumericProperty* Prop = Object ? CastField<FNumericProperty>(Object->GetClass()->FindPropertyByName(Name)) : nullptr;
+ if (!Prop)
+ {
+ return false;
+ }
+ const void* Data = Prop->ContainerPtrToValuePtr<void>(Object);
+ if (Prop->IsFloatingPoint())
+ {
+ OutValue = Prop->GetFloatingPointPropertyValue(Data);
+ return true;
+ }
+ if (Prop->IsInteger())
+ {
+ OutValue = static_cast<double>(Prop->GetSignedIntPropertyValue(Data));
+ return true;
+ }
+ return false;
+ }
+
+ // Nom de l'objet d'une variable Blueprint objet (currentAnimation) : "?" si la variable est introuvable, "-" si elle est vide
+ // (meme convention de vide que ReadObjectName de LPDebugSubsystem.cpp).
+ FString MZReadObjectName(const UObject* Object, const TCHAR* Name)
+ {
+ const FObjectPropertyBase* Prop = Object ? CastField<FObjectPropertyBase>(Object->GetClass()->FindPropertyByName(Name)) : nullptr;
+ if (!Prop)
+ {
+ return TEXT("?");
+ }
+ const UObject* Value = Prop->GetObjectPropertyValue_InContainer(Object);
+ return Value ? Value->GetName() : FString(TEXT("-"));
+ }
+
bool KeyDown(const APlayerController* PC, const FKey& Key)
@@ -1213,8 +1254,14 @@ void ULPDirectControlSubsystem::FitPersonBounds(float DeltaTime)
Body->SetRelativeLocation(FVector(Relative.X, Relative.Y, TemplateZ));
MeshZScans.Remove(Person);
- UE_LOG(LogLifePlay, Display, TEXT("M-Z : %s maillage relatif Z %.1f -> %.1f (gabarit %s), debout sans meuble"),
- *Person->GetName(), Relative.Z, TemplateZ, *Person->GetClass()->GetName());
+ // FIX1-MZ : instrumentation seule (F8b), lue par reflexion apres la correction, sans effet sur elle. "?" = variable introuvable.
+ double HeelHeight = 0.0;
+ const bool bHeelRead = MZReadNumber(Person, TEXT("HeelHeight"), HeelHeight);
+ const FString HeelText = bHeelRead ? FString::Printf(TEXT("%.3f"), HeelHeight) : FString(TEXT("?"));
+ const FString HeelZText = bHeelRead ? FString::Printf(TEXT("%.2f"), MZHeelBaseZ + MZHeelFactor * HeelHeight) : FString(TEXT("?"));
+ UE_LOG(LogLifePlay, Display, TEXT("M-Z : %s maillage relatif Z %.1f -> %.1f (gabarit %s), debout sans meuble ; HeelHeight=%s ; currentAnimation=%s ; -90+12*HeelHeight=%s"),
+ *Person->GetName(), Relative.Z, TemplateZ, *Person->GetClass()->GetName(),
+ *HeelText, *MZReadObjectName(Person, TEXT("currentAnimation")), *HeelZText);
}
}
else
Texte exact de la nouvelle ligne de journal (catégorie LogLifePlay, niveau Display, une ligne par déclenchement de M-Z, émise après la correction) :
M-Z : <acteur> maillage relatif Z <Z avant> -> <Z gabarit> (gabarit <classe>), debout sans meuble ; HeelHeight=<h> ; currentAnimation=<nom> ; -90+12*HeelHeight=<z>
<h>:%.3f, ou?siHeelHeightest introuvable (ou ni flottant ni entier).<z>:%.2f, de la même formule quePerson::updateHeelHeight(-90 + 12 × h), ou?si<h>vaut?.<nom>: nom de l'objet decurrentAnimation,-si la variable existe mais est vide,?si elle est introuvable (ou n'est pas une propriété objet).- Forme attendue, non observée en jeu :
M-Z : <acteur> maillage relatif Z -80.4 -> -90.0 (gabarit Person_C), debout sans meuble ; HeelHeight=0.800 ; currentAnimation=<nom> ; -90+12*HeelHeight=-80.40. Lecture :<Z avant>égal à<z>(à 0,05 près) = décalage de talons ; différent = autre cause. - Motif à chercher : chaîne fixe
HeelHeight=sur les lignesM-Z :, ou l'expression régulièreM-Z : .* maillage relatif Z (-?[0-9.]+) -> (-?[0-9.]+) \(gabarit (\S+)\), debout sans meuble ; HeelHeight=(\S+) ; currentAnimation=(\S+) ; -90\+12\*HeelHeight=(\S+). Le début de ligne (M-Z : … debout sans meuble) est inchangé : une recherche deM-Z :retrouve les anciennes et les nouvelles lignes. Aucun consommateur de cette ligne dansTools(GrepM-ZsurD:\Game\LifePlay-master 5.8\Tools: aucun résultat).
APIs moteur utilisées, lues dans UE 5.8.3 (Build.version : 5.8.3) : UStruct::FindPropertyByName(FName) Class.h:663 ; FNumericProperty::IsFloatingPoint UnrealType.h:1819, IsInteger :1822, GetSignedIntPropertyValue(void const*) :1886, GetFloatingPointPropertyValue(void const*) :1902 (pas de variante _InContainer pour les flottants, d'où ContainerPtrToValuePtr) ; FProperty::ContainerPtrToValuePtr<ValueType>(UObject const*, int32) :811 ; FObjectPropertyBase::GetObjectPropertyValue_InContainer(const void*, int32) :2896. Les mêmes signatures existent en 5.5.4 (UnrealType.h:1720, 1723, 1787, 1803, vérifiées par Grep).
2. Écarts à la SPEC
La fiche tient lieu de SPEC. Écarts et choix :
- Référence inexacte de la fiche :
LPDebugSubsystem.cpp:631-643ne lit nicurrentAnimationnimeshZ(ce sont l'enregistrement dePersonsDumpCommandet le ticker-LPPersonsLog). La lecture par réflexion est àLPDebugSubsystem.cpp:316-321(ReadObjectName),:333(SeatPlace),:414-418(ligneSTATE … meshZ= … currentAnimation=). Modèle suivi :ReadObjectName. ?et-distincts : la fiche demande?si une variable est introuvable. PourcurrentAnimation, un objet vide s'écrit-(convention deReadObjectName,LPDebugSubsystem.cpp:320), pour ne pas confondre « variable absente » (?) et « aucune animation » (-).- Constantes −90 et 12 littérales (nommées
MZHeelBaseZ,MZHeelFactor), comme dans la formule de l'ordre de l'utilisateur et du Blueprint (L6f_dump_Person.txt:19820, 19826), et nonTemplateZ + 12 × HeelHeight;TemplateZfigure déjà dans la ligne (-> %.1f). Si un jour le gabarit n'est plus à −90, les deux valeurs divergent, ce qui se verra. - Types admis pour
HeelHeight: flottant (cas attendu :double,Conv_StringToDouble,L6f_dump_Person.txt:19774-19781) ou entier ; tout autre type donne?. Le dump est celui de la 5.5 (L6f) : le type en 5.8 n'est pas relu dans le.uasset5.8. - Noms préfixés
MZdans lenamespaceanonyme (unity build : un nom identique dans un autre.cppdu module donnerait C2374,lp-build§ 8) ; Grep\bMZ[A-Z][A-Za-z]*surSourceavant édition : aucun résultat. - Instantané non refait :
D:\Game\LifePlay_Backup_5.5\FIX1-MZ\existait déjà (voir § 3). CopieEtat.ps1 -Lot FIX1rend le code 1 (alerte GIT) : voir## Constats. La commande est celle de la fiche, sans-Assets.
3. Instantané
- Lot
FIX1-MZ, dossierD:\Game\LifePlay_Backup_5.5\FIX1-MZ\: créé avant ma fiche (par l'ordonnateur ; date du manifeste2026-10-20T20:04:15), contientSource\LifePlay\LPDirectControlSubsystem.cppetmanifest.csv. - Manifeste (lu) :
"Source/LifePlay/LPDirectControlSubsystem.cpp","True","62510","5F9D7E00402688822687E7EB32979BD1","2026-10-20T20:04:15". - Vérifié par
certutil -hashfile D:\Game\LifePlay_Backup_5.5\FIX1-MZ\Source\LifePlay\LPDirectControlSubsystem.cpp MD5=5f9d7e00402688822687e7eb32979bd1: la copie d'instantané est l'état de départ exact. - Retour arrière (proposé, non lancé) :
Tools\Restore.ps1 -Lot FIX1-MZ, ou recopie de ce fichier d'instantané.
4. Ce qui n'a pas été fait
- Aucune mesure en jeu, aucune séance : la ligne n'a jamais été émise par un exécutable lancé. La préparation de la séance
-LPPersonsLog=2n'est pas dans cette fiche (périmètre : instrumentation C++ seule) ; elle revient à l'ordonnateur. - Aucun paquet (
BuildDebug.ps1, cuisson) : seulsLifePlayEditoretLifePlayDevelopment ont été compilés dansBinaries\Win64de la copie. Une séance sur un build empaqueté demande une fiche de paquet ; le build COM21 existant n'a pas ce code. - Aucune modification de comportement (M-Z force toujours le Z du gabarit), aucun correctif Blueprint (F8b reste en build 2), aucun fichier hors
LPDirectControlSubsystem.cpp. - Pas de test de la branche
?: elle n'a pas été déclenchée (aucune exécution). - Aucune commande git qui écrit.
5. Points à confirmer en VAL
- La chaîne
HeelHeight=%s ; currentAnimation=%s ; -90+12*HeelHeight=%sest dansBinaries\Win64\LifePlay.exeetUnrealEditor-LifePlay.dll(rejouer les deux recherches de## Constats, ouLogStatssur un journal d'une séance). - Dans un journal de séance, chaque ligne
M-Z :porte les trois champs ; relever le nombre de lignes avecHeelHeight=?(attendu 0 si la variable existe sous ce nom dansPerson_C5.8) et aveccurrentAnimation=?(attendu 0). - Pour chaque ligne : comparer
<Z avant>(valeur avant->) et-90+12*HeelHeight=; égalité à 0,05 près = décalage de talons ; écart (cas à −88,0 deFIX1-F7-PRE.md, 7 sur 18) = autre cause à instruire. - Contrôle de non-régression : le Z gabarit après correction (
-> -90.0) et le moment du déclenchement (2 balayages) sont ceux des journaux précédents (même nombre de lignesM-Z :par séance comparable). - Type réel de
HeelHeighten 5.8 : si une ligne porteHeelHeight=?alors que le personnage porte des talons, la variable n'est pas flottante ou entière sous ce nom (relirePerson.uasset5.8 parLPDumpFunction/MCP). - Le build
LifePlayEditorcompte exactement 20 lignes UBTHyperAIStudioet le buildLifePlay0 (lp-build§ 7) : retrouvés ici (20 et 0).
6. Fichiers à commiter
Dépôt du jeu (D:\Game\LifePlay-master 5.8, branche ue5.8) :
M Source/LifePlay/LPDirectControlSubsystem.cppA Docs/Migration/etat/REL/FIX1/FIX1-MZ-IMPL.md
Ne pas inclure Source/LifePlay/LPCameraModeSubsystem.cpp (autre lot, F8a). Les résumés de build FIX1_Build_20261020-200728.txt et FIX1_Build_20261020-200822.txt (même dossier) n'apparaissent pas dans git status --short -- Docs/Migration/etat/REL/FIX1 (les .txt de ce dossier sont ignorés par git) : à ne pas commiter. Les journaux bruts Saved\Logs\portage\FIX1_Build_*.log restent hors dépôt. Aucun fichier de l'addon ni des Modules.
Tours : 25 / 40 (budget N2 par défaut : la fiche ne donne pas de rubrique 9 ; Tools/FicheStats.py fait foi)
Constats
Compilation (hors gabarit, deux relevés)
Trace : D:\Game\LifePlay-master 5.8\Docs\Migration\etat\REL\FIX1\FIX1_Build_20261020-200728.txt — Fiche FIX1-MZ — 2026-10-20 20:07
Commande : cd 'D:\Game\LifePlay-master 5.8'; pwsh -NoProfile -File Tools/Build.ps1 -Lot FIX1 -EtatDir "D:\Game\LifePlay-master 5.8\Docs\Migration\etat\REL\FIX1" (LifePlayEditor Win64 Development, après Tools\CopieEtat.ps1 -Lot FIX1)
Environnement: copie 5.8, branche ue5.8, HEAD ad3c9c6 ; UE 5.8.3 ; éditeur fermé (UeState : processus=0) ; une seule compilation à la fois ; machine calme (cpu=1 % au CopieEtat)
Attendu : code 0, 0 erreur, 0 avertissement du compilateur ; 20 lignes UBT HyperAIStudio (connues)
Obtenu : code=0 duree=43s erreurs=0 avertissements=0 autres=20 unites=2 ; unités LPDirectControlSubsystem.cpp et Module.LifePlay.cpp ; DLL liée UnrealEditor-LifePlay.dll ; journal Saved\Logs\portage\FIX1_Build_20261020-200728.log
Lecture : « Makefile : » vide dans le résumé (statut non relevé par Build.ps1) ; module modifié bien recompilé (unité + DLL) ; chaîne « Using Visual Studio 14.50.35739 toolchain (…\MSVC\14.50.35717) and Windows 10.0.22621.0 SDK » = MSVC épinglé de la 5.8
Trace : D:\Game\LifePlay-master 5.8\Docs\Migration\etat\REL\FIX1\FIX1_Build_20261020-200822.txt — Fiche FIX1-MZ — 2026-10-20 20:08
Commande : cd 'D:\Game\LifePlay-master 5.8'; pwsh -NoProfile -File Tools/Build.ps1 -Lot FIX1 -Target LifePlay -Config Development -ExtraArgs '-NoUBA' -EtatDir "D:\Game\LifePlay-master 5.8\Docs\Migration\etat\REL\FIX1"
Environnement: identique ; lancé après la fin du premier build (UeState -Kind Editeur,Compilation -WaitExit : « plus rien ne tourne » avant lancement)
Attendu : code 0, 0 erreur, 0 avertissement ; 0 ligne UBT (cible jeu)
Obtenu : code=0 duree=56s erreurs=0 avertissements=0 autres=0 unites=2 ; unités LPDirectControlSubsystem.cpp [NoUba] et Module.LifePlay.cpp [NoUba] ; « DLL liées : 0 » (cible monolithique) ; exécutable Binaries\Win64\LifePlay.exe daté 2026-10-20 20:09:16 ; journal Saved\Logs\portage\FIX1_Build_20261020-200822.log
Lecture : « DLL liées : 0 » est normal pour la cible jeu ; la preuve de l'exécutable passe par la date, le MD5 et la recherche de chaîne ci-dessous ; 0 avertissement : le C4701 de F8a est bien absent
MD5 des binaires (certutil -hashfile … MD5) : Binaries\Win64\LifePlay.exe = e2ba7dec63d479974394e2cffd1efc19 (335 850 496 o, 2026-10-20 20:09:16) ; Binaries\Win64\UnrealEditor-LifePlay.dll = 68aee3039e0a320a4a085db1aa6e6018 (1 996 800 o, 20:08:10). L'exécutable livré dans Binaries\Win64\LifePlay-Win64-Shipping.exe (2026-10-14) n'est pas touché.
Présence de la nouvelle chaîne dans les binaires
Trace : sortie de commande, Fiche FIX1-MZ — 2026-10-20 ~20:12
Commande : grep -a -c -P 'H\x00e\x00e\x00l\x00H\x00e\x00i\x00g\x00h\x00t\x00=\x00%\x00s\x00' <binaire> puis grep -a -c -P 'd\x00e\x00b\x00o\x00u\x00t\x00 \x00s\x00a\x00n\x00s\x00 \x00m\x00e\x00u\x00b\x00l\x00e\x00 \x00;\x00' <binaire> (chaînes UTF-16LE de TEXT())
Environnement: depuis D:\Game\LifePlay-master 5.8 ; binaires ci-dessus
Attendu : ≥ 1 ligne correspondante dans chaque binaire (chaîne nouvelle compilée)
Obtenu : LifePlay.exe : 1 et 1 ; UnrealEditor-LifePlay.dll : 1 et 1
Lecture : `grep -c` compte des « lignes » binaires, pas des occurrences ; 1 = au moins une. Exception à la règle « Grep, pas grep » : l'outil Grep ne cherche pas de l'UTF-16 dans un binaire (lecture seule, ponctuelle). Preuve de présence seulement : elle ne dit pas que le code s'exécute (voir § 4)
CopieEtat (avant les builds)
COPIE ALERTE lot=FIX1 copie=LifePlay-master 5.8 proc=0 assets=0 absents=0 modifies=0 git=2/0/0 hors_declares=2 parasites=0 jeu_hors_docs=3 jeu_docs=8 head=ad3c9c6/30beef0/c8661cd verrou=248:libre cpu=1% alertes=GIT
ALERTE GIT : jeu [ M] Source/LifePlay/LPCameraModeSubsystem.cpp
ALERTE GIT : jeu [ M] Source/LifePlay/LPDirectControlSubsystem.cpp
INFO : controle d'instantane non fait (parametre -Depuis absent)
code=1
Lecture : les deux entrées sont des fichiers modifiés non déclarés par -Assets (la fiche n'en passe pas) : LPDirectControlSubsystem.cpp est le mien, LPCameraModeSubsystem.cpp vient de F8a (déjà modifié avant ma fiche, git status initial de la session). Aucun processus (proc=0), aucun parasite. Alerte attendue, non bloquante ; rien corrigé.
PubCheck
Commande : pwsh -NoProfile -File Tools/PubCheck.ps1 -Fichiers Source/LifePlay/LPDirectControlSubsystem.cpp -Depot "D:/Game/LifePlay-master 5.8" < /dev/null
Sortie : PubCheck : 0 constat(s)
code=0
Le livrable FIX1-MZ-IMPL.md et les résumés de build ne sont pas passés à PubCheck (la fiche ne demande que le fichier source ; chemins D:\Game\… présents dans les textes, comme dans FIX1-F8a-IMPL.md) : à contrôler par le gardien avant commit si la règle l'exige.
État final
Tools\UeState.ps1 en fin de fiche : processus=0 editeur=0 compilation=0 shaders=0 jeu=0 (code 0). Aucun processus Unreal lancé par moi n'est resté ouvert.