96 lines
9.7 KiB
Markdown
96 lines
9.7 KiB
Markdown
|
|
# Fiche STG-C1 — Niveau N3 — Modèle prévu claude-opus-5-5 | utilisé claude-opus-5-5
|
|||
|
|
|
|||
|
|
CART de **B-CHEV** (personnages qui se chevauchent ; exigence de l'utilisateur : deux personnages occupent deux espaces
|
|||
|
|
distincts, séparés d'au moins 10 cm). Lot STG, registre `STG-TACHES.md`. Lecture seule, sans copie UE.
|
|||
|
|
Date : 2026-10-13. Copie : `D:\Game\LifePlay-master 5.8`, branche `ue5.8`, HEAD `0745917`.
|
|||
|
|
|
|||
|
|
## 1. Sources lues (aucune nouvelle extraction)
|
|||
|
|
|
|||
|
|
| Repère | Fichier | Contenu |
|
|||
|
|
|---|---|---|
|
|||
|
|
| ROOM | `etat/anim/AP5/AP5_LPDumpFunction_20261006-134746.txt` | toutes les fonctions de `Room` (5.8, avant CAM) : `getStandSpots`, `FilterTooHigh`, `MoveAllToCenterRoom`, `RelocateOccupiers` |
|
|||
|
|
| ROOM-EG | `etat/ST/STE/dumps/Room__EventGraph_V5.txt` | appels `getStandSpots` (`AfterLoadRoom`, minuterie 1 s), `standIdle(Distance=250)` à l'arrivée d'un PNJ |
|
|||
|
|
| SI | `etat/ST/STA/dumps/Person__standIdle.txt` | `Person::standIdle` (avant CHG-284 / STB-PEA, qui n'a ajouté que deux gardes `IsValid` / `IsValidIndex`) |
|
|||
|
|
| PEG | `etat/ST/STE/dumps/Person__EventGraph_D4.txt` | événements `moveTo`, `moveToPersonStand`, `StartCheckMove`, `CompleteCurrentMovement` |
|
|||
|
|
| GI55 | `etat/portage55/L6f/L6f_dump_GI.txt` | `GI::removeTooClose`, `GI::toggleGravity` (5.5) |
|
|||
|
|
| P55 | `etat/portage55/L6f/L6f_dump_Person.txt` | `standIdle` 5.5 : mêmes constantes (50, 250, -1, 100-500, 2) |
|
|||
|
|
| COMP | `etat/CAM/CAM-T4_LPDumpComponents_20261011-004910.txt` | composants de `Person` : capsule, mouvement |
|
|||
|
|
| CFG | `Config/DefaultEngine.ini` l. 56-68 | `RecastNavMesh` |
|
|||
|
|
| SCN | `Content/Modules/**/*.lpscene` | appels `moveToPersonStand(…, d)` |
|
|||
|
|
|
|||
|
|
## 2. Mécanisme (établi dans les graphes)
|
|||
|
|
|
|||
|
|
1. **Emplacements debout** : `Room::getStandSpots` (ROOM), appelé par `AfterLoadRoom` 1 s après le chargement du lieu
|
|||
|
|
(ROOM-EG l. 3923-3940). Il vide `Standspots` **et** `Standspots_Occupied`, puis tire `trunc(échelle X × 30)` points
|
|||
|
|
au hasard sur le navmesh (`LPNavigationHelpers::GetRandomLocationInNavigableRadius`) autour du centre de
|
|||
|
|
`StaticMeshComponent`, rayon = **min**(demi-largeur X, demi-largeur Y) de la pièce (`Wall2`, `Wall4`) ; puis
|
|||
|
|
`FilterTooHigh` (garde les points à ±20 cm de la médiane des Z), puis `GI.removeTooClose(Distance = 40)`.
|
|||
|
|
2. **`removeTooClose`** (GI55) compare les points par `EqualEqual_Vector2DVector2D` avec `ErrorTolerance = Distance` :
|
|||
|
|
tolérance **par composante** (carré de 40 cm de côté), pas une distance. Deux emplacements gardés ont donc leurs centres
|
|||
|
|
à **≥ 40 cm** sur un axe au moins.
|
|||
|
|
3. **Capsule** (COMP l. 1767-1769, 1881) : rayon **20**, demi-hauteur 88 ; profil `Custom` : **Pawn = Ignore**,
|
|||
|
|
WorldStatic = Ignore, Visibility = Ignore. Les personnages ne se repoussent jamais ; aucun évitement (pas de RVO
|
|||
|
|
réglé ; journal U7 : `LogCrowdFollowing: Unable to find RecastNavMesh instance … UCrowdManager`). Navmesh : rayon
|
|||
|
|
d'agent **13** (CFG l. 59), inférieur au rayon de capsule.
|
|||
|
|
4. **Choix d'un emplacement** : `Person::standIdle(Near, Distance, NearStatic)` (SI), appelé par `PlayIdle(250)`, par
|
|||
|
|
l'arrivée d'un PNJ (ROOM-EG l. 4274) et par `moveToPersonStand` quand `Distance = 250`. Il parcourt `Standspots`,
|
|||
|
|
saute ceux dont `Standspots_Occupied[i]` est valide, prend le premier libre à moins de `clamp(Distance, 100, 500) + 2i`
|
|||
|
|
de `Near` (ou le premier libre sans `Near`), l'inscrit dans `Standspots_Occupied`, puis `moveTo(Dest)`.
|
|||
|
|
5. **Déplacement** : `moveTo` (PEG l. 12622) → `AIController::MoveToLocation` (rayon d'acceptation 100, ou 0 si précis) ;
|
|||
|
|
échec → `SetActorLocation(currentDestination)` sans balayage ; à l'arrivée, `StartCheckMove` (0,5 s) →
|
|||
|
|
`CompleteCurrentMovement` → `SetActorLocation(currentDestination)` sans balayage (PEG l. 13176, nœud 487).
|
|||
|
|
|
|||
|
|
## 3. Causes de chevauchement (une par ligne ; niveau de preuve)
|
|||
|
|
|
|||
|
|
| # | Cause | Preuve | Niveau |
|
|||
|
|
|---|---|---|---|
|
|||
|
|
| K1 | Espacement des emplacements : centres à 40 cm, capsules de 20 cm de rayon → **0 cm** entre capsules ; épaules et bras du maillage Daz plus larges que la capsule | ROOM `getStandSpots` (`Distance = '40.000000'`), GI55 `removeTooClose`, COMP | établi (graphe) ; recouvrement visible estimé (largeur d'épaules non mesurée) |
|
|||
|
|
| K2 | **Repli sans emplacement libre** : boucle terminée sans emplacement → `Dest` = centre de `Room.StaticMeshComponent` + Z 50 (SI, nœuds `_17`→`_22`→`VariableSet_3`) ; `Array_Find` rend -1 → aucune inscription → **tous** les personnages en repli vont au même point | SI | établi (graphe) |
|
|||
|
|
| K3 | Pièce étroite : rayon = **min** des demi-côtés → en street (échelle 3,5 × 18, `street___vin01.lpworld` l. 1) les emplacements tiennent dans un disque de la largeur de la rue, au milieu ; peu d'emplacements → K2 plus fréquent, et la foule se concentre | ROOM `getStandSpots` (`MinOfFloatArray`) | établi (graphe) ; nombre d'emplacements en street non mesuré |
|
|||
|
|
| K4 | `getStandSpots` vide `Standspots_Occupied` à chaque chargement : un personnage resté debout n'est plus inscrit → son emplacement peut être redonné | ROOM `getStandSpots` (`Array_Clear` ×2) | établi (graphe) ; ordre réel avec `RelocateOccupiers` non mesuré |
|
|||
|
|
| K5 | `moveToPersonStand(P, d)` avec `d ≠ 250` : destination = position de P ± d sur X **ou** Y (au hasard), sans contrôle des emplacements ni des tiers ; scènes des modules (`grep -rhoiE "moveToPersonStand\([^)]*\)" --include=*.lpscene Content/Modules`) : `d` = 50 (36 appels), 100 (59), 200 (1), sans distance (10) | PEG l. 15266-15561 ; SCN | établi (graphe) ; recouvrement avec un tiers estimé |
|
|||
|
|
| K6 | `standIdle(Distance = -1)` (précis) : garde la position courante, sans inscription | SI (`EqualEqual 250/-1`) | établi ; appelants non comptés |
|
|||
|
|
| K7 | En marche, les capsules se traversent (Pawn Ignore, pas d'évitement) : chevauchement **transitoire** | COMP, PEG | établi |
|
|||
|
|
|
|||
|
|
Hors défaut (par conception) : `GI::toggleGravity` met les capsules des `SexPersons` en `NoCollision` (GI55) ; scènes de
|
|||
|
|
couple, meuble partagé et `Dummy` se recouvrent volontairement. À faire confirmer (Q-STG-1).
|
|||
|
|
|
|||
|
|
Origine : constantes et graphes identiques en 5.5 (P55, GI55) → **préexistant**, au moins en 5.5 (estimé : 4.27 de même
|
|||
|
|
auteur). Aucun lien avec la migration 5.8.
|
|||
|
|
|
|||
|
|
## 4. Assets et nœuds en jeu
|
|||
|
|
|
|||
|
|
- `Content/BPs/Room.uasset` : `getStandSpots` (`K2Node_CallFunction_11.Distance = 40`, `K2Node_CallFunction_2` min,
|
|||
|
|
`K2Node_CommutativeAssociativeBinaryOperator_1` × 30) — **réservé par CAM** (modifié, non commité, B2 en cours).
|
|||
|
|
- `Content/BPs/Person.uasset` : `standIdle` (repli `_3` / `_17` / `_19` / `_22`), `EventGraph` `moveToPersonStand`
|
|||
|
|
(`K2Node_CallFunction_664` = 250, `_531`), capsule (CDO).
|
|||
|
|
- `Content/BPs/GI.uasset` : `removeTooClose` (fonction partagée ; STE-H3e la lit).
|
|||
|
|
- `Source/LifePlay` : aucun code de placement ; `LPDebugSubsystem` (commandes console non-Shipping) peut porter une mesure.
|
|||
|
|
|
|||
|
|
## 5. Options de correction (coût, risque)
|
|||
|
|
|
|||
|
|
| Option | Geste | Coût | Risque / effet de bord |
|
|||
|
|
|---|---|---|---|
|
|||
|
|
| C-O1 | `getStandSpots` : `removeTooClose` 40 → **70** (centres ≥ 70 cm → 30 cm entre capsules, ≥ 10 cm entre corps au repos, estimé) | 1 valeur de broche (Room) | moins d'emplacements → K2 plus fréquent : à coupler avec C-O2 / C-O3 ; attend la fin de CAM sur Room |
|
|||
|
|
| C-O2 | `standIdle`, repli : au lieu du centre + 50, point du navmesh à ≥ 70 cm de tout personnage visible (`GI.DummyPersonsInUse` + `PlayerCharacter`), sinon position courante | ≈ 20-30 nœuds (Person) | moyen ; corrige aussi la hauteur du repli (B-SOL, H-SOL2) |
|
|||
|
|
| C-O3 | `getStandSpots` : rayon = demi-diagonale ou max, et tirages × 2 | 2-4 nœuds (Room) | faible ; plus d'emplacements en rue étroite |
|
|||
|
|
| C-O4 | `moveToPersonStand` : passer par `standIdle(Near = P, Distance = d)` pour toute distance (condition `== 250` levée) | 1 lien (Person) | change la mise en scène des scènes (face à face à 50 / 100 cm exact perdu) ; contrat des scènes non touché |
|
|||
|
|
| C-O5 | Garde C++ (sous-système d'instance de jeu, sans asset) : toutes les 0,5 s, personnages au repos visibles (hors `SexPersons`, `OccupyingFnt`, masqués, en marche) à moins de 70 cm → le dernier arrivé va au point libre du navmesh le plus proche, `currentDestination` mis à jour par réflexion (méthode `LPOutdoorRoomSubsystem`) | ≈ 150-200 lignes + build | moyen (petit saut visible) ; couvre K1-K6 et les scènes des mods ; indépendant de CAM et de STE |
|
|||
|
|
| C-O6 | Capsule `Pawn = Block` + évitement RVO | 2 propriétés (Person CDO) | **élevé** (scènes, meubles partagés, poussées) : déconseillé |
|
|||
|
|
| M1 | Mesure : commande console non-Shipping `LifePlay.PersonsDump` (`LPDebugSubsystem`) : par personnage position, capsule, plancher, et **distance 2D minimale entre deux personnages** → critère objectif des 10 cm | ≈ 100 lignes + build + 5 min de jeu | nul en Shipping ; sert aussi B-SOL (STG-C2) |
|
|||
|
|
|
|||
|
|
Recommandation de l'orchestrateur (décision à l'utilisateur) : **M1 + C-O1 + C-O3 + C-O2** (Blueprint, après le commit de
|
|||
|
|
CAM sur Room) ; **C-O5** si Room reste réservée trop près du 2026-10-18. Critère de VAL proposé : `PersonsDump` en street
|
|||
|
|
et dans 2 intérieurs, distance minimale entre personnages au repos hors scène ≥ 2 × 20 + 10 cm, plus contrôle visuel.
|
|||
|
|
|
|||
|
|
## 6. Questions pour l'utilisateur (par Big Boss)
|
|||
|
|
|
|||
|
|
- **Q-STG-1** : la règle des 10 cm vaut-elle pour les personnages au repos et debout hors scène seulement (proposé), ou
|
|||
|
|
aussi en marche (K7) et dans les scènes (couple, meuble partagé) ?
|
|||
|
|
- **Q-STG-2** : voie Blueprint (C-O1 + C-O3 + C-O2, Room après CAM, Person) ou garde C++ (C-O5, sans asset) ?
|
|||
|
|
|
|||
|
|
## 7. Fichiers à commiter
|
|||
|
|
|
|||
|
|
`Docs/Migration/etat/ST/STG/STG-TACHES.md`, `Docs/Migration/etat/ST/STG/STG-C1-CART.md`,
|
|||
|
|
`Docs/Migration/etat/ST/STG/STG-C2-CART.md` (ticket au gardien à la clôture de la CART, sur accord de Big Boss).
|