Charge le plugin via AdditionalPluginDirectories, conserve ShowCouple et les commandlets anim côté jeu, et documente les lots S0–S8 (CHG-212 à CHG-220). Co-authored-by: Cursor <cursoragent@cursor.com>
9.4 KiB
9.4 KiB
S1-T1 — Contrat Config/LPSandbox.ini
Rôle : A-ARCH. Périmètre : spécification uniquement (aucun changement runtime dans cette fiche).
Source analysée : Source/LifePlay/LPPairSandbox.cpp (et .h, qui ne contient aucun littéral de chemin : seulement QuaterniusMesh / QuaterniusClips en FString, lignes 261-262) + Source/LifePlay/LPAnimRedirect.cpp:22 (helper ClipPath utilisé par le sandbox).
1. Décisions de contrat
| Décision | Choix |
|---|---|
| Emplacement | Config/LPSandbox.ini (projet, versionné). Pas Saved/. |
| Lecture (S2, hors périmètre ici) | FConfigFile::Read(FPaths::Combine(FPaths::ProjectConfigDir(), TEXT("LPSandbox.ini"))) — lecture directe, non hiérarchique (pas de DefaultLPSandbox.ini). |
| Fichier absent / clé absente | Repli sur le default = littéral actuel du code (colonne « default »). Le comportement actuel doit rester identique sans ini. |
| Section | Une section par thème : [Sandbox.Mode], [Sandbox.Assets], [Sandbox.Roots], [Sandbox.Content], [Sandbox.Sky], [Sandbox.Output]. |
| Convention de chemin asset | Chemin UE complet /Game/...Nom.Nom (format LoadObject), sauf mention « racine » (sans .Nom). |
| Convention de chemin disque | Relatif à FPaths::ProjectContentDir() / ProjectSavedDir() selon la clé (le préfixe est noté dans l'usage). |
| Hors contrat (volontairement) | Saved/Config/Windows/LPKeyboard.ini (config clavier utilisateur, reste en Saved), Saved/sandbox_mode.txt et Saved/sandbox_tour.txt (déclencheurs éphémères consommés au lancement), littéraux /Engine/... (Cube, BP_Sky_Sphere), noms de clips/poses (Idle_Loop, Walk_Loop, A_TPose, préfixes B_/M_), liste des 43 poses Names[] (l. ~3365-3376). |
2. Tableau des clés
Les clés notées * sont critiques (demandées par la fiche). Numéros de ligne = LPPairSandbox.cpp au moment de l'analyse.
| clé ini | section | valeur default | usage dans code | fichier:ligne |
|---|---|---|---|---|
PersonBP * |
Sandbox.Assets |
/Game/BPs/Person.Person_C |
LoadObject<UClass> : lecture des défauts de capsule (rayon, demi-hauteur) dans ALPPairSandboxStage::Build |
LPPairSandbox.cpp:844 |
PersonBP (même clé, 2e usage) |
Sandbox.Assets |
idem | LoadObject<UClass> : copie du profil/réponses de collision de la capsule dans ConfigureCapsule |
LPPairSandbox.cpp:1089 |
WorldFile * |
Sandbox.Content |
Modules/vin_Base/World/work___vin01.lpworld |
Fichier de la chambre (props + échelle) ; chemin = ProjectContentDir() + valeur ; passé à PairSandbox::LoadWorldFile |
LPPairSandbox.cpp:832 |
ModuleRoot * |
Sandbox.Content |
Modules/vin_Base |
Racine du scan récursif *.lpaction (catalogue d'actions Interaction) ; ProjectContentDir() + valeur |
LPPairSandbox.cpp:622 |
ChatAction |
Sandbox.Content |
Modules/vin_Base/Interactions/chat.lpaction |
Lecture de ACTION_NAME pour ChatLabel ; ProjectContentDir() + valeur |
LPPairSandbox.cpp:1045 |
FurnitureRoot * |
Sandbox.Roots |
/Game/Heavy/New2/Furniture |
Racine des meshes de meubles : "<racine>/%s.%s" avec Prop.Name issu du .lpworld |
LPPairSandbox.cpp:857 |
FurnitureWallMaterial |
Sandbox.Assets |
/Game/Heavy/New2/Furniture/Materials/FntWall.FntWall |
LoadObject<UMaterialInterface> : matériau des murs/coque de la chambre |
LPPairSandbox.cpp:877 |
DazAnimRoot * |
Sandbox.Roots |
/Game/Heavy/Daz/Anims |
Racine des clips Daz : paires "<racine>/%s%s.%s%s" (Pair + _F/_M) ; idles Daz |
LPPairSandbox.cpp:2610, 3106, 1078-1079 |
DazIdleFemale |
Sandbox.Assets |
/Game/Heavy/Daz/Anims/Idle_F_Daz.Idle_F_Daz |
PlayIdle(bFemale = true) |
LPPairSandbox.cpp:1078 |
DazIdleMale |
Sandbox.Assets |
/Game/Heavy/Daz/Anims/idle_Daz.idle_Daz |
PlayIdle(bFemale = false) |
LPPairSandbox.cpp:1079 |
BridgetMesh * |
Sandbox.Assets |
/Game/Heavy/Daz/Bridget/bridget_gp.bridget_gp |
Corps Bridget : ApplyBody("Bridget") et mode Mesure (Place("Bridget", …)) |
LPPairSandbox.cpp:3026, 1529 |
MichaelMesh * |
Sandbox.Assets |
/Game/Heavy/Daz/Michael/michael.michael |
Corps Michael : ApplyBody("Michael") |
LPPairSandbox.cpp:3030 |
QuaterniusRoot * |
Sandbox.Roots |
/Game/Quaternius |
ScanPathsSynchronous de l'Asset Registry avant détection du corps/clips |
LPPairSandbox.cpp:2962 |
QuaterniusUALRoot * |
Sandbox.Roots |
/Game/Quaternius/UAL |
GetAssetsByPath (détection auto du mesh le plus riche en bones + clips non B_/M_) ; sert aussi de base à LPAnimRedirect::ClipPath ("<racine>/%s.%s") |
LPPairSandbox.cpp:2964, LPAnimRedirect.cpp:22 |
QuaterniusUALDisk |
Sandbox.Content |
Quaternius/UAL |
Dossier disque scanné (*.uasset) pour lister les clips ayant une copie B_ (43 clips) ; ProjectContentDir() + valeur |
LPPairSandbox.cpp:1894 |
QuaterniusMannequinMesh |
Sandbox.Assets |
/Game/Quaternius/UAL/UAL1_Standard.UAL1_Standard |
Mannequin de référence en mode Mesure (Place("Mannequin", …)) |
LPPairSandbox.cpp:1528 |
Mode * |
Sandbox.Mode |
Pair |
Mode initial du menu. Valeurs : Pair, Interaction, Mesure (liste Modes, Modes[0] = Pair). Aujourd'hui seul Mesure est activable, via Saved/sandbox_mode.txt ; l'ini fournirait le mode persistant. Le .txt éphémère garde la priorité (compat) |
LPPairSandbox.cpp:3396-3399, 3907-3921 |
SkyCubemap * (opt.) |
Sandbox.Sky |
/Game/Heavy/New2/Buildings/Mats/urban_street_03_1k.urban_street_03_1k |
LoadObject<UTextureCube> pour SkyLight->SetCubemap (SkyLight SLS_SpecifiedCubemap) |
LPPairSandbox.cpp:1001 |
SkyIntensity (opt.) |
Sandbox.Sky |
0.6 |
SkyLight->SetIntensity(0.6f) |
LPPairSandbox.cpp:1000 |
MeasureOutputRoot |
Sandbox.Output |
Measurement |
Sous-dossier de ProjectSavedDir() pour shots, tour, vignettes, planches, retarget_pose_*.txt (les sous-noms restent en dur) |
LPPairSandbox.cpp:1687, 1862, 1873, 1885, 1930-1931 |
Notes
PersonBPn'a qu'une clé pour deux sites d'appel (844 et 1089) : en S2 un seul accesseur partagé.DazAnimRoot: les deux idles (DazIdleFemale/Male) sont des clés distinctes car leurs noms ne suivent pas le motif%s%s.%s%s(casse différenteIdle_F_Daz/idle_Daz) ; les valeurs par défaut sont donc les littéraux exacts, y compris la casse.Walk_Loop,Idle_Loop,A_TPose, préfixesB_/M_: conventions de nommage Quaternius/retarget, non exposées (hors contrat) ; seul leur dossier (QuaterniusUALRoot) l'est.- Les préfixes disque vs chemin UE (
Quaternius/UALvs/Game/Quaternius/UAL) sont deux clés séparées pour ne pas dériver un chemin de l'autre (l'actuel code les écrit indépendamment). - Packaging : un
Config/LPSandbox.inicustom n'est staged que s'il est listé (UFS/DirectoriesToAlwaysStageAsUFSou+DirectoriesToAlwaysStageAsNonUFS) ; le sandbox est un outil éditeur/dev, donc à traiter en S2 uniquement si le sandbox doit tourner packagé.
3. Contenu proposé de Config/LPSandbox.ini
Les valeurs ci-dessous sont identiques aux littéraux actuels : charger ce fichier ne doit rien changer au comportement.
; Config/LPSandbox.ini
; Contrat S1-T1 — chemins et options du bac a sable LPPairSandbox.
; Toute cle absente => valeur par defaut du code (identique a celle-ci).
; Chemins "/Game/..." : format LoadObject (/Package/Nom.Nom ou /Package/BP.BP_C).
; Chemins relatifs (sans "/") : relatifs a Content/ sauf [Sandbox.Output] (relatif a Saved/).
[Sandbox.Mode]
; Mode initial du menu : Pair | Interaction | Mesure
; (Saved/sandbox_mode.txt, s'il existe, reste prioritaire et est consomme.)
Mode=Pair
[Sandbox.Assets]
PersonBP=/Game/BPs/Person.Person_C
BridgetMesh=/Game/Heavy/Daz/Bridget/bridget_gp.bridget_gp
MichaelMesh=/Game/Heavy/Daz/Michael/michael.michael
QuaterniusMannequinMesh=/Game/Quaternius/UAL/UAL1_Standard.UAL1_Standard
DazIdleFemale=/Game/Heavy/Daz/Anims/Idle_F_Daz.Idle_F_Daz
DazIdleMale=/Game/Heavy/Daz/Anims/idle_Daz.idle_Daz
FurnitureWallMaterial=/Game/Heavy/New2/Furniture/Materials/FntWall.FntWall
[Sandbox.Roots]
; Racines de packages UE (sans nom d'asset final)
FurnitureRoot=/Game/Heavy/New2/Furniture
DazAnimRoot=/Game/Heavy/Daz/Anims
QuaterniusRoot=/Game/Quaternius
QuaterniusUALRoot=/Game/Quaternius/UAL
[Sandbox.Content]
; Chemins disque, relatifs a Content/
ModuleRoot=Modules/vin_Base
WorldFile=Modules/vin_Base/World/work___vin01.lpworld
ChatAction=Modules/vin_Base/Interactions/chat.lpaction
QuaterniusUALDisk=Quaternius/UAL
[Sandbox.Sky]
; Optionnel : cubemap du SkyLight du sandbox
SkyCubemap=/Game/Heavy/New2/Buildings/Mats/urban_street_03_1k.urban_street_03_1k
SkyIntensity=0.6
[Sandbox.Output]
; Relatif a Saved/
MeasureOutputRoot=Measurement
4. Critères d'acceptation pour S2 (implémentation, hors de cette fiche)
- Sans
Config/LPSandbox.ini, comportement strictement identique à aujourd'hui (defaults = littéraux de la colonne « default »). - Avec le fichier d'exemple ci-dessus, comportement strictement identique.
- Un seul point de lecture (struct de config chargée une fois, p. ex.
FLPSandboxConfig::Get()), plus deTEXT("/Game/...")en dur dansLPPairSandbox.cpp/LPAnimRedirect.cpppour les clés ci-dessus. - Clé présente mais asset introuvable : même journal d'erreur qu'aujourd'hui (
LogLifePlay), sans repli silencieux sur une autre valeur.