159 lines
8.1 KiB
Markdown
159 lines
8.1 KiB
Markdown
|
|
# 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_<stamp>.log`.
|
|||
|
|
Résumés : `Docs/Migration/etat/PROP/PROP_LPDumpFunction_<stamp>.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` |
|