LifePlay-Revival/Docs/Migration/etat/ST/STE/STE-G3-IMPL.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

11 KiB

Fiche STE-G3 — Niveau N2 — Modèle prévu (modèle de l'agent lp-impl) | utilisé claude-opus-5-5 — Agent lp-impl — Skills sk-protocol, ue-cpp-build, lp-build, lp-ue-compat (préchargés), sk-change-safety (invoqué)

STE-G3-IMPL : NotifyCoupleTeleported(), reprise de LastSafe après une téléportation par CAM (2026-10-14)

Résultat : réussi (écrit, non compilé). Fonction publique ajoutée à ULPShowCoupleSubsystem : une seule écriture de LastSafe à la place actuelle du meneur, aucun balayage, gardes avant toute écriture. Compilation confiée au build COMMUN-11 (fiche § 3).

Mesure Avant (2026-10-14, entrée de fiche) Après (2026-10-14)
MD5 Source\LifePlay\LPShowCoupleSubsystem.h 57dc8cd468d2fb5de231bfbe25346389 44c721ee9e82bdfdf7571e493af70e39
MD5 Source\LifePlay\LPShowCoupleSubsystem.cpp 35cf128c8c3e059130e7cf48d9fa0454 3cdd572d78b691eef0a3f02b1b37a486
Fins de ligne (git ls-files --eol) i/crlf w/crlf (les deux) i/crlf w/crlf (les deux)

Commande des MD5 : certutil -hashfile "<fichier>" MD5. Mesuré, git -C "D:/Game/LifePlay-master 5.8" diff --stat -- Source/LifePlay/LPShowCoupleSubsystem.h Source/LifePlay/LPShowCoupleSubsystem.cpp :

 Source/LifePlay/LPShowCoupleSubsystem.cpp | 19 +++++++++++++++++++
 Source/LifePlay/LPShowCoupleSubsystem.h   |  4 ++++
 2 files changed, 23 insertions(+)

1. Fichiers modifiés

  • D:\Game\LifePlay-master 5.8\Source\LifePlay\LPShowCoupleSubsystem.h l. 28-30 (section public, après Deinitialize) : commentaire de deux lignes et déclaration void NotifyCoupleTeleported();.
  • D:\Game\LifePlay-master 5.8\Source\LifePlay\LPShowCoupleSubsystem.cpp l. 806-824 (après KeepTogether) : définition.

Diff résumé de la définition :

void ULPShowCoupleSubsystem::NotifyCoupleTeleported()
{
	ACharacter* Who = Lead.Get();
	if (!bEngaged || !Who || !Partner.Get() || !GetWorld())
	{
		return;
	}
	const FVector Now = Who->GetActorLocation();
	if (!(Now - LastSafe).IsNearlyZero())
	{
		UE_LOG(LogLifePlay, Warning, TEXT("Show couple : place reprise apres teleportation %s (ecart %.0f)"),
			*Now.ToString(), FVector::Dist(LastSafe, Now));
	}
	LastSafe = Now;
	LastBlocker.Reset();
}

(plus deux lignes de commentaire en tête du corps, non recopiées.)

1.1 Pour CAM : nom, signature, en-tête, appel

  • Nom : ULPShowCoupleSubsystem::NotifyCoupleTeleported.
  • Signature : void NotifyCoupleTeleported(); (publique, non const, sans paramètre, sans retour).
  • En-tête : #include "LPShowCoupleSubsystem.h" (même module LifePlay, classe LIFEPLAY_API, LPShowCoupleSubsystem.h:20).
  • Appel depuis le C++, pas depuis un Blueprint : B2p-F est « C++ LPCameraModeSubsystem, aucun asset » (CAM-COMMUN9-DIAG.md l. 129 et l. 215) ; G3 est « appelée par B2p-D après une pose libre validée par G1 » (l. 191-193) ; le glisser B2p-D est du C++ (LPCameraModeSubsystem.cpp:1064-1068). Donc pas de UFUNCTION (fiche § 3 : seulement si un Blueprint l'appelle).
  • Forme d'appel conseillée (même accès que LPCameraModeSubsystem.cpp:287, UGameInstance::GetSubsystem GameInstance.h:440), après la boucle qui déplace le couple (LPCameraModeSubsystem.cpp:1065-1068) et seulement si G1 a validé la place :
if (ULPShowCoupleSubsystem* Show = GI->GetSubsystem<ULPShowCoupleSubsystem>())
{
	Show->NotifyCoupleTeleported();
}

1.2 Grandeur reprise (point amont de la fiche § 3)

  • KeepTogether écrit LastSafe = Who->GetActorLocation(); avec Who = Lead.Get() (.cpp:752, .cpp:804) ; Engage écrit la même grandeur (LastSafe = InLead->GetActorLocation();, .cpp:400). La fonction reprend exactement celle-là : la place de l'acteur meneur (Lead), pas la boîte ni le partenaire. Établi.
  • Effet sur l'image suivante : KeepTogether calcule Delta = Now - LastSafe (.cpp:760-761) ; si CAM n'a plus rien bougé, Delta est nul et KeepTogether sort sans balayer (.cpp:762-765) ; sinon il balaie depuis la place libre posée par CAM (ResolveCoupleMove(…, LastSafe, Delta, …), .cpp:792-793). Établi par lecture.

1.3 États remis à zéro

  • LastBlocker (« dernier bloquant ») : vidé. Il n'est lu que pour dédoublonner le journal (.cpp:781 coque, .cpp:794 « bloque par ») ; aucun effet sur le mouvement. Conséquence : le prochain blocage (ou la coque) est réécrit une fois au journal, utile pour l'essai CAM-74. Établi (toutes les occurrences lues : .h:53, .cpp:781, 790, 794, 798, 823).
  • Aucun autre état de balayage dans le sous-système : profondeur, normale et bloquant sont des variables locales du résultat Move (.cpp:792-799). Box, FittedPair, RejectedPair, LoggedExtent (mesure de la boîte), bPawnLogged, SavedFurniture, SavedSeats, SavedPartnerMove (collisions, mouvement gelé) ne sont pas des états de balayage : non touchés. Établi par lecture de l'en-tête (.h:45-75).
  • Résolveur partagé : Grep "static " sur Plugins\LPAnimCore\Source\LPAnimCore\LPCoupleSimCore.cpp → 1 résultat, static const TCHAR* Excluded[] (l. 46), table constante : pas d'état gardé entre deux appels. LPCoupleSim.h cherché seulement avec le motif static … = (0 résultat) : absence d'autre état statique estimée.

1.4 Gardes, appel répété, appel hors scène

  • Gardes avant toute lecture ou écriture : bEngaged faux (hors scène, ou Release passé : .cpp:668-674), meneur absent ou détruit (Lead.Get() nul), partenaire absent, monde absent (GetWorld() nul) → retour sans rien changer, sans plantage (aucun déréférencement avant les gardes).
  • Pas de garde sur la boîte (Box) : non nécessaire pour reprendre LastSafe.
  • Appel répété : sans danger. LastSafe reçoit la même valeur (idempotent) ; LastBlocker est revidé ; la ligne de journal n'est écrite que si la place a bougé de plus de UE_KINDA_SMALL_NUMBER (Vector.h:600).
  • Appel hors scène : sans danger, la garde bEngaged sort avant toute écriture. Au premier tour d'une scène, Engage repose de toute façon LastSafe sur le meneur (.cpp:400).
  • Contrat pour CAM : n'appeler qu'après une pose validée par G1. Si la place posée recouvrait un meuble, la fonction en ferait la nouvelle place sûre et KeepTogether ne dépénètrerait pas tant que le meneur ne bouge pas (Delta nul, .cpp:762-765). Estimé par lecture.

1.5 API moteur relues (UE 5.8, D:\Game\Launcher\Engine\UE_5.8\Engine\Source\)

  • TWeakObjectPtr::Get() : Runtime\Core\Public\UObject\WeakObjectPtrTemplates.h:141 ([[nodiscard]], valeur utilisée).
  • UObject::GetWorld() const : Runtime\CoreUObject\Public\UObject\Object.h:711 (déjà appelé par le fichier, .cpp:289, .cpp:755 ; UGameInstanceSubsystem ne le redéfinit pas : GameInstanceSubsystem.h et Subsystem.h sans GetWorld).
  • AActor::GetActorLocation() const : Runtime\Engine\Classes\GameFramework\Actor.h:2502.
  • TVector::IsNearlyZero(T Tolerance = UE_KINDA_SMALL_NUMBER) const : Runtime\Core\Public\Math\Vector.h:600.
  • TVector::ToString() const : Vector.h:861 ; TVector::Dist(const TVector&, const TVector&) statique, rend T = double pour FVector : Vector.h:1015 (format %.0f, comme .cpp:796).
  • FString::Reset(int32 NewReservedSize = 0) : Runtime\Core\Public\Containers\UnrealString.h.inl:332.
  • UGameInstance::GetSubsystem<T>() const (pour CAM) : Runtime\Engine\Classes\Engine\GameInstance.h:440.
  • LogLifePlay : Source\LifePlay\LifePlay.h:9, inclus par .cpp:24.

2. Écarts à la SPEC

  • E1 : sk-change-safety invoqué après les deux Edit et non avant. Instantané pris par l'orchestrateur et vérifié ensuite : D:\Game\LifePlay_Backup_5.5\STE-G3\Source\LifePlay\LPShowCoupleSubsystem.h MD5 57dc8cd468d2fb5de231bfbe25346389, .cpp MD5 35cf128c8c3e059130e7cf48d9fa0454 (identiques à l'entrée de fiche), manifest.csv présent. Sans effet sur le résultat.
  • E2 : la ligne UE_LOG est conditionnelle (écrite seulement si la place a changé), pour ne pas écrire une ligne par appel sans déplacement. Elle reste une seule ligne, catégorie LogLifePlay, niveau Warning comme le reste du fichier.
  • E3 : pas de UFUNCTION : l'appelant est du C++ (§ 1.1), conforme à la fiche § 3.
  • E4 : la fiche ne dit pas où placer la fonction dans le .cpp ; placée après KeepTogether, à la fin du fichier.
  • Budget suivi : rubrique 9 de la fiche (20 tours), et non le budget N3 du message de lancement.

3. Instantané

Pris par l'orchestrateur (fiche § 2) : D:\Game\LifePlay_Backup_5.5\STE-G3\ (2 fichiers + manifest.csv), relu par MD5 le 2026-10-14 (§ 2 E1). Retour arrière (proposé, non lancé) : recopier les deux fichiers de l'instantané sur Source\LifePlay\ (Tools\Restore.ps1 -Lot STE-G3, à décider par l'orchestrateur).

4. Ce qui n'a pas été fait

  • Aucune compilation (build COMMUN-11, lp-builder), aucun éditeur, MCP, commandlet ni jeu (fiche § 6).
  • L'appel côté CAM (B2p-F) n'est pas écrit : fichier CAM, hors périmètre.
  • Ligne STE-G3 du registre STE-TACHES.md, entrée CHG, commit : orchestrateur et gardien.
  • Le mode « tourner » de la prise (CoupleGrabMode == 2, LPCameraModeSubsystem.cpp:1071-1085) déplace aussi le meneur autour du pivot ; le DIAG ne prévoit l'appel qu'après le glisser. Question pour CAM, non traitée.

5. Points à confirmer en VAL

  • Diff limité aux deux fichiers : git diff --stat = 2 fichiers, 23 insertions, 0 suppression.
  • LastSafe écrit une seule fois, à Lead.Get()->GetActorLocation(), même grandeur que .cpp:804.
  • Aucun appel à ResolveCoupleMove ni à un balayage ou recouvrement dans NotifyCoupleTeleported.
  • Gardes bEngaged, meneur, partenaire, monde placées avant toute lecture ou écriture.
  • LastBlocker seul état remis à zéro, lu seulement pour le journal (.cpp:781, .cpp:794).
  • Déclaration en section public (.h:30), sans UFUNCTION.
  • Fins de ligne CRLF conservées (git ls-files --eol : w/crlf pour les deux fichiers).
  • Aucun nom local qui masque un membre (Who, Now : pas de membre de ce nom, .h:45-75).
  • Build COMMUN-11 : LPShowCoupleSubsystem.cpp compilé, 0 erreur, 0 avertissement nouveau (C4458, C4456 compris).
  • En jeu, CAM-74 : couple coincé, glisser vers le milieu de la pièce → ligne Show couple : place reprise apres teleportation … puis plus de bloque par … profondeur 3 à chaque image.
  • En jeu : volume de la ligne « place reprise » pendant un glisser continu (une ligne par image déplacée si CAM appelle à chaque image).

6. Fichiers à commiter

Dépôt jeu D:\Game\LifePlay-master 5.8, branche ue5.8 :

  • M Source/LifePlay/LPShowCoupleSubsystem.h
  • M Source/LifePlay/LPShowCoupleSubsystem.cpp
  • A Docs/Migration/etat/ST/STE/STE-G3-IMPL.md

Tours : 15 / 20