LifePlay-Revival/Docs/Migration/etat/REL/FIX1/FIX1-MZ-IMPL.md
2026-10-21 09:36:04 +02:00

19 KiB
Raw Blame History

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 ? si HeelHeight est introuvable (ou ni flottant ni entier). <z> : %.2f, de la même formule que Person::updateHeelHeight (-90 + 12 × h), ou ? si <h> vaut ?.
  • <nom> : nom de l'objet de currentAnimation, - 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 lignes M-Z :, ou l'expression régulière M-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 de M-Z : retrouve les anciennes et les nouvelles lignes. Aucun consommateur de cette ligne dans Tools (Grep M-Z sur D:\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 :

  1. Référence inexacte de la fiche : LPDebugSubsystem.cpp:631-643 ne lit ni currentAnimation ni meshZ (ce sont l'enregistrement de PersonsDumpCommand et le ticker -LPPersonsLog). La lecture par réflexion est à LPDebugSubsystem.cpp:316-321 (ReadObjectName), :333 (SeatPlace), :414-418 (ligne STATE … meshZ= … currentAnimation=). Modèle suivi : ReadObjectName.
  2. ? et - distincts : la fiche demande ? si une variable est introuvable. Pour currentAnimation, un objet vide s'écrit - (convention de ReadObjectName, LPDebugSubsystem.cpp:320), pour ne pas confondre « variable absente » (?) et « aucune animation » (-).
  3. 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 non TemplateZ + 12 × HeelHeight ; TemplateZ figure déjà dans la ligne (-> %.1f). Si un jour le gabarit n'est plus à −90, les deux valeurs divergent, ce qui se verra.
  4. 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 .uasset 5.8.
  5. Noms préfixés MZ dans le namespace anonyme (unity build : un nom identique dans un autre .cpp du module donnerait C2374, lp-build § 8) ; Grep \bMZ[A-Z][A-Za-z]* sur Source avant édition : aucun résultat.
  6. Instantané non refait : D:\Game\LifePlay_Backup_5.5\FIX1-MZ\ existait déjà (voir § 3).
  7. CopieEtat.ps1 -Lot FIX1 rend le code 1 (alerte GIT) : voir ## Constats. La commande est celle de la fiche, sans -Assets.

3. Instantané

  • Lot FIX1-MZ, dossier D:\Game\LifePlay_Backup_5.5\FIX1-MZ\ : créé avant ma fiche (par l'ordonnateur ; date du manifeste 2026-10-20T20:04:15), contient Source\LifePlay\LPDirectControlSubsystem.cpp et manifest.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=2 n'est pas dans cette fiche (périmètre : instrumentation C++ seule) ; elle revient à l'ordonnateur.
  • Aucun paquet (BuildDebug.ps1, cuisson) : seuls LifePlayEditor et LifePlay Development ont été compilés dans Binaries\Win64 de 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

  1. La chaîne HeelHeight=%s ; currentAnimation=%s ; -90+12*HeelHeight=%s est dans Binaries\Win64\LifePlay.exe et UnrealEditor-LifePlay.dll (rejouer les deux recherches de ## Constats, ou LogStats sur un journal d'une séance).
  2. Dans un journal de séance, chaque ligne M-Z : porte les trois champs ; relever le nombre de lignes avec HeelHeight=? (attendu 0 si la variable existe sous ce nom dans Person_C 5.8) et avec currentAnimation=? (attendu 0).
  3. 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 de FIX1-F7-PRE.md, 7 sur 18) = autre cause à instruire.
  4. 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 lignes M-Z : par séance comparable).
  5. Type réel de HeelHeight en 5.8 : si une ligne porte HeelHeight=? alors que le personnage porte des talons, la variable n'est pas flottante ou entière sous ce nom (relire Person.uasset 5.8 par LPDumpFunction/MCP).
  6. Le build LifePlayEditor compte exactement 20 lignes UBT HyperAIStudio et le build LifePlay 0 (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.cpp
  • A 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.