LifePlay-Revival/Docs/Migration/etat/REL/FIX1/FIX1-MZ2-IMPL.md

219 lines
23 KiB
Markdown
Raw Normal View History

Fiche FIX1-MZ2 — Niveau N2 — Modèle prévu sonnet | utilisé claude-sonnet-5-5 — Agent lp-impl — Skills sk-protocol, ue-cpp-build
# FIX1-MZ2-IMPL : M-Z vise −90 + 12 × HeelHeight au lieu de −90 fixe, déclenchement et valeur écrite (2026-10-20)
Décision citée par la fiche : l'utilisateur a répondu « approuvé » à la recommandation de Big Boss : « corriger M-Z dès la build 1, pour qu'il vise −90 + 12 × la hauteur des talons au lieu de −90 fixe ». La fiche ne donne ni la session ni l'heure (`sk-protocol` § 2) : je la traite comme une consigne de fiche et n'en tire aucune autre décision.
Hors gabarit : les deux compilations, `CopieEtat`, la preuve de présence dans les binaires, `PubCheck` et le tableau de comportement attendu 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 (commandes de build, 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`, fonction `ULPDirectControlSubsystem::FitPersonBounds`, bloc M-Z `:1241-1272` (établi, `Read` et `Grep` après édition).
| Mesure | Valeur | Commande |
|---|---|---|
| MD5 avant (exigé `687c63d8`) | `687c63d85395888b8a334cb537c16a53`, conforme ; identique à l'instantané | `certutil -hashfile Source/LifePlay/LPDirectControlSubsystem.cpp MD5` avant l'édition ; colonne MD5 de `D:\Game\LifePlay_Backup_5.5\FIX1-MZ2\manifest.csv` |
| MD5 après | `86ef519e880989941e033edeadda7c26` (inchangé après les deux builds) | `certutil -hashfile …` après l'édition, puis après les builds |
| Taille avant, après | 64 858 o, 65 503 o | manifeste de l'instantané ; `ls -l` |
| Fins de ligne | `i/crlf w/crlf attr/-text` ; 1824 CR = 1824 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` |
| Diff contre l'instantané | 9 lignes retirées, 15 ajoutées | `diff <instantané> <fichier> \| grep -c '^<'` puis `'^>'` |
| Diff contre HEAD (cumulé avec FIX1-MZ, non commité) | `1 file changed, 59 insertions(+), 6 deletions(-)` | `git diff --stat -- Source/LifePlay/LPDirectControlSubsystem.cpp` |
Une seule édition (outil Edit, sans script). Le premier essai a échoué (un tabulateur de trop sur chaque ligne, aucune écriture), repris avec l'indentation vérifiée par Grep (`^\t{2}// M-Z`, `^\t{4}Body->SetRelativeLocation`).
```diff
--- D:/Game/LifePlay_Backup_5.5/FIX1-MZ2/Source/LifePlay/LPDirectControlSubsystem.cpp
+++ Source/LifePlay/LPDirectControlSubsystem.cpp
@@ -1239,28 +1239,34 @@
MeasuredSeats.Remove(Person);
}
// M-Z (STG-COMMUN9-DIAG) : une place feminine releve le maillage (-80,4 au lieu de -90) et rien ne le redescend au lever ; la
- // Person debout flotte. Debout (aucun meuble), hors sexe et hors scene, capsule en collision, maillage hors de la hauteur relative
- // du gabarit de sa classe (CDO) depuis 2 balayages (1 s) : on remet la hauteur du gabarit (X et Y inchanges).
+ // Person debout flotte. Debout (aucun meuble), hors sexe et hors scene, capsule en collision, maillage hors de sa hauteur relative
+ // cible depuis 2 balayages (1 s) : on remet cette hauteur (X et Y inchanges).
+ // FIX1-MZ2 : la cible est -90 + 12 x HeelHeight (Person::updateHeelHeight, L6f_dump_Person.txt:19818-19827), pas le -90 seul : en
+ // talons (-80,4 pour 0,8) le maillage est deja a sa hauteur voulue et M-Z ne se declenche plus. HeelHeight illisible ou non
+ // fini : la cible reste la hauteur relative du gabarit de la classe (CDO), comme avant.
const ACharacter* Template = Person->GetClass()->GetDefaultObject<ACharacter>();
const USkeletalMeshComponent* TemplateBody = Template ? Template->GetMesh() : nullptr;
const UCapsuleComponent* Capsule = Person->GetCapsuleComponent();
const double TemplateZ = TemplateBody ? TemplateBody->GetRelativeLocation().Z : 0.0;
+ double HeelHeight = 0.0;
+ const bool bHeelRead = MZReadNumber(Person, TEXT("HeelHeight"), HeelHeight) && FMath::IsFinite(HeelHeight);
+ const double TargetZ = bHeelRead ? MZHeelBaseZ + MZHeelFactor * HeelHeight : TemplateZ;
+ // "(talons)" seulement si la cible vient de talons reels (HeelHeight non nul) : sans talons la ligne reste celle d'avant.
+ const bool bHeelTarget = bHeelRead && !FMath::IsNearlyZero(HeelHeight);
const FVector Relative = Body->GetRelativeLocation();
if (TemplateBody && !bSceneRunning && !IsValid(Seat) && Capsule && Capsule->GetCollisionEnabled() != ECollisionEnabled::NoCollision
- && FMath::Abs(Relative.Z - TemplateZ) > 1.0)
+ && FMath::Abs(Relative.Z - TargetZ) > 1.0)
{
int32& Scans = MeshZScans.FindOrAdd(Person);
if (++Scans >= 2)
{
- Body->SetRelativeLocation(FVector(Relative.X, Relative.Y, TemplateZ));
+ Body->SetRelativeLocation(FVector(Relative.X, Relative.Y, TargetZ));
MeshZScans.Remove(Person);
- // 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);
+ // FIX1-MZ : champs de diagnostic (F8b), lus apres la correction. "?" = variable introuvable.
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(),
+ UE_LOG(LogLifePlay, Display, TEXT("M-Z : %s maillage relatif Z %.1f -> %.1f%s (gabarit %s), debout sans meuble ; HeelHeight=%s ; currentAnimation=%s ; -90+12*HeelHeight=%s"),
+ *Person->GetName(), Relative.Z, TargetZ, bHeelTarget ? TEXT(" (talons)") : TEXT(""), *Person->GetClass()->GetName(),
*HeelText, *MZReadObjectName(Person, TEXT("currentAnimation")), *HeelZText);
}
}
```
**Logique des balayages relue en entier** (`:1157-1163` nettoyage de `MeshZScans`, `:1164-1165` `bSceneRunning`, `:1166-1174` filtre des `Person_C` visibles, `:1241-1275` bloc M-Z) :
- Le compteur `MeshZScans` monte d'un cran à chaque balayage où la condition tient et retombe (`else` → `MeshZScans.Remove(Person)`, `:1273-1275`) dès qu'un balayage ne la remplit plus : un personnage à sa cible n'accumule donc rien. La condition d'entrée comparait `Relative.Z` à `TemplateZ` (tolérance 1,0 cm) : c'est cette comparaison qui rendait M-Z actif sur un joueur en talons à −80,4. Elle compare maintenant à `TargetZ`, **même tolérance** (`> 1.0`). La valeur écrite (`SetRelativeLocation`) et la valeur affichée après `->` sont la même `TargetZ`.
- `TemplateBody` reste dans la condition (inchangé) ; `TemplateZ` ne sert plus qu'au repli (HeelHeight illisible) et n'est plus affiché (`(gabarit %s)` donne toujours la classe).
- `HeelHeight` est lu **à chaque balayage et pour chaque `Person_C` visible** (et non plus seulement à l'émission du journal) : un `FindPropertyByName` par personne et par balayage, comme `OccupyingFnt` juste au-dessus (`:1225`). Coût négligeable ; mesure de temps de trame non faite.
**Texte exact de la ligne de journal** (catégorie `LogLifePlay`, niveau `Display`) :
```
M-Z : <acteur> maillage relatif Z <Z avant> -> <cible>[ (talons)] (gabarit <classe>), debout sans meuble ; HeelHeight=<h> ; currentAnimation=<nom> ; -90+12*HeelHeight=<z>
```
- `<cible>` : `%.1f`, la valeur écrite (`−90 + 12 × h` si `h` est lisible, sinon le Z du gabarit). ` (talons)` n'apparaît que si `h` est lisible **et non nul** ; sans talons la ligne est octet pour octet celle de FIX1-MZ.
- Regex à jour (remplace celle de `FIX1-MZ-IMPL.md:98`) : `M-Z : .* maillage relatif Z (-?[0-9.]+) -> (-?[0-9.]+)( \(talons\))? \(gabarit (\S+)\), debout sans meuble ; HeelHeight=(\S+) ; currentAnimation=(\S+) ; -90\+12\*HeelHeight=(\S+)`. Le préfixe `M-Z :` est inchangé. Aucun consommateur de la ligne dans `Tools` (Grep `M-Z` sur `D:\Game\LifePlay-master 5.8\Tools` au lot FIX1-MZ : aucun résultat ; non rejoué ici).
APIs moteur nouvelles, lues dans UE 5.8.3 : `FMath::IsFinite(double)` — `GenericPlatformMath.h:587`, surcharge Windows `MicrosoftPlatformMath.h:18` (`_finite`), appelée comme `FMath::IsFinite` à `UnrealMathUtility.h:439` ; `FMath::IsNearlyZero(double, double = UE_DOUBLE_SMALL_NUMBER)` — `UnrealMathUtility.h:418-421`, tolérance `1.e-8` (`:139`). Les autres appels (`FMath::Abs`, `SetRelativeLocation`, `MZReadNumber`) sont ceux d'avant. Le code de 5.5.4 n'a pas été relu (développement 5.5 arrêté, mémoire projet du 2026-10-12).
## 2. Écarts à la SPEC
La fiche tient lieu de SPEC. Écarts et choix :
1. **« (talons) » seulement pour des talons réels.** La fiche dit « si la cible vient de HeelHeight ». Une lecture littérale l'ajouterait à toute ligne dont `HeelHeight` est lisible, donc à toutes (la variable existe sur `Person_C`) y compris `HeelHeight=0.000`, ce qui ne distinguerait plus rien et changerait les lignes sans talons. J'ai retenu `bHeelRead && !IsNearlyZero(HeelHeight)`. Si l'ordonnateur veut la lecture littérale : remplacer `bHeelTarget` par `bHeelRead` (une ligne).
2. **Position de « (talons) »** : juste après la cible (`-> -80.4 (talons) (gabarit …)`), la fiche ne précise pas l'emplacement. La regex de `FIX1-MZ-IMPL.md:98` ne reconnaît plus ces lignes (champ optionnel ajouté, ci-dessus) ; aucun outil du dépôt ne la consomme.
3. **Cible à `HeelHeight = 0` = constante −90**, non le Z du gabarit : la fiche écrit « −90 + 12 × HeelHeight » et « le gabarit seulement si HeelHeight est illisible ». Pour `Person_C` les deux valent −90,0 : les 41 lignes `M-Z :` des journaux archivés de `D:\Game\LifePlay_Build_5.8_*` portent toutes `-> -90.0 (gabarit Person_C)` (Grep `M-Z : .*gabarit [A-Za-z_0-9]+` sur `D:\Game`, glob `LifePlay*.log` : 17 fichiers, aucune autre classe ni autre valeur). Une classe `Person_C*` à gabarit ≠ −90 donnerait une cible différente du gabarit pour `h = 0` ; **non observée**, estimé improbable.
4. **Garde `FMath::IsFinite(HeelHeight)`** ajoutée à la lecture : une valeur non finie compte comme « illisible » (cible = gabarit). Sans elle, `Abs(Z − NaN) > 1.0` est faux et M-Z se désactiverait en silence pour ce personnage. Cas non observé (`Conv_StringToDouble` donne 0 sur texte invalide, `L6f_dump_Person.txt:19774-19781`) ; la ligne affiche alors `HeelHeight=?` au lieu de `nan`.
5. **Aucun bornage** de `HeelHeight` (négatif, très grand) : la formule du Blueprint n'en a pas non plus (`L6f_dump_Person.txt:19818-19827`).
6. **Symétrie de la comparaison** : la valeur absolue écarte aussi une Person avec talons restée à −90, qui est maintenant **remontée** à −80,4 (ligne avec « (talons) »). C'est la conséquence directe de « la cible est −90 + 12 × HeelHeight » ; **aucun cas de ce genre** dans les 5 lignes COM22 (toutes à la valeur de la formule). Voir § 5, point 3.
7. **Instantané non refait** : `D:\Game\LifePlay_Backup_5.5\FIX1-MZ2\` existait déjà (voir § 3).
8. **`CopieEtat.ps1 -Lot FIX1` rend le code 1** (alerte GIT, deux fichiers modifiés non déclarés) : voir `## Constats`. Commande de la fiche, sans `-Assets`.
## 3. Instantané
- Lot `FIX1-MZ2`, dossier `D:\Game\LifePlay_Backup_5.5\FIX1-MZ2\` : créé avant ma fiche (par l'ordonnateur ; manifeste daté `2026-10-20T20:51:54`), contient `Source\LifePlay\LPDirectControlSubsystem.cpp` et `manifest.csv`.
- Manifeste (lu) : `"Source/LifePlay/LPDirectControlSubsystem.cpp","True","64858","687C63D85395888B8A334CB537C16A53","2026-10-20T20:51:54"`.
- Vérifié par `certutil -hashfile D:/Game/LifePlay_Backup_5.5/FIX1-MZ2/Source/LifePlay/LPDirectControlSubsystem.cpp MD5` = `687c63d85395888b8a334cb537c16a53` : la copie d'instantané est l'état de départ exact.
- Retour arrière (proposé, non lancé) : `Tools\Restore.ps1 -Lot FIX1-MZ2`, ou recopie de ce fichier.
## 4. Ce qui n'a pas été fait
- **Aucune exécution en jeu** : ni éditeur, ni paquet, ni séance. Le comportement décrit en § Constats « Comportement attendu » est **calculé** à partir des valeurs des journaux COM22, pas observé.
- **Aucun paquet** (`BuildDebug.ps1`, cuisson) : seuls `LifePlayEditor` et `LifePlay` Development ont été compilés dans `Binaries\Win64` de la copie. Le jeu COM22 de l'utilisateur tourne peut-être depuis une autre archive : non touché, non fermé (`UeState` : aucun processus Unreal dans cette copie).
- Pas de correctif Blueprint (`updateHeelHeight`, `unOccupyFnt`), pas de changement de la tolérance (1,0), du nombre de balayages (2), des conditions debout/scène/capsule.
- Pas d'essai de la branche `HeelHeight=?` ni de la garde `IsFinite` (aucune exécution).
- Pas de mesure du coût par trame de la lecture de `HeelHeight` à chaque balayage.
- Aucune commande git qui écrit.
## 5. Points à confirmer en VAL
1. La chaîne `%.1f%s (gabarit` et ` (talons)` est dans `Binaries\Win64\LifePlay.exe` et `UnrealEditor-LifePlay.dll`, et l'ancienne forme `%.1f (gabarit` n'y est plus (rejouer les recherches de `## Constats`).
2. **En jeu, talons** : joueur avec talons (`HeelHeight` > 0) qui s'assied puis se lève : aucune ligne `M-Z :` pour lui sur la fenêtre ; relevés `STATE PlayerCharacter … meshZ=` égaux à `−90 + 12 × HeelHeight` (−80,4 pour 0,8) avant et après le lever ; à l'écran, pieds sur le sol (capture de l'utilisateur, comme en COM22).
3. **En jeu, sans talons** : même séance sans talons ; `meshZ=-90.0`, **0** ligne `M-Z :` si MES.2 n'en avait pas ; si une ligne sort (cas −88,0 ou −80,4 sans talons), elle porte `-> -90.0 (gabarit Person_C)` **sans** « (talons) » et `HeelHeight=0.000`.
4. Toute ligne `M-Z : … (talons)` d'une séance : `<Z avant>` ≠ `<cible>` par construction ; relever `<Z avant>` : une valeur −90,0 avec talons dit qu'un chemin du Blueprint écrase le Z sans passer par `updateHeelHeight` (cas non vu en COM22) ; une valeur à −88,0 avec talons rouvre la question du chemin −88,0 (`FIX1-F7-PRE.md:170`).
5. Aucune ligne avec `HeelHeight=?` (variable introuvable ou non numérique).
6. Non-régression du déclenchement : après 2 balayages (≈ 1 s), même nombre de lignes `M-Z :` que dans les séances sans talons comparables.
7. Les builds comptent **20** lignes UBT `HyperAIStudio` pour `LifePlayEditor` et **0** pour `LifePlay` (`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` (porte aussi l'instrumentation FIX1-MZ, encore non commitée : `FIX1-MZ-IMPL.md`)
- `A Docs/Migration/etat/REL/FIX1/FIX1-MZ2-IMPL.md`
Ne pas inclure `Source/LifePlay/LPCameraModeSubsystem.cpp` (F8a). Les résumés de build `FIX1_Build_20261020-205618.txt` et `FIX1_Build_20261020-205639.txt` ne figurent pas dans `git status --short -- Docs/Migration/etat/REL/FIX1` (les `.txt` de ce dossier sont ignorés) : à 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
### Comportement attendu (calculé, non observé)
Source des valeurs : `D:\Game\LifePlay_Build_5.8_Development_COM22\Windows\LifePlay\Saved\Logs\LifePlay.log` lignes 2382, 4204, 5378, 13544, 13545 (Grep `M-Z : .*gabarit`) ; formule `L6f_dump_Person.txt:19818-19827` (si « Heels » dans l'inventaire : `Z = −90 + 12 × HeelHeight`, `:19804-19827` ; sinon `HeelHeight = 0` et Z = −90, `:19786-19790`, `:19828-19835`) ; la nouvelle condition `|Z − cible| > 1,0`.
| Cas | Z relatif | HeelHeight | Cible nouvelle | \|Z − cible\| | M-Z |
|---|---|---|---|---|---|
| COM22:2382 et :5378, joueur levé (`currentAnimation=-` puis `fnt_chair11-f-0-sit`) | −80,4 | 0,800 | −80,4 | 0 | ne se déclenche plus (avant : `-80.4 -> -90.0`, pieds enfoncés d'environ 9,6 cm) |
| COM22:13544, PNJ | −85,2 | 0,400 | −85,2 | 0 | ne se déclenche plus |
| COM22:4204 et :13545, PNJ | −80,4 | 0,800 | −80,4 | 0 | ne se déclenche plus |
| sans talons, debout normal | −90,0 | 0 | −90,0 | 0 | ne se déclenche pas (inchangé) |
| sans talons, siège féminin non redescendu | −80,4 | 0 | −90,0 | 9,6 | se déclenche comme avant : `-80.4 -> -90.0 (gabarit …)`, ligne identique à l'ancienne |
| sans talons, cas −88,0 (7 sur 18 de `FIX1-F7-PRE.md`, `HeelHeight` alors non journalisé) | −88,0 | supposé 0 | −90,0 | 2,0 | se déclenche comme avant |
| talons restés à −90 (non observé) | −90,0 | 0,800 | −80,4 | 9,6 | se déclenche : `-90.0 -> -80.4 (talons)` — comportement nouveau (écart 6) |
| `HeelHeight` illisible | z | ? | Z du gabarit | selon z | comme avant, ligne `HeelHeight=?` |
Estimé (calcul : −90 + 12 × 0,8 = −80,4 ; −90 + 12 × 0,4 = −85,2 ; les 5 lignes COM22 donnent `-90+12*HeelHeight=` égal à `<Z avant>` à 0,05 près). Preuve en jeu : § 5, points 2 à 4.
### Compilation (hors gabarit, deux relevés)
Trace : `D:\Game\LifePlay-master 5.8\Docs\Migration\etat\REL\FIX1\FIX1_Build_20261020-205618.txt` — Fiche FIX1-MZ2 — 2026-10-20 20:56
```
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" < /dev/null (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 editeur=0) ; une seule compilation à la fois ; machine calme (cpu=2 % au CopieEtat)
Attendu : code 0, 0 erreur, 0 avertissement du compilateur ; 20 lignes UBT HyperAIStudio (connues)
Obtenu : code=0 duree=12s erreurs=0 avertissements=0 autres=20 unites=1 ; unité LPDirectControlSubsystem.cpp ; DLL liée UnrealEditor-LifePlay.dll ; 4 actions (UBA local) ; journal Saved\Logs\portage\FIX1_Build_20261020-205618.log
Lecture : « Makefile : » vide dans le résumé (statut non relevé par Build.ps1) ; module modifié bien recompilé (unité + DLL) ; une seule unité (la précédente en comptait deux : Module.LifePlay.cpp n'a pas été regroupé cette fois) ; 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-205639.txt` — Fiche FIX1-MZ2 — 2026-10-20 20:56
```
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" < /dev/null
Environnement: identique ; lancé après la fin du premier build (UeState -Kind Editeur,Compilation : processus=0 editeur=0 compilation=0 avant lancement)
Attendu : code 0, 0 erreur, 0 avertissement ; 0 ligne UBT (cible jeu)
Obtenu : code=0 duree=23s erreurs=0 avertissements=0 autres=0 unites=1 ; unité LPDirectControlSubsystem.cpp [NoUba] ; « DLL liées : 0 » (cible monolithique) ; 3 actions ; journal Saved\Logs\portage\FIX1_Build_20261020-205639.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
```
Sortie de commande, binaires (`certutil -hashfile <fichier> MD5` et `ls -l --time-style=full-iso`) :
```
Binaries/Win64/LifePlay.exe 335850496 o 2026-10-20 20:57:01 MD5 963927f34716cc1ee278d94f3eff8334
Binaries/Win64/UnrealEditor-LifePlay.dll 1996800 o 2026-10-20 20:56:29 MD5 596d9e75f4cab01d351e419f5a078939
```
(références FIX1-MZ : `LifePlay.exe` e2ba7dec63d479974394e2cffd1efc19, DLL 68aee3039e0a320a4a085db1aa6e6018). Le fichier `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-MZ2 — 2026-10-20 ~20:58
```
Commande : grep -a -c -P '<motif UTF-16LE>' <binaire>, trois motifs : ' (talons)' ; '%.1f (gabarit' (ancienne forme) ; '%.1f%s (gabarit' (nouvelle forme) ; octets séparés par \x00, depuis D:\Game\LifePlay-master 5.8
Environnement: Binaries\Win64\LifePlay.exe et UnrealEditor-LifePlay.dll ci-dessus
Attendu : ' (talons)' ≥ 1, ancienne forme 0, nouvelle forme ≥ 1 dans chaque binaire
Obtenu : LifePlay.exe : 1 / 0 / 1 ; UnrealEditor-LifePlay.dll : 1 / 0 / 1
Lecture : `grep -c` compte des « lignes » binaires, pas des occurrences ; exception à la règle « Grep, pas grep » (l'outil Grep ne cherche pas d'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=10 head=ad3c9c6/30beef0/c8661cd verrou=248:libre cpu=2% 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 (et FIX1-MZ), `LPCameraModeSubsystem.cpp` vient de F8a. 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 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-MZ-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.
### À verser
`aucun` skill à modifier. Observation : `Build.ps1` a groupé 2 unités au premier build de FIX1-MZ (`Module.LifePlay.cpp` en plus) et 1 seule ici ; le critère « module modifié recompilé » reste l'unité `LPDirectControlSubsystem.cpp` plus la DLL liée.