# PROP-CART — Diagnostic technique (dumps / graphes) **Fiche :** PROP-T1 **Date :** 2026-10-08 **Workspace :** `d:\Game\LifePlay-master 5.5` **Statut :** Correctif C++ compilé (`LPPersonPropGuardSubsystem`) — **PIE à valider** **Fiche bug (symptôme, repro, cause, acceptation) :** [PROP-BUG.md](PROP-BUG.md) — **ERR-043** Complément dumps pour le bug « seul le verre reste apparent ». --- ## 1. Contexte PIE (preuves journal) Source : `Saved/Logs/LifePlay.log` (session PIE 2026-10-07 → 08). | Observation | Détail | |---|---| | Premier `No SkeletalMesh` CharacterMesh0 | Ligne ~5331, `22.39.21` — **21 083** warnings dans la session | | Déclencheur immédiat | `GI` : `test0204 DestroyDummies` puis `test0304 DESTROY…` (Jared / Jack / Stephanie / Isaac) | | Acteurs concernés | `Person_C_0` … `Person_C_5` (pool dummies) | | Corrélation approche | Juste avant : `customer_approaches.lpscene`, `pub___vin01`, spam ERR-008 `WidgetComponents` length 0 (atténué CHG-243) | | ERR-011 | `GetSocketInfoByName … No SkeletalMesh` déjà **accepté** comme bruit (existe en 4.27) — ici le volume explose au `DestroyDummies` | Chaîne typique : ``` DestroyDummies → destroyDummy(Person) → SetActorHiddenInGame(true) → ResetVars() ← appelé ; graphe Person introuvable au dump (voir §3) → transform origine → unOccupyFnt → (PAS de clearProps) → CharacterMesh0 sans SkeletalMesh → sockets head/pelvis/… en échec → StaticMesh props (verre) encore présents / visibles ``` --- ## 2. Inventaire des dumps `LPDumpFunction` (lot PROP) Commande type : ```powershell .\Tools\RunCommandlet.ps1 -Lot PROP -Commandlet LPDumpFunction ` -Args '-BP=Person -Fn=spawnProp -Pins' -ProjectRoot 'd:\Game\LifePlay-master 5.5' ``` Moteur : `D:\Game\Launcher\Engine\UE_5.5\Engine`. Journaux bruts : `Saved/Logs/portage/PROP_LPDumpFunction_.log`. Résumés : `Docs/Migration/etat/PROP/PROP_LPDumpFunction_.txt`. | Horodatage | Cible | Exit | Résultat | |---|---|---:|---| | `20261008-010449` | `Person` / `spawnProp` | 0 | 9 nœuds — voir §3.1 | | `20261008-010554` | `Person` / `clearProps` | 0 | 17 nœuds — voir §3.2 | | `20261008-010647` | `GI` / `destroyDummy` | 0 | 39 nœuds — voir §3.3 | | `20261008-010803` | `Person` / `ResetVars` | **1** | Fonction **introuvable** dans `Person` (appelée pourtant par `destroyDummy`) | | `20261008-010919` | `Person` (liste) | 0 | **134** graphes — `spawnProp`, `clearProps`, `ClearSMCs` présents ; **aucun** `ResetVars` / `PlayDaily` | | `20261008-011027` | `Person` / `ClearSMCs` | 0 | 9 nœuds — voir §3.4 | | `20261008-011115` | `Person` / `PlayDaily` | **1** | Fonction introuvable (appel GI EventGraph vers `Person_C::PlayDaily` ailleurs) | Dump antérieur utile (hors lot PROP) : | Fichier | Usage | |---|---| | `Docs/Migration/etat/DOC-MOD_LPDumpFunction_20261007-083554.txt` | `GI` EventGraph : appels `destroyDummy`, un appel `Person_C::clearProps` (ligne ~26340, autre chemin — pas dans `destroyDummy`) | --- ## 3. Synthèse des graphes ### 3.1 `Person::spawnProp` (9 nœuds) 1. `AddComponent` template `NODE_AddStaticMeshComponent-0` 2. `K2_AttachToComponent(Parent = Person.Mesh, SocketName)` — KeepRelative 3. `SetStaticMesh(SM)` 4. `Array_Add` → variable **`Props`** 5. `SetCollisionEnabled(NoCollision)` Le verre (`drinkglass_prop`, etc.) est donc un **composant** du Person, attaché au skeletal mesh, référencé dans `Props` — pas un acteur séparé. ### 3.2 `Person::clearProps` (17 nœuds) - Boucle sur `Props` : `SetVisibility(false)` + `K2_DestroyComponent` + `SetStaticMesh(None)` - `Array_Clear(Props)` - Puis `Mesh->GetChildrenComponents` → cast `StaticMeshComponent` → même nettoyage **Cette fonction nettoie correctement les verres.** Elle n’est **pas** appelée par `destroyDummy`. ### 3.3 `GI::destroyDummy` (39 nœuds) — trou critique Ordre utile : | Étape | Appel | Effet | |---|---|---| | 1 | `Array_RemoveItem(DummyPersonsInUse)` | retire du pool « en service » | | 2 | garde `isPlayer` | — | | 3 | **`SetActorHiddenInGame(true)`** | cache l’acteur | | 4 | **`Person::ResetVars()`** | dump Person : **fonction absente de la liste** | | 5 | `SetActorTransform(0,0,0)` | téléporte à l’origine | | 6 | `removeAlreadyGot` / `PersonsUsedThisScene` | cleanup mappings | | 7 | `unOccupyFnt` | libère le meuble | | 8 | `PrintString("test0304 DESTROY…")` | log observé en PIE | | — | **`clearProps`** | **ABSENT** | Conséquence : quand le skeletal mesh est vidé (ResetVars / recyclage) ou l’acteur caché de façon incomplète côté composants dynamiques, les SMC de `Props` (verre) restent le seul rendu apparent. ### 3.4 `Person::ClearSMCs` (9 nœuds) `GetChildrenComponents(Mesh, bIncludeAllDescendants=true)` → détruit les enfants dont le **nom se termine par `SM`**. Complément éventuel à `clearProps`, **pas** branché dans `destroyDummy` non plus. ### 3.5 Liste `Person` (134 graphes) — extraits props / pose Présents : `spawnProp`, `clearProps`, `ClearSMCs`, `UpdateDailyPose`, `PlayIdle`, `HideSlot`, `unOccupyFnt`, … Absents au dump : `ResetVars`, `PlayDaily` (alors que GI les référence) — piste dette de nom / parent / graphe non listé ; à ne pas confondre avec un échec de compilation (le jeu tourne et imprime `DESTROY`). --- ## 4. Hypothèses retenues | # | Hypothèse | Statut | |---|---|---| | H1 | `destroyDummy` sans `clearProps` → verre orphelin au recycle dummy | **retenue** (dump + log) | | H2 | Mesh `CharacterMesh0` nul → corps invisible, prop SMC encore là | **retenue** (21k warnings au DESTROY) | | H3 | ERR-008 MapMarkers cause la disparition du corps | **écartée** comme cause directe (corrélée à l’approche ; garde CHG-243). Confirmation [Investigate MapMarkers approach](8d7f20d3-0709-4655-bea7-b82196a94500) : `FocusOnMapMarkers` lit `WidgetComponents[0]` sans Length ; `HideAllMarkers` ne clear pas `Vector2Ds` (déjà compensé par la garde). Même chemin approche → `updateAllPersonButtons` → `SpawnMapMarkers`, mais `Person.updateButtonSize` ne masque que **`ButtonSM`** (bouton nom), pas le skeletal mesh ni les props `spawnProp`. | | H4 | Verre flottant PNJ **encore visible** (barmaid + carnet) = prop d’anim précédente (`drinkglass`) non clear avant `write` / socket perdu après glitch mesh | **plausible** — garde orphelines (socket invalide / parent ≠ Mesh) | | H5 | Matériaux verre opaques blancs (étagères) | **hors périmètre** PROP (qualité / translucency) | | H6 | « Disparition » perçue à l’approche = seul `ButtonSM` qui se cache | **partielle** — explique un clignotement UI, pas le verre orphelin ni `No SkeletalMesh` au `DestroyDummies` | --- ## 5. Correctif (CHG-244) `Source/LifePlay/LPPersonPropGuardSubsystem.h/.cpp` — compile `LifePlayEditor` Win64 Development **PASS** (2026-10-08) : - Tick ~0,2 s, acteurs `Person_C` du GI courant - Si `IsHidden()` **ou** `Mesh` sans `SkeletalMeshAsset` → `ProcessEvent(clearProps)` + purge C++ du tableau `Props` + enfants SMC dont le nom contient `NODE_AddStaticMeshComponent` uniquement (évite de casser les SMC vêtements `*SM`) - Sinon : retire les props orphelines (parent ≠ Mesh, ou socket None / inexistant — cas verre collé à l’origine du mesh) Aucun Blueprint modifié. **Validation PIE :** relancer l’éditeur (nouvelle DLL), entrer dans un pub, forcer un recycle dummies / changer de lieu ; chercher `PersonPropGuard :` dans le log ; plus de verre flottant après DESTROY. --- ## 6. Index des artefacts | Artefact | Chemin | |---|---| | Fiche bug ERR-043 | `Docs/Migration/etat/PROP/PROP-BUG.md` | | Résumés dumps | `Docs/Migration/etat/PROP/PROP_LPDumpFunction_*.txt` | | Logs commandlets | `Saved/Logs/portage/PROP_LPDumpFunction_*.log` | | PIE session | `Saved/Logs/LifePlay.log` | | Captures utilisateur | workspace Cursor `assets/…image-d4b12d9d…png`, `…image-c2441b41…png` | | Garde MapMarkers | CHG-243 / `LPMapMarkersGuardSubsystem` | | Assets props | `Content/Heavy/New3/Anims/Daily/Props/drinkglass_prop.uasset`, anims `drinkglass_F/M` |