LifePlay-Revival/Docs/21_Sandbox_Addon.md
edujiro5972 8084622450 LifePlay UE 5.8 : état de développement au 2026-10-19
Tickets : REP1-T4

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 22:57:42 +02:00

253 lines
45 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 21. Migration sandbox → addon éditeur (lots S0 à S8 clos, CHG-220 ; pin et registre des reports tenus à jour)
**Objectif :** extraire le code de sandbox Pair / Interaction / Mesure (aujourd'hui dans `Source/LifePlay/` et
`Source/LifePlayEditorTools/`, en grande partie non suivi par git) vers un **plugin éditeur** dédié, sans casser le
jeu empaqueté ni la chaîne d'animations (`20_Chaine_Animations.md`). Le module `LifePlay` ne garde que le contrat
minimal vers le jeu (dont `LPShowCoupleSubsystem`).
**Amont :** lot S0 validé (`S0-VAL.md` : PASS). Inventaire gelé : `Docs/Migration/etat/sandbox/S0/S0-CART.md`.
---
## Périmètre S0 (fichiers gelés)
Liste figée au 2026-10-06 ; toute évolution ultérieure passe par une fiche de lot et une entrée `CHG`.
### Runtime (`Source/LifePlay/`)
| Chemin | LOC approx. | Notes |
|---|---:|---|
| `LPPairSandbox.h` | 322 | Stage / Character / GameMode Pair |
| `LPPairSandbox.cpp` | 4261 | Monolith Pair, interaction, mesure |
| ~~`LPInteractionSandbox.*`~~ | — | **Retiré S4-T3** (addon) ; Interaction via menu `LPPairSandbox` |
| `LPPoseMeasure.h` | 100 | API mesure |
| `LPPoseMeasure.cpp` | 1558 | Sample / Transfer / T-fit |
| `LPSkeletonProfile.h` | 38 | Profils JSON |
| `LPSkeletonProfile.cpp` | 157 | |
| `LPPoseOrchestrator.h` | 30 | |
| `LPPoseOrchestrator.cpp` | 487 | |
| `LPAnimRedirect.h` | 15 | Cible `sandbox` \| `game` |
| `LPAnimRedirect.cpp` | 24 | |
| `LPShowCoupleSubsystem.h` | 77 | **Reste dans LifePlay** (sync lot S5) |
| `LPShowCoupleSubsystem.cpp` | 1048 | |
### Éditeur (`Source/LifePlayEditorTools/`)
| Chemin | LOC approx. | Notes |
|---|---:|---|
| `LPPairCollisionTestCommandlet.*` | ~546 | PairCol headless |
| `LPAnimEvalCommandlet.*` | ~489 | Mesure headless |
| `LPAnimCatalogCommandlet.*` | ~388 | |
| `LPAnimChecks.*` | ~435 | |
| `LPAnimTwistCommandlet.*` | ~384 | |
### Lanceurs (`Tools/debug/`)
| Chemin | Notes |
|---|---|
| `LifePlay_pair_sandbox.bat` | Pair |
| `LifePlay_interaction_sandbox.bat` | Interaction |
| `LifePlay_measure_sandbox.bat` | Mesure |
**Synthèse S0-CART :** ~7,5 k LOC runtime sandbox + mesure ; trois lanceurs désormais versionnables (motif
`.gitignore` : `/Debug/`).
---
## Contrat (S1 : configuration des chemins)
Le lot S1 fixe le premier contrat jeu ↔ addon : **tous les chemins d'assets et de fichiers du sandbox Pair passent par
`Config/LPSandbox.ini`**, lu par un point d'accès unique. Détail : `etat/sandbox/S1/S1-SPEC.md` ; implémentation
`S1-IMPL.md` ; audit `S1-CART.md` ; validation `S1-VAL.md` (PASS statique ; compilation et runtime à confirmer).
- **Fichier** : `Config/LPSandbox.ini` (versionné, pas dans `Saved/` ; depuis DC3 il vit dans l'addon, avec sa section `[Workshop]` `GameRoot`), lecture directe non hiérarchique (`FConfigFile::Read`).
- **API** : `struct LIFEPLAY_API FLPSandboxConfig` (`Source/LifePlay/LPSandboxConfig.h/.cpp`), `static const FLPSandboxConfig& Get()`, chargé une fois. `LPPairSandbox.cpp` et `LPAnimRedirect::ClipPath` n'utilisent plus de littéral `/Game/...`.
- **Repli** : fichier, clé ou valeur vide absents => default = littéral historique (comportement identique sans ini). Un asset introuvable garde le journal `LogLifePlay` d'origine, sans repli silencieux.
- **19 clés, 6 sections** : `Sandbox.Mode` (`Mode` = `Pair` | `Interaction` | `Mesure`, `Saved/sandbox_mode.txt` reste prioritaire) ; `Sandbox.Assets` (`PersonBP`, `BridgetMesh`, `MichaelMesh`, `QuaterniusMannequinMesh`, `DazIdleFemale`, `DazIdleMale`, `FurnitureWallMaterial`) ; `Sandbox.Roots` (`FurnitureRoot`, `DazAnimRoot`, `QuaterniusRoot`, `QuaterniusUALRoot`) ; `Sandbox.Content`, chemins relatifs à `Content/` (`ModuleRoot`, `WorldFile`, `ChatAction`, `QuaterniusUALDisk`) ; `Sandbox.Sky` (`SkyCubemap`, `SkyIntensity`) ; `Sandbox.Output`, relatif à `Saved/` (`MeasureOutputRoot`).
- **Conventions** : asset = chemin UE complet `/Game/...Nom.Nom` (`LoadObject`) ; racine = package sans nom d'asset ; disque = relatif à `ProjectContentDir()` (ou `ProjectSavedDir()` pour `Output`).
- **Hors contrat (volontaire)** : `LPKeyboard.ini`, `Saved/sandbox_mode.txt` / `sandbox_tour.txt`, littéraux `/Engine/...`, noms de clips et poses (`Idle_Loop`, `Walk_Loop`, `A_TPose`, `B_`/`M_`), liste `Names[]`.
- **Reste ouvert (lots suivants)** : points d'accroche ShowCouple (S5) ; staging de `LPSandbox.ini` si le sandbox doit tourner empaqueté. (Dépendances `Build.cs` et répartition des exports : traitées en S2, section suivante.)
---
## Module `LPAnimMeasure` (S2 : extraction de la chaîne de mesure)
Le lot S2 sort la chaîne de mesure de `LifePlay` vers un module Runtime dédié, `Source/LPAnimMeasure/` (structure plate, comme `LifePlay`). Détail : `etat/sandbox/S2/S2-CART.md` (cartographie), `S2-IMPL-H.md` (implémentation), `S2-VAL.md` (validation : PASS statique et runtime Mesure).
- **Contenu** : `LPPoseMeasure`, `LPSkeletonProfile`, `LPPoseOrchestrator`, `LPAnimRedirect` (8 fichiers déplacés) + `LPAnimMeasure.Build.cs`, `LPAnimMeasure.h/.cpp` (catégorie de journal `LogLPAnimMeasure`, ex-`LogLifePlay` pour les lignes `POSET` / `PROFIL` / `ORCH` / `MESURE`).
- **Exports** : `LPANIMMEASURE_API` remplace `LIFEPLAY_API` ; 6 symboles ajoutés pour `LPPairSandbox.cpp` (`KeyBones`, `LogReport`, `TFitReport`, `Run`, `Restore`, `SampleAt`) ; les structs de données restent header-only.
- **Rupture du couplage** : `LPAnimRedirect` ne lit plus `LPSandboxConfig`. l'addon (`LPSandbox.cpp:17`) appelle `LPAnimRedirect::SetUALRoot(FLPSandboxConfig::Get().QuaterniusUALRoot)` (`FLifePlayModule::StartupModule()` ne l'appelle plus) ; depuis DC1, `LPAnimRedirect` et `LPCoupleSim` sont dans le plugin du jeu `Plugins/LPAnimCore` ; défaut interne `/Game/Quaternius/UAL` (identique à celui de la config).
- **Déclaration** : entrée `Runtime` / `Default` dans `LifePlay.uproject`, placée avant `LifePlay` ; `ExtraModuleNames` des deux `*.Target.cs`.
### Graphe de dépendances des modules
```mermaid
flowchart LR
LPET["LifePlayEditorTools<br/>(Editor)"] -->|Public| LP["LifePlay<br/>(Runtime, module primaire)"]
MT["LPModTools<br/>(Editor, addon, DC2)"] -->|Public| AM["LPAnimMeasure<br/>(Runtime, nouveau S2)"]
LP -->|Public<br/>LPPairSandbox, LPDirectControl| AM
LP -->|Public DC1| AC["LPAnimCore<br/>(plugin du jeu : LPAnimRedirect, LPCoupleSim)"]
AM -->|Private DC1| AC
SB["LPSandbox<br/>(addon)"] -->|DC1| AM
SB -->|DC1| AC
SB -.->|"LPSandbox.cpp:17 : SetUALRoot(QuaterniusUALRoot)"| AC
AM -->|Public| ENG["Core, CoreUObject, Engine"]
AM -->|Private| JSON["Json"]
```
Règles : `LPAnimMeasure` ne dépend ni de `LifePlay` ni de `LifePlayEditorTools` (graphe acyclique) ; `LPSandboxConfig` reste dans `LifePlay` et pousse la configuration vers `LPAnimMeasure` par un setter, jamais l'inverse. Ordre de chargement `LPAnimMeasure` avant `LifePlay` : dépendance `Build.cs` et ordre du `.uproject`.
| De | Vers | Type | Motif |
|---|---|---|---|
| `LifePlay` | `LPAnimMeasure` | Public | `LPPairSandbox.h/.cpp`, `LPDirectControlSubsystem.cpp`, `LifePlay.cpp` |
| `LifePlay` | `LPAnimCore` | Public | DC1 : `LPAnimRedirect`, `LPCoupleSim` (plugin du jeu `Plugins/LPAnimCore`) |
| `LPAnimMeasure` | `LPAnimCore` | Private | DC1 : la mesure utilise `LPAnimRedirect` |
| `LPSandbox` | `LPAnimMeasure`, `LPAnimCore` | Public | DC1 : mesure et redirection / géométrie du couple |
| `LifePlayEditorTools` | `LifePlay` | Public | existant |
| `LPModTools` (Editor, addon) | `LPAnimMeasure` | Public | DC2 : `LPAnimChecks.h` expose `FLPPose` ; commandlets `LPAnimEval`, `LPAnimCatalog`, `LPAnimTwist`, `LPAnimIdentify`, `LPHairFromStaticMesh` (ex-`LifePlayEditorTools`, qui ne dépend plus de `LPAnimMeasure`) |
| `LPAnimMeasure` | `Core`, `CoreUObject`, `Engine` / `Json` | Public / Privé | animations, squelettes ; lecture de `Tools/anim/profiles/*.json` |
| `LPAnimMeasure` | `LifePlay`, `LifePlayEditorTools` | **aucune** | évite un cycle de modules |
---
## Stratégie git et liaison jeu ↔ addon (S3)
Le lot S3 déplace le code sandbox dans un dépôt séparé, `LifePlay-Sandbox` (https://github.com/edujiro5972/LifePlay-Sandbox.git, branche `main`). Détail : `etat/sandbox/S3/S3-INT.md` ; validation : `etat/sandbox/S3/S3-VAL.md` (PASS).
**Décision : deux dépôts siblings + `AdditionalPluginDirectories`. Pas de submodule imbriqué.**
```
D:\Game\
LifePlay-master 5.5\ <- jeu (repo LifePlay)
LifePlay-Sandbox\ <- addon (repo LifePlay-Sandbox)
```
- **Liaison** : `LifePlay.uproject` déclare `"AdditionalPluginDirectories": ["../LifePlay-Sandbox/Plugins"]` (chemin relatif au `.uproject`) et active `LPSandbox` dans `Plugins`. UBT et l'éditeur y trouvent `LPSandbox.uplugin` (modules `LPSandbox` et `LPAnimMeasure`) ; les DLL du plugin sont compilées avec le jeu (`Build.bat LifePlayEditor Win64 Development`).
- **Pourquoi pas un submodule** : l'addon est un `uproject` mince qui contient le plugin sous `Plugins/LPSandbox/`. Un submodule monté sur `Plugins/LPSandbox` du jeu donnerait `Plugins/LPSandbox/Plugins/LPSandbox/` (plugin imbriqué, non scanné au bon niveau) ; un submodule `External/LifePlay-Sandbox` dupliquerait l'addon à côté du sibling et rendrait ambigu l'exemplaire chargé. Un clone sibling évite les deux problèmes.
- **Pin** : le jeu consomme un commit précis de l'addon, consigné à la main ici depuis le lot U0 (`etat/` est local ; auparavant dans `S3-INT.md`) (aujourd'hui `f73e017db767ae663fc8e4ee066ac413c9c952be`, U3 règles de compilation et de validation, skill `lp-validate` ; précédents : `f0af432fd88965c92e3d01ddf2feb6194ce0adc4` U1 commandlet `LPAuditBlueprintCalls` dans `LPModTools` et skills `lp-*` des sous-agents, `79f0205b7281152dde7cd088086d8c813e0b20f5` DC3 atelier de mods (scripts, `ModSources`, `AnimSources`) dans l'addon, `97c0d134cd1388c3735add79d77ea98817e89fbe` DC2 module éditeur `LPModTools` et chemins propres à l'addon, `3e9c32f1f27b1abdaf7731dc90496c27ee061718` DC1 `LPAnimRedirect` et `LPCoupleSim` rapatriés dans le plugin `LPAnimCore` du jeu, `16905c68070992f5139dab907b41b461fb765957` SB4 ouverture par déclencheur éphémère non mémorisée, `3d858527fccfdddd8711c7c7448fa001442e0b8a` SB2-O1 correction de `ShowRoom`, `fece7e9a0e63b3058b5d24d96d669a3c9c0e9add` SB2 bibliothèques de scène et de personnages, caméra du socle, état des modes sorti vers les mods, `82dae58380b76c45f60541fd7cb5a0a409700e10` SB1 registre de mods et barre latérale, `3b21fd180c04f0fa49a1b5c9ef1b517ade1cb362` SB0 conception de la sandbox modulaire, `f09c42e5a2bc613cf269cce76c878461ca41c8b7` S7-T2 uplugin, `c1fdd29e2c1036c7d6365ba6389eff5d2f8c8c96` S5-T2 `LPCoupleSim`, `f8102647ccdebad37e4977ccbf2c51e583823a80`, S4-T3). Le pin est mis à jour (hash ici et dans le README de l'addon) à chaque évolution de l'addon que le jeu doit prendre. Reproduire :
```powershell
cd D:\Game
git clone https://github.com/edujiro5972/LifePlay-Sandbox.git
git -C LifePlay-Sandbox checkout f73e017db767ae663fc8e4ee066ac413c9c952be
# le jeu doit être cloné à côté : D:\Game\LifePlay-master 5.5
```
- **Copie 5.8 (lot U4)** : la copie `LifePlay-master 5.8` suit la branche `ue5.8` de l'addon, en worktree git `D:\Game\LifePlay-Sandbox-5.8` (créé depuis `f9033a1`) ; son `LifePlay.uproject` déclare `../LifePlay-Sandbox-5.8/Plugins`. Le checkout `D:\Game\LifePlay-Sandbox` reste sur la branche 5.5 pour le jeu 5.5. Pin de la copie 5.8 : `6377ce6` (branche `ue5.8`, REP1 : vague de reprise : skills et agents PIPE1, référentiel CGREF1, sources C++ et fiches SBXTYP, CHG-368 et CHG-369) ; précédents `67c2e64` (SBXTYP-R5), `8af9345` (SBXTYP-R4), `d0f3ff5` (SBXTYP-R3), `53517a9` (SBXTYP-R2), `5c5c038` (CGREF1-R1), `2986b37` (PIPE1-T1) ; précédent `63674ac` (SK : réunion des commits de skills depuis f0af432, même arbre que 132cfbf) ; `132cfbf`, `b25c253`, `96ce8cf` et les précédents suivants ne sont plus sur la branche `ue5.8` depuis la réunion SK du 2026-10-19 ; ils restent lisibles par le tag local `sauve/ue5.8-avant-SK` (ERR-139) ; ancienne chaîne : `132cfbf` (branche `ue5.8`, OPT0 : ordre d'un tour MCP dans `lp-mcp` § 2 et `lp-lot/boss.md` § 4, CHG-367) ; précédent `b25c253` (branche `ue5.8`, UES1 : recyclage du plugin Epic « Unreal Engine Skills » 3.1.1 (MIT) dans `lp-mcp` (avec `LICENSE` et `references/toolset.md`), `lp-commandlets`, `lp-doc`, `lp-validate`, `lp-build`, `lp-repo`, CHG-366) ; précédent `96ce8cf` (branche `ue5.8`, REF1 et OPT0 : paragraphe « Où écrire » dans `lp-doc` et `lp-lot`, recette PresentMon du banc P1, CHG-365) ; précédent `6ddf424` (branche `ue5.8`, NOM1 : `lp-doc` et `lp-lot` renvoient à la charte de nommage (doc 36), CHG-364) ; précédent `256794e` (branche `ue5.8`, OPT0 : skill `lp-perf` (recettes PresentMon, CSV Profiler, Gauntlet, Tracy) et agents `lp-perf` et `lp-refac`, CHG-363) ; précédent `4cdde5a` (branche `ue5.8`, AMEL1 : skills qui nomment les outils intégrés à `Tools/` (OUTIL1), CHG-362) ; précédent `d1c0a63` (branche `ue5.8`, AMEL1 : skills alignés sur `Tools/` local et non suivi, `sk-protocol` et `sk-repo` suivis, CHG-360) ; précédent `a84e48b` (branche `ue5.8`, AMEL1 : corrections de skills W3 et règle A5, CHG-358) ; précédent `082fb00` (branche `ue5.8`, AMEL1 : textes de skills issus de l'évaluation EVAL2 dans `lp-lot`, `lp-doc`, `lp-validate`, `lp-paths`, `lp-build`, ajout de `sk-windows-shell`, `sk-orchestrate` et de l'agent `lp-inventory`, CHG-350) ; précédent `5953696` (branche `ue5.8`, TRACE1 : règle des traces de session dans `lp-lot` (fichier `<LOT>-TRACES.csv` à la FIN-LOT), `lp-paths` (index et scripts, exception aux sauvegardes) et `lp-doc/gabarits.md` (résumé d'index), CHG-342 ; branche 5.5 non reportée) ; précédents `d2a67bd` PUB3 : `lp-repo` (garde-fou `pre-push`, ligne `PubCheck` du ticket, pièges), `lp-lot` (`PubCheck` avant ticket), `lp-paths` (tag `ue5.5-final` local, publication par `pub/ue5.8`), CHG-341 (branche 5.5 `6c04b51`, même contenu), `afe31e0` PUB3 : chemin du profil Windows remplacé par `%USERPROFILE%` dans `lp-doc`, CHG-340 (branche 5.5 `ffc0fe5`, même contenu), `4142939` P7 : leçons du lot « projet 7 » dans `lp-doc/gabarits.md`, `lp-lot`, `lp-validate` et `lp-ue-compat`, CHG-333 (branche 5.5 `87d3fe7`, même contenu), `5cc88c7` VERR1 : piège `New-Item` non atomique et règles du gardien (reprise du verrou, ticket `fait` sans commit, nom cherché jamais écrit) dans `lp-repo`, CHG-331 (branche 5.5 `662f81a`, même contenu), `22dd7c3` ARCH427 : `lp-paths` et `lp-env`, archive 4.27 remisée (branche 5.5 `083a3a0`, même contenu ; CHG de clôture d'ARCH427 à venir), `d77a0e2` ORGA1 : protocole Big Boss dans `lp-lot` (annexe `boss.md`), CHG-328 (branche 5.5 `32c7158`, même contenu), `3f94b5e` U8P : pièges de la reprise U8 dans `lp-build` (annexe `shipping.md`) et `lp-validate`, CHG-324 (branche 5.5 `29747a2`, même contenu), `9227db8` OBP : pièges P9 et P10 du lot OBB dans `lp-repo`, P10 dans `lp-validate`, P11 dans le gabarit TACHES de `lp-doc/gabarits.md`, CHG-312 (branche 5.5 `1334ac1`, même contenu), `3f73504` OBP : pièges Shipping / UAT du lot OBB dans `lp-build` (annexe `shipping.md`), CHG-310 (branche 5.5 `bb958b8`, même contenu), `247af5a` OBB : commandes git du dépôt Modules en `--git-dir`/`--work-tree`, `lp-paths` et `lp-repo`, CHG-304 (branche 5.5 `8b884a6`, même contenu), `8f6bc11` BUD1 : `lp-doc/gabarits.md`, budget de taille par niveau, CHG-295 (branche 5.5 `3d0cb95`), `4042315` EDIT3 : pièges U8 dans `lp-build` et `lp-validate`, CHG-293 (branche 5.5 `0d2f0d0`), `ec23fad` EDIT2 : `lp-doc/gabarits.md`, livrable écrit d'un seul Write par les agents sans Edit, CHG-277 (branche 5.5 `3ee14bc`), `1b766c2` TPL1 : skill `lp-doc`, gabarits à remplir et registre `<LOT>-TACHES.md`, CHG-274 (branche 5.5 `08d3c7c`), `aa0c1e5` EDIT1 et OUT1 : skills `lp-doc` et `lp-validate` (édition par l'outil Edit, CHG-267 ; `FileCheck.ps1`, CHG-264), `lp-build` et `lp-commandlets` (`8422fd6`, CHG-264), `1bcfe1b` ETAT2 : gabarits `etat` des skills et `SyncModSources.ps1`, `ce2e269` U7b : tournée Mesure hors écran, garde-fou `RetargetPack.py`, `d1efdd1` U7 : atelier 5.8, `EngineVersion`, guide, et `a19cedd` U4). La jonction `Content` du worktree pointe vers `LifePlay-master 5.8\Content`.
- **Content** : le jeu n'a rien à monter. L'addon utilisé seul (`LPSandbox.uproject`) a besoin du Content du jeu : junction NTFS `LifePlay-Sandbox\Content` → `LifePlay-master 5.5\Content` (`/Game` ne peut pointer que vers `<projet>/Content` ; la clé `AdditionalAssetDirectories` n'existe pas en UE 5.5). Voir le README de l'addon.
- **Contenu du jeu après S3-T3** : `Source/LPAnimMeasure/` et les fichiers `LPPairSandbox*`, `LPInteractionSandbox*`, `LPSandboxConfig*` ne sont plus dans le jeu. Le bat Pair lance toujours `LifePlay.uproject` avec `game=/Script/LPSandbox.LPPairSandboxGameMode`. `Source/LifePlay/LifePlay.Build.cs` dépend toujours de `LPAnimMeasure` (module désormais fourni par le plugin).
- **Validation S3-VAL** : bat Pair depuis le jeu, plugin monté et GameMode résolu sans erreur de module ; addon mince lancé avec le même GameMode (réserve : son `.uproject` n'active pas `StreetMap`, d'où des erreurs de chargement de Blueprints du jeu sans effet sur le sandbox).
---
## CoupleBox : `LPCoupleSim` partagé (S5)
Le lot S5 ferme la **dérive de fork** entre la sandbox (`LPSandbox/LPCoupleSim.cpp`, méthodes de `ALPPairSandboxStage`) et le jeu (`LPShowCoupleSubsystem`) : les deux gardaient une copie de la géométrie du couple (mesure de pose, boîte, balayage, soudure) qui divergeait (plancher −90 / −88, itérations 2 / 3, os exclus). Détail : `etat/sandbox/S5/S5-CART.md` (écarts), `S5-IMPL-H.md` (implémentation), `S5-VAL.md` (validation : PASS runtime Pair, PASS-STATIC ShowCouple). Addon pinné sur `c1fdd29`.
- **Où** : header `Plugins/LPSandbox/Source/LPAnimMeasure/LPCoupleSim.h` (215 l.) et `LPCoupleSimCore.cpp` (474 l.), module `LPAnimMeasure`, `namespace LPCoupleSim`, exports `LPANIMMEASURE_API`. Une seule copie : le jeu la voit par `LifePlay.Build.cs` (dépendance publique existante), sans recopie ni changement de `.Build.cs`. Le nom `LPCoupleSimCore.cpp` évite la collision avec `LPSandbox/LPCoupleSim.cpp`.
- **Trois niveaux d'API** :
- *pur* (sans `UObject` ni `UWorld`, testable sans monde) : `MeshToActor`, `ComposeComponentSpace`, `AccumulatePoints`, `IsExcludedLiveBone`, `FitFromAnimBounds`, `FitFromLiveBounds`, `SlideWish` ;
- *lecture* : `CapsuleHalfOf`, `AccumulateAnimBounds` (8 pas, os animés, `GetBoneTransform(raw=false)`), `AccumulateLiveBody` ;
- *effets de bord* : `EnsureBox`, `ApplyBoxFit`, `PlaceBodyMesh`, `SaveAndFreeze` / `RestoreMove` (`FSavedMove`), `AttachPartner`, `Unweld`, `ResolveCoupleMove`.
- **Paramètres** : `FBoxFitParams` (demi-capsule 88, pad anime 12/12/6 plafond 800, pad vivant 4/4/4 min 8 plafond 400, ancre pelvis 140, `FloorLocalZ`, `MinExtentZ` 20) ; `FSweepOptions::Show()` (3 itérations, `SweepMulti`, dépénétration, PNJ + coque `Wall*` ignorés) et `FSweepOptions::Sandbox()` (2 itérations, `SweepSingle`, arrêt net, marches, Z à plat). `ResolveCoupleMove` **ne déplace rien** : elle rend la position retenue (`FSweepResult`), chaque appelant l'applique.
- **Appelants** : sandbox `FitCoupleBox` / `Weld` / `MoveCouple` ; jeu `FitBox` / `FitToBodies` / `Weld` / `Engage` / `Release` / `KeepTogether`. Les copies `AddPose` (jeu), `Accumulate` (sandbox), les deux créations de `UBoxComponent` et les deux boucles de balayage n'existent plus (−336 lignes dupliquées, +689 dans le module partagé).
- **Écarts conservés volontairement** (options, pas de copies) : plancher sandbox −90 contre jeu −88 (`FloorLocalZ`), balayage simple 2 itérations contre multi 3 itérations, nom de composant `CoupleBox` contre `LPShowCoupleBox`. L'alignement du plancher est une ligne dans `FitCoupleBox`, à décider après capture en jeu.
- **Reste dans `LifePlay`** : sélection du couple (`SexPersons`, `AP1/AP2`, `ShowReach`), réflexion `GI` / `Room`, `IsBedMesh` (injecté via `IsWalkableSupport`), `IsUseFurniture`, `OpenUseFurniture`, `PairSibling` / `IsIdleClip`, `FlipResponse` / `RestoreResponses` (non partagés, hors S5-T2), CVar `lp.ShowCouple`.
- **Contrat de modification** : tout changement de géométrie du couple se fait dans `LPCoupleSim` (addon), puis bump du pin ; le jeu ne doit pas réintroduire de copie locale.
---
## Acceptation
État au 2026-10-06 (lot S8). Case cochée = prouvée par la fiche citée ; case vide = non faite.
- [x] **S0** : hygiène dépôt, inventaire gelé (`S0-VAL.md` PASS).
- [x] **S1** : tous les chemins du sandbox via `Config/LPSandbox.ini` (`S1-VAL.md` PASS statique).
- [x] **S2** : module `LPAnimMeasure` extrait, sans dépendance vers `LifePlay` (`S2-VAL.md` PASS).
- [x] **S3** : addon dans le dépôt `LifePlay-Sandbox`, liaison sibling + `AdditionalPluginDirectories`, pin manuel (`S3-VAL.md` PASS).
- [x] **S4** : sandbox Pair découpé, GameMode Interaction legacy retiré (`S4-VAL.md` PASS).
- [x] **S5** : géométrie du couple partagée via `LPCoupleSim`, une seule copie (`S5-VAL.md` PASS runtime Pair, PASS-STATIC ShowCouple).
- [x] **S6** : stack Mesure sur la liaison addon, `LPAnimEval` court (`S6-VAL.md` PASS).
- [x] **S7 / isolation** : plugin sans `include` / `LIFEPLAY_API` / module `LifePlay` ; `Person` = CDO seul, aucun `GI` / `Room` ; chemins par config (`S7-SPEC.md`, `S7-CART.md` : 0 écart).
- [x] **S7 / configurations** : `LPSandbox` hors Shipping (`TargetConfigurationDenyList`), `LPAnimMeasure` conservé, plugin `Optional` dans `LifePlay.uproject` (`S7-IMPL-L.md`).
- [x] **Smoke Pair** (bat court, plugin monté, boîte du couple identique à S5-VAL, 0 crash) (`S7-VAL.md`).
- [x] Commandlets anim restants (`LPAnimCatalog`, `LPAnimChecks`, `LPAnimTwist`) déplacés dans un module éditeur de l'addon : **fait au lot DC2** (module `LPModTools`, avec `LPAnimEval`, `LPAnimIdentify`, `LPAnimMethodSelect`, `LPHairFromStaticMesh`).
- [x] **S8** : bilan du mode multi-agents (`22_Eval_Agents_Sandbox.md` : GO conditionnel) ; code sandbox absent du module jeu depuis S3 ; smoke Pair par le `.bat` réel, boîte du couple identique à S5 / S7, 0 crash (`S8-VAL.md` PASS).
- [ ] `BuildMod.ps1 -Target sandbox -Open` rejoué sur la liaison addon : **non fait**.
- [ ] Compilation / packaging **Shipping** complets avec le plugin (seul le plan UBT est vérifié).
- [ ] Parcours Show complet en jeu et décision d'alignement du plancher (-90 / -88).
- [x] Commit addon `f09c42e` poussé vers `origin/main` (constaté en S8 : `origin/main` = `dae6206`, qui le contient).
- [ ] Migration commitée **côté jeu** (`LifePlay.uproject`, `Config/LPSandbox.ini`, `Build.cs`, `LPShowCoupleSubsystem.*`, docs `21` / `22`, `etat/sandbox/`) : **non fait** (`22` § 6).
- [x] **SB0** : conception de la sandbox modulaire (addon, pin `3b21fd1`, tag `lot-SB0-valide`).
- [x] **SB1** : registre de mods, barre latérale, 7 descripteurs `.lpmod`, modes Pair / Interaction / Mesure enveloppés en `lps_couple` / `lps_interaction` / `lps_asset_integration` (`etat/sandbox/SB1/SB1-VAL.md` PASS, contrôle visuel utilisateur 2026-10-07 ; tag `lot-SB1-valide`).
- [x] **SB2** : bibliothèques `lps_lib_scene` / `lps_lib_actors`, caméra du socle, état des modes sorti vers les mods `lps_couple` / `lps_interaction` / `lps_asset_integration` (`etat/sandbox/SB2/SB2-VAL.md` PASS, contrôle visuel utilisateur 2026-10-07 ; tag `lot-SB2-valide`).
- [x] Reports SB1 (registre unique, lot propriétaire **SB2**) : (traité) images de la tournée Mesure non déterministes : SB2-T5 compare les JSON/CSV (identiques) et les images visuellement ; (traité, SB4-T0, prouvé SB4-VAL F2) « Open réécrit » : chaque ouverture de mod réécrit `Open` dans `Saved/sandbox_mods.ini` (une tournée automatique laisse donc `Open=lps_asset_integration`). Corrigé : `Open(Id, Context, bRemember)`, une ouverture par `Saved/sandbox_mode.txt` n'est plus mémorisée.
- [x] **SB4** : validation finale (SB4-VAL PASS : démarrage, tournées Quaternius et FreeAnimationsPack identiques à SB2-REF, LPAnimEval identique, Open intact), doc 23 § 7 ; commit `16905c6` et tag `lot-SB4-valide` ; évaluation `etat/sandbox/SB4/SB4-EVAL.md` : GO transposition.
- [x] **G-SB3** : SB3 abandonné (décision utilisateur 2026-10-07). Motif : les mods du jeu sont du contenu (.lpmod + pak), leurs dépendances sont vérifiées par le registre (prouvé en SB1/SB2) ; coût ≈ 1 à 1,5 lot, et `LPAnimMeasure` est utilisé par le jeu en Shipping ; on passe à SB4.
- [x] **SB2-O1** : correction du défaut O1 (`etat/sandbox/SB2/SB2-O1-BUILD.md` PASS, contrôle visuel utilisateur 2026-10-07 ; tag `lot-SB2-O1-valide`).
- [x] Reports SB2 : (O1) traité (SB2-O1, `3d858527fccfdddd8711c7c7448fa001442e0b8a` : `ShowRoom` symétrique de `HideRoom`, contrôle visuel utilisateur 2026-10-07 « c'est bon ») ; (E3) sans `lps_lib_scene`, la pièce est construite quand même : non traité, séparation physique abandonnée à la porte G-SB3 (décision utilisateur 2026-10-07).
- [x] **DC0** : cartographie et SPEC du découplage jeu / sandbox (`etat/sandbox/DC0/DC0-SPEC.md`, approuvée par l'utilisateur 2026-10-07) ; plan `24_Plan_Decouplage_Sandbox.md`.
- [x] **DC1** : Plugin LPAnimCore dans le jeu, LPAnimMeasure réduit à la mesure (DC1-T1..T5) (DC1-VAL PASS, contrôle visuel utilisateur 2026-10-07 ; tag addon lot-DC1-valide).
- [x] **DC2** : Commandlets de mods vers un module éditeur de la sandbox (DC2-T1..T5) (DC2-VAL PASS ; tag addon lot-DC2-valide ; le jeu compile et démarre sans l'addon).
- [x] **DC3** : Scripts, données et sources de mods vers la sandbox (DC3-T1..T5) (DC3-VAL PASS ; tag addon lot-DC3-valide ; atelier de mods dans l'addon).
- [x] **DC4** : Preuve « jeu seul », docs, évaluation (DC4-T1..T4) (DC4-VAL PASS, test en jeu utilisateur 2026-10-07 ; évaluation DC4-EVAL : le jeu public compile et tourne sans l'addon).
- [ ] Intégration des déplacements dans le jeu à améliorer (remarque utilisateur au contrôle visuel DC1, 2026-10-07) ; lot propriétaire : à définir, hors DC.
- [x] Reports DC0 (lot propriétaire **DC1**, traité : texte corrigé en § Rupture du couplage) : § Rupture du couplage : la mention d'un appel à SetUALRoot par FLifePlayModule::StartupModule() est périmée ; seul l'addon l'appelle (LPSandbox.cpp:17, LPSandboxMeasure.cpp:39) — voir DC0-CART b2.
- [x] Report DC2 (traité en DC3 : `-Livraison=` obligatoire) : `LPAnimCatalog` ignore `-DryRun` et a des valeurs par défaut (pack quaternius) : lancé sans arguments, il réécrit `Saved/AnimPipeline/quaternius/fiches_calculees.json` (DC2-VAL anomalie 1) — lot propriétaire DC3.
- [x] Report DC2 (traité en DC4, `fbbcee1`) : `LifePlay.Build.cs` garde `Json` avec un commentaire AP1 périmé (plus aucun usage dans `LifePlay`) — lot propriétaire DC4.
- [x] Report DC2 (traité : documenté dans `09`/`18`) : sans addon, l'absence est silencieuse au runtime ; l'éditeur/UBT affiche `AdditionalPluginDirectory … not found` (avertissement, non bloquant) — pour information, DC4 docs.
- [x] Report DC3 (traité : documenté dans `09`/`18`) : après un test sans addon, UBT réutilise un `Makefile.bin` sans les modules de l'addon : le déplacer avant de recompiler (DC3-BUILD) — à écrire dans `09`/`18` — lot propriétaire DC4.
- [x] Numéros de docs en double : traité (DOCNUM, CHG-246) — `23_Video_Quality.md` → `25_Video_Quality.md`, `24_Eval_Agents_VideoQuality.md` → `26_Eval_Agents_VideoQuality.md` (ordre de création ; 23 et 24 inchangés).
- [x] Reports U4 faits (lot U4, CHG-254) : scripts de l'addon lisant le moteur par `Engine.ps1` (plus de `UE_5.5` en dur ; 0 référence 5.5 hors Docs et skills) ; C4996 StreetMap et outils sous garde de version ; `Makefile.bin` déplacé au retour de l'addon ; addon sur la branche `ue5.8` (worktree) ; contrôle R1 par la tournée Mesure (boîte du couple identique 5.5 / 5.8).
- [ ] Report U4 : correction de `LPSandbox.uproject` en 5.5 (`AdditionalPluginDirectories` désignant le dossier de LPAnimCore au lieu de son parent ; UBT ne lit que les sous-dossiers) — lot propriétaire : addon 5.5, hors U58 (branche `lot/DC3-atelier`).
- [x] Report U4 : capture des planches de la tournée Mesure indépendante de la fenêtre (assert D3D12 `D3D12Texture.cpp:1551` sous 5.8 en fenêtre minimisée) — lot propriétaire : **U7b** (requalifié de U7, décision de l'utilisateur 2026-10-09). Traité en U7b (CHG-259, ERR-050, ERR-051) : `AnimPipeline.ps1` lance la tournée avec `-RenderOffScreen -ExecCmds="r.SetRes 1600x900w"` (addon `ce2e269`) ; tournée freeanims : géométrie 20/20 lignes identiques à `U4-REF55`, JSON 10/10, dimensions 20/20, 0 assertion. Non mesuré : pixels, absence de fenêtre pendant toute la tournée, pilote complet rejoué de bout en bout.
- [x] Report U4 : `BuildMod.ps1`, `EditMod.ps1`, `HairPipeline.ps1` jamais exécutés en 5.8 (PASS-STATIC seulement, pas de mode à blanc) — lot propriétaire : **U7**. Traité en U7 (CHG-257) : chaîne complète rejouée en 5.8 sur le mod de test (NewMod → HairPipeline → EditMod → BuildMod, 6 paquets, 0 erreur), mod accepté en jeu (conteneur 5, registre 24, `EngineVersion` 5.8.3) ; recuisson des 3 mods d'assets par `BuildMod` (3 archives `*-1.0-for-LifePlay-2026.10.2.0.zip`, 70 / 84 / 20 paquets) ; VAL U7 PASS.
- [ ] Report U5 : `RetargetPack.py` (étape 4 de la chaîne d'animation) : `set_retarget_chain_settings` est sans effet en 5.8 (passer par l'op « FK Chains ») et le 9e argument de `duplicate_and_retarget` a changé (booléen → chemin) — lot propriétaire : **après V2.0** (atelier ; requalifié de U7b par la décision de l'utilisateur du 2026-10-09). Garde-fou en place (U7b, CHG-259, ERR-052) : le script refuse 5.6 et plus avant toute suppression ; **portage après V2.0** (troisième rupture relevée en U7b : un retargeter neuf n'a aucune op en 5.8), case laissée ouverte.
- [x] Report U5 : 28 avertissements « Ressource de la pose … n'est pas à jour » en 5.8 (`CompileAllBlueprints`, inchangés par le resave) — lot propriétaire : **U7b** (requalifié de U7, décision de l'utilisateur 2026-10-09 : 0 effet au journal du jeu en U6, poses de démo Manny / Quinn). Traité en U7b (CHG-259, ERR-053) : « Update Source » sur les 28 poses ; `CompileAllBlueprints` 56 lignes → 0 (418 BP, 0 erreur de compilation) ; 28/28 `_pose` changées, 28/28 `_anim` identiques. Les poses ne sont pas suivies par git (`.gitignore:59`) : filet = instantané `D:\Game\LifePlay_Backup_5.5\U7b`. Les mêmes avertissements existaient en 5.5.4 (défaut du pack, pas une régression 5.8).
- [ ] Report U5 : 210 acteurs externes orphelins dans `Content/__ExternalActors__` et `Content/__ExternalObjects__` (cartes ThirdPerson / Vehicle absentes), non resauvés ; retrait à décider — lot propriétaire : utilisateur, après V2.0.
- [x] Report U5 : NaN `FRotator::Quaternion` vu une fois au recalcul DDC de `/Game/Heavy/New3/Anims/DM_RazDog_0` (non reproduit) — lot propriétaire : **U6** (à surveiller). Non reproduit en jeu U6 : 0 occurrence au journal du jeu 5.5 et 5.8 (CHG-256).
- [ ] Report U6 : brouillard / scalabilité (Effects Low-Med, nouvelles clés de base 5.8) non comparés 5.5 contre 5.8, pas de captures même cadrage — lot propriétaire : **prochain cycle de livraison** (U8 clos sans publication, CHG-325 ; test Shipping). Avancement U8 (CHG-323) : reste ouverte ; T6 annulée, décision de l'utilisateur (2026-10-10, sans captures) ; rendu Low / Med jugé acceptable à l'œil sur 5.8 ; comparaison 5.5 impossible, la V1.5 n'a pas le réglage Effects (`U8-TACHES.md`, `U8-T6-VAL.md`).
- [x] Report U6 : 4 « Gamethread hitch waiting for resource cleanup » sur `MapMarkers_C.LPFocusWidgetComponent`, propres à 5.8 (absents du journal 5.5) — à surveiller : lot propriétaire **U8**. Mesure U8-T5c (CHG-276) : 2 hitchs (1,77 et 11,66 ms) contre 4 en U6 (max 6,07 ms), un parcours ; reste à surveiller (doc 29, STA). Traité au niveau **estimé** en U8 (CHG-323) : correctif CHG-292 (composant de focus retiré du code), 0 hitch et 0 ligne `MapMarkers` sur U8-T5cr et U8-T5cr2 ; carte ouverte et marqueurs survolés pendant T5cr2 sur déclaration de l'utilisateur (2026-10-11), aucune trace au journal (`U8-T5cr2-VAL.md`).
- [x] Report U6 : compilation sous UBA, erreurs internes non déterministes (C1001 / C2206) avec mémoire engagée élevée, contournement `-NoUBA` — à porter dans la skill `lp-build` (dépôt addon) : lot propriétaire **U7**. Traité en U7 (CHG-257) : règle `-NoUBA` (et « un build de test ne s'écrit jamais dans un dossier d'archive existant ») dans `lp-build`, addon `lot/DC3-atelier` `6295829`.
- [x] Report U6 : la copie d'une sauvegarde de test = `Saved\SaveGames` + `Content\Saves` (seuls les `.sav` copiés : `Player.lpcharacter` non chargé, menu d'actions absent) — à documenter avec le lot SAV1 / ERR-042 : lot propriétaire **U7**. Traité en U7 (CHG-257) : règle de copie de sauvegarde et contrôle d'une copie d'essai dans `lp-validate`, addon `lot/DC3-atelier` `6295829`. Le lot SAV1 lui-même (dossier de sauvegardes partagé, ERR-042) reste ouvert.
- [x] Report U6 : cuisson Shipping à froid (avertissement `LegacyIterative` requis, `bUseZenStore=False`) — lot propriétaire : **U8**. Traité en U8-T3 (CHG-276) : sans `-iterate`, le cuiseur écrit `FULL COOK … Deleting previously cooked packages … recooking all packages` (8 923 paquets, 0 erreur, 0 avertissement, 164 s, DDC gardée) ; l'avertissement ne vient que de `-iterate` (passé par `Tools/BuildDebug.ps1` et U7-T14) : tout build de référence ou de publication se cuit sans `-iterate`.
- [x] Report U7 : scripts écrivant à la racine de `etat/` (`RunCommandlet.ps1`, `ReimportCorrectif.ps1`, `AssetHeaders.ps1`, `Build.ps1` 5.8) et gabarits de skills : lot **ETAT2** (CHG-261). Preuve : `Tools/EtatDir.ps1` (jeu 5.5 `d4b3ea3`, jeu 5.8 `1d1d283` et `9184ecb`), gabarits de 5 skills (addon `e99e423`, `ue5.8` `1bcfe1b`) ; validations T3 (A2), T5 (A5), T7 (B2) PASS.
- [x] Report U7 : réorganisation de `etat/` de la copie 5.8 par projet : lot **ETAT2** (CHG-261). Preuve : 362 fichiers déplacés, MD5 362/362 identiques au manifeste `ETAT2-R8`, `MAPPING-58.csv` (SHA-256 `034341413821577408AAE04FD7480F69F66053E6B76BAF1A6E005796D0AB8E1E`), racine réduite à 3 fichiers ; les 2 fichiers STM sont dans `etat/ST/STM/`.
- [x] Report U7 : transfert scripté des `ModSources/*/Content` (ignorés par git, absents du worktree 5.8 de l'addon, ERR-046) : lot **ETAT2** (CHG-261). Preuve : `Tools/SyncModSources.ps1` de l'addon (`e99e423` sur `lot/DC3-atelier`, `1bcfe1b` sur `ue5.8`) ; T5 : essai à blanc 174 IDENTIQUE, essai réel 174 COPIE_OK, MD5 174/174 ; ERR-046 corrigé.
- [ ] Report U7 : lot MCP STM — lot propriétaire : après V2.0 (doc 29).
- [ ] Report U7 : liste des bugs non prioritaires (doc 29, § défauts connus), dont le message de `HairPipeline.ps1:215` (ERR-048), le faux positif « dependances A VERIFIER » de `HairMaterials.py` (ERR-049), la coiffure de mod gardée par un personnage après décochage et la mise en page du gestionnaire de mods — lot propriétaire : projet ST (doc 29).
- [ ] Report U7 : C3 (ordre d'affichage des mods par défaut), bouton du nom d'un mod refusé (un clic bascule encore la coche), libellé moteur (« format 4, game 5 » incompris) — décisions de l'utilisateur 2026-10-09 : non retenus en U7 — lot propriétaire : doc 29.
- [ ] Report U7 : personnages enfoncés dans la rue (défaut ancien, présent dans les builds 5.5, sans lien avec U7) — lot propriétaire : après V2.0 (doc 29), hors U58.
- [ ] Report U7 : plugin `McpAutomationBridge` — lot propriétaire : OB (doc 30).
- [ ] Report U7 : Shipping final et publication des 3 archives `2026.10.2.0` — lot propriétaire : **prochain cycle de livraison** (U8 clos sans publication, CHG-325 ; voir doc 27). Avancement U8 (CHG-323) : reste ouverte ; Shipping candidat U8r2 et archive de jeu `LifePlay_Revival_V2.0_Windows_Game.7z` préparés, 3 mods recuits ; publication à la porte T11.
- [x] Report U7 : archivage des PDB du Shipping (doc 27:300 ; règle doc 29 : un dossier de PDB par numéro de build, à côté de `Releases`) ; le build `D:\Game\LifePlay_Build_5.8_Shipping_V2.0` n'en contient aucun (`U8-T0-INV`, anomalie A2) : recompilation nécessaire — lot propriétaire : **U8** (fiche U8-T4). Avancement U8-T4 (CHG-276) : build d'essai non distribué `D:\Game\LifePlay_Build_5.8_Shipping_U8`, PDB dans le dossier voisin `…_Shipping_U8_PDB` avec `BUILD-ID.txt` (SHA-256 de l'exe, ligne RSDS) ; à refaire pour le build publié. Traité en U8 (CHG-323) : pour le build candidat, `D:\Game\LifePlay_Build_5.8_Shipping_U8r2_PDB` avec `BUILD-ID.txt` (`U8-T4r2-BUILD.md`).
- [x] Report U8 (U8-T5a, CHG-276) : le Shipping desktop est « installé » (moteur `App.cpp:218-219`) : `Saved` = `%LOCALAPPDATA%\LifePlay\Saved`, dossier commun avec les sauvegardes et `GameSettings.sav` des versions précédentes (le Development garde `Saved` dans son dossier) ; à décider avant la publication V2.0 (README, `-UserDir`, migration) — lot propriétaire : **U8** (T8 / porte), lien SAV1 / ERR-042. Traité en U8 (CHG-323) : décision D4 de l'utilisateur (2026-10-10), dossier laissé tel quel et écrit au README racine (`U8-T8b-DOC.md`) ; le lien SAV1 / ERR-042 reste porté par le lot SAV1.
- [x] Report U8 (constat OBA-T23, 2026-10-09) : l'addon privé finit dans le jeu 5.8 (exe Shipping lié à `LPAnimMeasure`, `RemappedPlugins/LPSandbox/LPSandbox.uplugin` au pak ; V1.5 : 0) — lot propriétaire : **U8-ADDON**. Traité (CHG-279, décision utilisateur « éditeur seulement ») : `LifePlay.uproject`, entrée `LPSandbox` + `"TargetAllowList": ["Editor"]` ; compilation Shipping code 0, `.rsp` de lien régénéré `LPAnimMeasure` 1 → 0 (`etat/U58/U8/U8-ADDON-T1-BUILD.md`) ; aucun des 9 070 `.uasset` / `.umap` de `Content` (suivis ou non) ne référence `/Script/LPSandbox`, `/Script/LPAnimMeasure`, `/Script/LPModTools` (`grep -rlF`, témoin `/Script/ModdingExtra` = 12). Reste à constater au prochain empaquetage : `LPSandbox` absent de `Manifest_UFSFiles_Win64.txt`.
- [x] Report U8 (constat OBA-T23, 2026-10-09) : `Content/Modules/.git` (431 Mo, 142 fichiers, historique complet) embarqué par la règle NonUFS `Modules` dans tous les builds 5.8 (`…_Shipping_V2.0`, `…_Shipping_U8`, `…_Development_U8`) ; V1.5 : 0 — décision utilisateur en attente (porte G-OB) ; lot propriétaire : OB, avant toute publication. Source corrigée : dépôts déplacés hors de l'arbre (`D:\Game\LifePlay_ModulesGit\<5.8 ou 5.5>.git`, OBB-T1, CHG-304 et CHG-307) et contrôle `Tools/CheckPackage.ps1` (CHG-301) ; reste la preuve dans un build neuf : OBB-T7. Preuve : Shipping 5.8 neuf `D:\Game\LifePlay_Build_5.8_Shipping_OBB2` (OBB-T7c), `Tools/CheckPackage.ps1` 4 PASS, 0 ligne `Modules/.git` au manifeste NonUFS, 1 573 286 287 o (U8 : 2 024 056 223), démarrage sans plantage (OBB-T7s, sur l'archive `…_Shipping_OBB`, exe identique) ; CHG-308.
- [x] Report U8 : référence `Releases/2026.10.2.0` (U7-T14) et 3 archives de mods `*-for-LifePlay-2026.10.2.0.zip` (U7-T15) produites sur un build avec addon et `.git` : à refaire sur un Shipping propre (après CHG-279 et la décision `.git`) — lot propriétaire : **U8** (reprise après G-ST et OB). Traité en U8 (CHG-323) : référence recréée sous le même numéro sur un Shipping propre (T3r2, `Releases/2026.10.2.0` de 5 fichiers, `.ucas` `f242facd…` = archive, `CheckPackage` 4 PASS) ; 3 mods recuits contre elle (T8a : 3 × `BuildMod` code 0, `MODULE_GAME_VERSION` 2026.10.2.0, 70 / 84 / 20 paquets, anciennes archives en `.precedent_*`). La preuve en jeu des mods recuits vaut avec le smoke T5ar2 (mods lus).
- [ ] Report U1 : `README.md:4` → mention UE 5.8 à la publication V2.0 (décision de l'utilisateur 2026-10-08, doc 27:200) — lot propriétaire : **prochain cycle de livraison** (U8 clos sans publication, CHG-325 ; fiche U8-T8). Avancement U8 (CHG-323) : README préparé (titre UE 5.8, statut V2.0, dossier `Saved`), non commité ; case cochée à la publication.
- [x] Report U7b : erreur HyperAIStudio au démarrage (`LogHyperAIStudioAutomation: Error … AutomationController is not loaded`, code de sortie 1 des commandlets alors que chaque commandlet finit en `result 0`) : correctif dans `LifePlayEditorTools` préparé par la session du lot 29, bloquant avant la cuisson U8 ; à appliquer avec l'accord de l'utilisateur — lot propriétaire : **STM / lot 29**, avant U8. Traité en STM (CHG-260, `cb6697a`, ERR-054 corrigé) ; case cochée en U8 (CHG-273, anomalie A1 de `U8-T0-INV`). Preuve : avant, `U7b_CompileAllBlueprints_20261009-140525.log` (2 lignes `LogHyperAIStudioAutomation: Error`, `Failure - 1 error(s)`, code de sortie 1 au résumé `etat/U58/U7b/`) ; après, même commandlet `STM-T4c_CompileAllBlueprints_20261009-162345.log` (HyperAIStudio monté l.367, `AutomationController` chargé l.1281 juste après `LifePlayEditorTools` l.1280, toolset `HyperAIStudioAutomation` enregistré l.1687, 0 ligne `LogHyperAIStudioAutomation: Error`, `Success - 0 error(s), 0 warning(s)`, code de sortie 0 au résumé `etat/ST/STM/`), de même `ETAT2_LPTestStringCompat_20261009-153349.log` et `OUT1_LPTestStringCompat_20261009-161745.log` (0 erreur, code 0). Non rejoué : preuve par l'échec plugin désactivé ; le correctif est à retirer quand le vendeur publiera une version corrigée (ERR-054).
- [ ] Report ETAT2 : `Tools/ReimportCorrectif.ps1:38` crée le dossier du lot avant le contrôle d'arbre propre (dossier vide laissé si refus) — lot propriétaire : **ST** (doc 29, liste des bugs non prioritaires).
- [ ] Report ETAT2 : `Tools/SyncModSources.ps1` R1 (erreur de paramètre : code de sortie 1) et R2 (exception en plein `-Apply` : pas de rapport CSV) — lot propriétaire : **ST** (doc 29, liste des bugs non prioritaires).
- [ ] Report ETAT2 : `Tools/Build.ps1` (copie 5.8) utilise `$etatDir` et `$EtatDir` pour la même variable (casse, sans effet) — lot propriétaire : **ST** (doc 29, liste des bugs non prioritaires).
- [ ] Report ETAT2 : `Resolve-LPEtatDir` (`Tools/EtatDir.ps1`) exige `-ProjectRoot` en appel direct — lot propriétaire : **ST** (doc 29, liste des bugs non prioritaires).
- [ ] Report ETAT2 : `Tools/Build.ps1:55` refuse de s'exécuter si un éditeur tourne dans N'IMPORTE QUELLE copie (et non dans la seule copie visée) — lot propriétaire : **ST** (doc 29, liste des bugs non prioritaires).
- [x] Report D6 : archivage 4.27 → traité en ARCH427 (CHG-332), avancé avant la publication V2.0 : dossiers 4.27 sous `D:\Game\LifePlay_Backup_5.5\ARCH427\`, moteur UE_4.27 gardé, branches `archive/*` en bundle.
- [ ] Report UES1-B2 : premier jeu d'outils MCP LifePlay en lecture (C++, `LifePlayEditorTools`), règles dans `lp-mcp/references/toolset.md` — lot propriétaire : lot à ouvrir.
- [ ] Report UES1-R9 : `lp-build` (161), `lp-validate` (145) et `lp-repo` (133) dépassent 120 lignes (SK-ARBRE R9), déjà avant le lot UES1 — lot propriétaire : lot à ouvrir.
## Lots (S0 … S8)
| Lot | Objet (une ligne) |
|---|---|
| **S0** | Hygiène dépôt : `/Debug/` dans `.gitignore`, lanceurs `Tools/debug` suivis, inventaire et preuves `etat/sandbox/S0/*`. |
| **S1** | Contrat jeu ↔ addon : API minimale, dépendances modules, règles de linking (placeholder ci-dessus). |
| **S2** | Extraction du module `LPAnimMeasure` (mesure, profils, orchestrateur, redirection) hors de `LifePlay` ; dépendances `Build.cs` et exports. **Fait** : `S2-VAL.md` PASS (voir section « Module `LPAnimMeasure` »). Le plugin éditeur (uplugin) reste à faire. |
| **S3** | Création du dépôt addon `LifePlay-Sandbox` (scaffold, transfert du code, retrait côté jeu) et liaison par clone sibling + `AdditionalPluginDirectories`, pin manuel. **Fait** : `S3-VAL.md` PASS (voir section « Stratégie git »). Rejeu stack Mesure : lot **S6** (`S6-VAL.md`). |
| **S4** | Sandbox Pair : découpage `LPPairSandbox`, retrait GM Interaction legacy (S4-T3 **fait**), commandlet `LPPairCollisionTest`, bat Pair. Validation : `S4-VAL.md` (PASS). |
| **S5** | ShowCouple : `LPShowCoupleSubsystem` reste dans `LifePlay` ; géométrie du couple partagée via `LPCoupleSim` (module `LPAnimMeasure` de l'addon, pin `c1fdd29`). **Fait** : `S5-VAL.md` PASS (runtime Pair, PASS-STATIC ShowCouple ; voir section « CoupleBox »). Show complet en jeu et alignement du plancher restent à valider. |
| **S6** | Stack Mesure sur la liaison addon : `LifePlayEditorTools` → `LPAnimMeasure` (plugin), lanceurs `Tools/debug`, sorties `Saved/Measurement`, commandlet `-run=LPAnimEval`. **Fait** : `S6-VAL.md` PASS (doc `20` / `09`, essai court LPAnimEval). |
| **S7** | Isolation du plugin (sans lien vers `LifePlay`, `Person` en CDO seul, config seulement), `LPSandbox` hors Shipping, `Optional` dans `LifePlay.uproject`. **Fait** : `S7-VAL.md` PASS (smoke Pair ; Shipping vérifié par plan UBT). Le déplacement des commandlets Catalog / Checks / Twist reste à planifier (voir § Acceptation). |
| **S8** | Bilan et clôture : évaluation du mode multi-agents + multi-modèles (`22_Eval_Agents_Sandbox.md`, GO conditionnel, 3 recommandations), smoke Pair final. **Fait** : `S8-VAL.md` PASS. `BuildMod -Target` et commit côté jeu restent ouverts (§ Acceptation). |
Chaque lot suit `10_Protocole_Operations.md` : instantané, entrée `CHG`, retour arrière documenté.