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

24 KiB

Fiche STE-P1 — Niveau N3 — Modèle prévu (modèle de l'agent lp-impl) | utilisé claude-opus-5-5 — Agent lp-impl (A-IMPL-H) — Skills sk-protocol, ue-cpp-build, lp-build, lp-ue-compat, lp-mcp, lp-doc (gabarits)

STE-P1-SPEC : poser le style d'une Text Box sans laisser Slate pointer sur une temporaire (ERR-088) (2026-10-10)

Cette SPEC est écrite en lecture seule. Sources lues : le moteur installé D:\Game\Launcher\Engine\UE_5.8\Engine\Source (abrégé UE58\), le moteur 5.5 pour la garde (UE55\), Source\LifePlay et le relevé Saved\Logs\portage\U5_assets_apres.txt (abrégé relevé). Livrable amont : STE-TXT-DIAG.md. Les lignes de ScriptCore.cpp viennent de ce DIAG et n'ont pas été relues ici.

Décision. Je retiens le corps (D), une variante de (B) : TextBox->WidgetStyle = Style; TextBox->SetWidgetStyle(TextBox->GetWidgetStyle()); en 5.8.

  • En 5.5, sous la garde UE_VERSION_OLDER_THAN(5, 8, 0), la fonction écrit seulement le membre, comme le faisait le nœud Set.
  • (A) est écarté : SynchronizeProperties réapplique tout le widget (§ 2.1, § 6.3).
  • La fonction va dans une nouvelle bibliothèque, ULPWidgetStyleLibrary. Build.cs ne change pas.
  • Les 4 nœuds sont situés dans un relevé 5.8 valable pour l'état courant : aucun dump ne manque (§ 2.4).
  • Aucune question bloquante.

1. Objectif mesurable

  • Ajouter une fonction C++ BlueprintCallable : ULPWidgetStyleLibrary::SetEditableTextBoxStyle(UEditableTextBox* TextBox, const FEditableTextBoxStyle& Style).
    • Après l'appel, SEditableTextBox::Style vise UEditableTextBox::WidgetStyle. Ce membre vit autant que le widget UMG.
    • Slate ne reçoit jamais l'adresse du paramètre, même un instant.
    • Rien d'autre n'est réappliqué : texte, liaisons, infobulle, visibilité restent tels quels.
  • Remplacer les 4 nœuds Set WidgetStyle par un appel à cette fonction : CharGen K2Node_VariableSet_1146 et _1147, StatMenu K2Node_VariableSet_1146 et _1147. Mêmes entrées, même enchaînement d'exécution.
  • Mesures :
    • build LifePlayEditor 5.8 : code 0, 0 erreur, 0 avertissement nouveau ;
    • compile_blueprint sans avertissement sur CharGen et StatMenu ;
    • 0 nœud Set WidgetStyle restant dans les deux EventGraph ;
    • CompileAllBlueprints 0/0 ;
    • en PIE : 10 refus de nom de suite sans plantage, flash rouge visible, texte noir lisible (critère 8 de la fiche).

2. Fichiers touchés, ordre

Ordre : (1) Source\LifePlay\LPWidgetStyleLibrary.h et (2) .cpp, créés par lp-impl. Puis (3) BUILD par lp-builder. Puis (4) Content\UI\StatMenu.uasset et (5) Content\UI\CharGen.uasset, modifiés par l'orchestrateur par MCP, sous BUILD-GO, une fois le module compilé et l'éditeur relancé. LifePlay.Build.cs ne change pas.

2.1 Choix du corps : (A), (B) ou (D)

Critère (A) membre + SynchronizeProperties (B) SetWidgetStyle(InStyle) puis SetWidgetStyle(GetWidgetStyle()) (D) retenu : membre, puis SetWidgetStyle(GetWidgetStyle())
Pointeur gardé par Slate à la fin &WidgetStyle (EditableTextBox.cpp:133) &WidgetStyle (:397, InStyle = le membre) &WidgetStyle (idem)
Slate vise le paramètre un instant non oui, entre les deux appels non
Ce qui est réappliqué tout le widget (§ 6.3) SetStyle seul, deux fois (:392-399) SetStyle seul, une fois
Auto-affectation WidgetStyle = WidgetStyle non oui oui (sûre, § 6.2)
Compile en 5.5 oui, sans garde non : SetWidgetStyle et GetWidgetStyle n'existent pas en 5.5 non, d'où la garde (§ 2.3)
Proximité du nœud Set actuel faible (texte et liaisons réappliqués) setter 5.8 sans le défaut setter 5.8 sans le défaut : c'est le correctif P3 de STE-TXT-DIAG.md

Raisons du choix :

  • (D) fait exactement ce que ferait le setter du moteur s'il passait &WidgetStyle au lieu de &InStyle (EditableTextBox.cpp:394, :397) :
    • il copie le style dans le membre ;
    • puis il appelle SEditableTextBox::SetStyle sur le membre (SEditableTextBox.cpp:113-132). Cet appel recalcule les pointeurs de bordure, recopie le style de texte (SEditableText.cpp:161-167) et invalide la mise en page.
    • C'est le traitement que le nœud Set reçoit aujourd'hui, défaut en moins.
  • (A) écarté. SynchronizeProperties réapplique tout (§ 6.3). Les valeurs sont en principe identiques, mais deux effets sont réels :
    • le texte est relu de force (SlateEditableTextLayout.cpp:273-284). Avec le focus et une liaison Text, le texte saisi peut être remplacé (:4343, :4361), le curseur peut sauter en fin (:4364-4367) et OnTextChanged peut être émis (:4370-4373) ;
    • l'infobulle est recréée (Widget.cpp:1506-1526).
    • lp-mcp § 4 (ERR-057) donne la même leçon : les liaisons et les OnValueChanged se déclenchent pendant SynchronizeProperties.
  • (D) plutôt que (B). L'effet final est le même. (D) ne donne pas à Slate l'adresse du paramètre et fait un SetStyle de moins. L'adresse du paramètre est une référence valable le temps de l'appel seulement (P_GET_STRUCT_REF → PARAM_PASSED_BY_REF, ScriptMacros.h:73).
  • Aliasing, demandé par la fiche pour (B), qui vaut aussi pour (D). SetWidgetStyle(GetWidgetStyle()) passe à WidgetStyle = InStyle une référence au membre lui-même (EditableTextBox.h:263, .cpp:401-404).
    • L'opérateur de copie est celui par défaut (SlateTypes.h:1024, SlateTypes.cpp:310). Il copie membre à membre ; détail au § 6.2.

2.2 Emplacement

Nouvelle bibliothèque Source\LifePlay\LPWidgetStyleLibrary.h/.cpp, ULPWidgetStyleLibrary : UBlueprintFunctionLibrary.

  • ULPModSettingsLibrary ne convient pas : elle porte la sélection de mods de l'écran titre (lot UI15, LPModSettingsLibrary.h:1-8, catégorie LifePlay|Mods, :23). C'est un autre domaine.
  • Le modèle suivi est ULPMeshCompat (LPMeshCompat.h:1-32) : une fonction de bibliothèque qui contourne, pour les Blueprints, un comportement du moteur.
  • Les dépendances sont déjà là : Slate, SlateCore, UMG en privé (LifePlay.Build.cs:38). L'en-tête n'est inclus par aucun autre module. LifePlayEditorTools n'inclut que LPAssetRegistryHelpers.h (LifePlay.Build.cs:11-15). Les dépendances privées suffisent donc, et Build.cs ne change pas.
  • Statut : contournement d'un défaut du moteur, à garder comme les correctifs de compatibilité (lp-ue-compat § 4) tant que le moteur installé garde SetStyle(&InStyle) (EditableTextBox.cpp:397).

2.3 Code à écrire (IMPL lp-impl)

En-tête : il inclut Styling/SlateTypes.h (SlateCore). Le thunk généré par UHT construit un FEditableTextBoxStyle local et a donc besoin du type complet. UEditableTextBox est seulement prédéclaré.

UFUNCTION(BlueprintCallable, Category = "LifePlay|UI", meta = (DisplayName = "Set Widget Style (Text Box, LP)"))
static void SetEditableTextBoxStyle(UEditableTextBox* TextBox, const FEditableTextBoxStyle& Style);

Corps :

if (!IsValid(TextBox)) { UE_LOG(LogLifePlay, Verbose, ...); return; }
TextBox->WidgetStyle = Style;                           // membre public, non déprécié (EditableTextBox.h:50-52)
#if !UE_VERSION_OLDER_THAN(5, 8, 0)
TextBox->SetWidgetStyle(TextBox->GetWidgetStyle());     // auto-affectation, puis SetStyle(&WidgetStyle)
#endif
// UE 5.5 : pas de setter natif ; le nœud Set écrivait le membre seul, et Slate visait déjà &WidgetStyle.
  • Includes du .cpp : LPWidgetStyleLibrary.h d'abord, puis Components/EditableTextBox.h, Misc/EngineVersionComparison.h et LifePlay.h (pour LogLifePlay, comme LPMeshCompat.cpp:3-7).
  • Fichiers en ASCII et fins de ligne LF, comme les voisins (file LPMeshCompat.* LPModSettingsLibrary.* : « ASCII text », sans CRLF). Commentaires en français sans accents.
  • Branche 5.5, choisie pour rester fidèle à 5.5 :
    • en 5.5, la propriété n'a pas de Setter (UE55\…\EditableTextBox.h:48). Le nœud Set écrivait donc le membre ;
    • Slate gardait l'adresse du membre, donnée par SynchronizeProperties (UE55\…\EditableTextBox.cpp:129) ;
    • la couleur de fond est relue à chaque image (DetermineBackgroundColor, SEditableTextBox.cpp:348-352 en 5.8 ; même mécanisme estimé en 5.5) ;
    • la branche 5.5 ne fait donc rien de plus que le nœud d'origine.

2.4 Graphe : les 4 substitutions (orchestrateur, MCP, BUILD-GO)

Source : le relevé. CharGen :1195439-1195460, StatMenu :1415089-1415112.

Le relevé vaut pour l'état courant (établi) :

  • CharGen : les nœuds _1146, _1147, MakeStruct_62 et _64, IfThenElse_366 et VariableGet_2400 sont identiques octet pour octet entre HEAD et l'état STE-TXT (STE-TXT-DIAG.md:81-85).
  • StatMenu : md5sum = 4fa5d803b35bcaa47aab3c0a854b1ad8, identique à git show HEAD:Content/UI/StatMenu.uasset. Le fichier date du 2026-10-08 20:28:43, le relevé du 20:31:01. Dernier commit sur StatMenu : 809102a (U5). git status : StatMenu n'est pas modifié.
  • Aucun dump ne manque. Confirmation facultative, sous BUILD-GO, éditeur fermé : .\Tools\RunCommandlet.ps1 -Lot STE-D -Commandlet LPDumpFunction -Args '-BP=StatMenu -Fn=EventGraph -Pins -Exec' (même commande avec -BP=CharGen).
Asset Nœud à supprimer Position (X, Y) execute ← then → Cible TextBox ← Style ← Output_Get
CharGen K2Node_VariableSet_1147 (rouge) (-2400, 13024) K2Node_IfThenElse_366.else K2Node_CallFunction_5310.execute (Delay) K2Node_VariableGet_2400.FilenameEntry K2Node_MakeStruct_62.EditableTextBoxStyle non relié
CharGen K2Node_VariableSet_1146 (blanc) (-1808, 13024) K2Node_CallFunction_5310.then aucun (fin de chaîne) K2Node_VariableGet_2400.FilenameEntry K2Node_MakeStruct_64.EditableTextBoxStyle non relié
StatMenu K2Node_VariableSet_1147 (rouge) (496, 2592) K2Node_IfThenElse_366.else K2Node_CallFunction_5310.execute K2Node_VariableGet_204.FilenameEntry K2Node_MakeStruct_62.EditableTextBoxStyle non relié
StatMenu K2Node_VariableSet_1146 (blanc) (1088, 2592) K2Node_CallFunction_5310.then aucun K2Node_VariableGet_204.FilenameEntry K2Node_MakeStruct_64.EditableTextBoxStyle non relié

Sources du tableau : relevé :1195442-1195449, :1195453-1195460, :1415092-1415100, :1415104-1415112. Aucune broche Output_Get n'est reliée : rien en aval ne lit la valeur du Set.

Procédure, pour chaque asset (lp-mcp § 1 règle 3 et § 3) :

  1. git status --short -- Content/UI/StatMenu.uasset doit être vide. Puis .\Tools\Snapshot.ps1 -Lot STE-P1 -Path Content\UI\StatMenu.uasset (fiche, rubrique 4). Pour CharGen, voir R8 et Q2.
  2. load_asset (/Game/UI/<Asset>). Puis find_node_types {graph, type_id_filter:"SetEditableTextBoxStyle"} ; à défaut, filtrer sur Set Widget Style (Text Box, LP). Noter le type_id (catégorie LifePlay|UI).
  3. get_node_infos du nœud Set : vérifier que ses liens sont ceux du tableau. Écart = arrêt et rapport (fiche, rubrique 9).
  4. create_node à la position du nœud Set. Lire ensuite les indices des broches par get_node_infos : execute, then, TextBox, Style. La broche self de la bibliothèque est cachée.
  5. Relier d'abord les broches qui acceptent plusieurs liens :
    • FilenameEntry → TextBox et MakeStruct_xx.EditableTextBoxStyle → Style (sorties de données) ;
    • pour _1147 seulement : then → K2Node_CallFunction_5310.execute (entrée d'exécution).
  6. delete_node de l'ancien Set. Cela libère IfThenElse_366.else ou CallFunction_5310.then, des sorties d'exécution à lien unique.
  7. Relier execute ← K2Node_IfThenElse_366.else (pour _1147) ou ← K2Node_CallFunction_5310.then (pour _1146).
  8. Relire le nœud par get_node_infos : 4 liens pour la copie de _1147, 3 pour celle de _1146. Puis find_nodes {graph, title} sur le titre du nœud Set : 0 dans l'EventGraph.
  9. compile_blueprint, avertissements traités comme des erreurs, puis hyper_blueprint_debug_inspect : 0 diagnostic. Puis save_assets {asset_paths:["/Game/UI/CharGen","/Game/UI/StatMenu"]}, ces deux assets seuls.

3. Repli

  • C++ : .\Tools\Restore.ps1 -Lot STE-P1. Les deux fichiers sont notés Existed=False et seront déplacés, pas supprimés. Le graphe doit être restauré en même temps, sinon les nœuds d'appel deviennent orphelins.
  • StatMenu : l'instantané STE-P1 de l'étape 1, ou git (HEAD = 4fa5d803…), éditeur fermé.
  • CharGen : l'instantané STE-TXT est l'état d'avant STE-TXT (HEAD, 21ab367c…). Le restaurer défait aussi STE-TXT. Voir R8 et Q2.
  • Si la VAL montre un défaut d'affichage avec (D) : le corps (A) s'écrit dans le même fichier, sans toucher au graphe. Ses risques sont au § 2.1.
  • Si le module ne compile pas : lp-builder rapporte, sans rien corriger (boucle U3, lp-build § 5).

4. Risques R#, questions Q#

  • R1 (estimé, faible) : auto-affectation.
    • Les types qui portent de la mémoire sont sûrs, et c'est établi : TArray et FString (Array.h:1012-1020, test this != &Other), TSharedPtr (SharedPointer.h:966-971, copie puis échange).
    • Aucun operator= n'est déclaré dans SlateBrush.h, SlateFontInfo.h, SlateColor.h, SlateWidgetStyle.h, ni dans SlateTypes.h en dehors de :1024 (Grep operator=\s*\(). Les autres membres utilisent donc la copie implicite.
    • Conséquence si c'était faux : un style abîmé, visible en VAL. Repli (A).
  • R2 (établi, sans effet nouveau) : SetStyle recopie le style de texte et relance la mise en page (SEditableTextBox.cpp:130-131, SEditableText.cpp:161-167). Le nœud Set le fait déjà aujourd'hui.
  • R3 (incertain) : d'autres appelants du setter existent peut-être.
    • C++ du jeu : Grep UEditableTextBox|SetWidgetStyle sur Source\LifePlay donne 5 lignes, toutes sur d'autres widgets, toutes sûres :
      • USlider : LPColorGradeSubsystem.cpp:201, LPVideoQualitySubsystem.cpp:395, LPSettingsSubsystem.cpp:415 ;
      • UCheckBox : LPSettingsSubsystem.cpp:371 ;
      • USpinBox : LPSettingsSubsystem.cpp:390. Leurs setters 5.8 passent &WidgetStyle (Slider.cpp:215, CheckBox.cpp:244) ou invalident le style (SpinBox.cpp:154). Seul UEditableTextBox passe &InStyle. Aucun UEditableTextBox dans Source.
    • Blueprints du relevé : 4 nœuds en tout (STE-TXT-DIAG.md:121-123).
    • Les mods (Content\Modules) n'ont pas été cherchés : un mod qui pose WidgetStyle sur une Text Box garde le défaut. Ce point sort du périmètre et va aux Constats.
  • R4 (établi) : la branche 5.5 ne sera pas compilée dans ce lot, faute de build 5.5 dans la fiche. Elle se limite à une affectation de membre public : UE55\…\EditableTextBox.h:45-49, section public ouverte à :45.
  • R5 (constaté) : les deux nœuds Set de StatMenu portent ErrorType = 1 (relevé :1415094, :1415106).
    • 1 vaut EMessageSeverity::Error (TokenizedMessage.h:23).
    • ClearCompilerMessage ne remet pas ErrorType à zéro (EdGraphNode.h:398, :667-670) : c'est probablement un drapeau ancien (estimé).
    • Les nœuds sont supprimés, mais l'orchestrateur relit les diagnostics de StatMenu à l'étape 9.
  • R6 (établi par la fiche) : le plantage n'arrive pas à chaque fois. Seule la répétition le prouve absent (T3 : 10 refus de suite).
  • R7 (incertain) : type_id localisé. Trouver le nœud par find_node_types, ne pas le deviner (lp-mcp § 3).
  • R8 (établi) : retour arrière de CharGen. Aucun instantané ne garde l'état STE-TXT (9669B103…) : seul l'instantané STE-TXT existe, et il garde HEAD. Pour défaire STE-P1 seul, il faut prendre .\Tools\Snapshot.ps1 -Lot STE-P1 -Path Content\UI\CharGen.uasset avant l'écriture MCP. Voir Q2.
  • R9 (estimé) : UEditableTextBox est MinimalAPI (EditableTextBox.h:26).
    • Le code généré du jeu référence ses informations de type. MinimalAPI exporte précisément ces informations, et les membres utilisés sont exportés (UMG_API, :261, :263).
    • L'accès direct à WidgetStyle ne demande aucun export.
    • Le build le confirmera, à l'édition de liens.
  • R10 (estimé) : si Epic corrige la ligne :397 dans une version future, (D) reste correct : l'appel donnerait le même résultat.
  • Q1 (non bloquante) : faut-il garder la branche 5.5 ? La règle lp-ue-compat § 1 vaut pour U0-U8. Si la copie 5.5 ne reçoit plus de code, la garde peut être retirée plus tard. Je la garde par défaut.
  • Q2 (non bloquante, pour l'orchestrateur) : prendre l'instantané de CharGen sous STE-P1 (R8) ? Cela s'écarte de la rubrique 4 de la fiche, qui dit « CharGen : instantané STE-TXT déjà pris ».

5. Interdits

  • Ne pas modifier le moteur. Ne pas modifier Build.cs. Ne rien écrire hors des deux fichiers C++ et des livrables (lp-impl). Ne rien écrire hors de CharGen et StatMenu (orchestrateur).
  • Pas de SynchronizeProperties dans la branche 5.8 (§ 2.1). Pas de PRAGMA_DISABLE_DEPRECATION_WARNINGS.
  • Pas de « modernisation » des fichiers de compatibilité (LPStringCompat, LPMeshCompat, LPNavigationHelpers…).
  • Graphe : ne toucher ni aux MakeStruct_62 à _65, ni au Delay CallFunction_5310, ni à IfThenElse_366. Aucun nœud ajouté hors des 4 appels.
  • Pas de compilation ni d'éditeur par lp-impl. Aucune commande git qui écrit (sk-protocol § 2).

6. Valeurs moteur lues dans le moteur installé

6.1 Le défaut et le correctif (5.8)

  • UE58\Runtime\UMG\Public\Components\EditableTextBox.h :
    • :26 : UCLASS(..., MinimalAPI) ;
    • :39 et :54 : Text et HintText sont sous UE_DEPRECATED(5.1, ...) ;
    • :50-52 : WidgetStyle, UPROPERTY(..., Getter, Setter, ...), sans UE_DEPRECATED. L'accès direct ne produit donc pas de C4996 ;
    • :261 : UMG_API void SetWidgetStyle(const FEditableTextBoxStyle&), sans UFUNCTION ;
    • :263 : UMG_API const FEditableTextBoxStyle& GetWidgetStyle() const ;
    • :270 : UMG_API virtual void SynchronizeProperties(), public.
  • UE58\Runtime\UMG\Private\Components\EditableTextBox.cpp :
    • :97 : RebuildWidget → .Style(&WidgetStyle) ;
    • :121-151 : SynchronizeProperties, avec :133 SetStyle(&WidgetStyle) ;
    • :392-399 : SetWidgetStyle : :394 WidgetStyle = InStyle, :397 MyEditableTextBlock->SetStyle(&InStyle) (le défaut) ;
    • :401-404 : GetWidgetStyle renvoie le membre.
  • UE58\Runtime\Slate\Private\Widgets\Input\SEditableTextBox.cpp :
    • :45-47 : bordure, fond et avant-plan sont liés à Determine* ;
    • :65 : la police est liée à DetermineFont ;
    • :113-132 : SetStyle : Style = InStyle (:115), pointeurs BorderImage* dans le style (:125-128), SetTextBlockStyle(&Style->TextStyle) (:130), Invalidate(Layout) (:131). Pas de sortie anticipée si le pointeur ne change pas ;
    • :342-346 : DetermineFont lit Style->TextStyle.Font ;
    • :348-352 : DetermineBackgroundColor lit Style->BackgroundColor.
  • UE58\Runtime\Slate\Private\Widgets\Input\SEditableText.cpp:161-167 : SetTextBlockStyle copie le style (SetTextStyle(*InTextStyle)) et ne garde pas de pointeur.
  • UE58\Runtime\CoreUObject\Public\UObject\ScriptMacros.h:73 : P_GET_STRUCT_REF = PARAM_PASSED_BY_REF. Le paramètre const& est une référence à durée d'appel.
  • Repris de STE-TXT-DIAG.md § 3.4, non relu ici : ScriptCore.cpp:2906-2929. La VM appelle le setter avec une temporaire, puis la détruit.

6.2 Copie et auto-affectation

  • UE58\Runtime\SlateCore\Public\Styling\SlateTypes.h:1018-1025 : FEditableTextBoxStyle déclare un constructeur de copie, un operator= et un destructeur, tous SLATECORE_API.
  • UE58\Runtime\SlateCore\Private\Styling\SlateTypes.cpp:309-312 : ils sont = default, placés entre PRAGMA_DISABLE/ENABLE_DEPRECATION_WARNINGS.
    • Ils sont définis hors ligne. Le membre Font_DEPRECATED n'est donc pas touché dans l'unité du jeu : pas de C4996.
  • UE58\Runtime\Core\Public\Containers\Array.h:1012-1020 : TArray::operator= teste this != &Other.
  • UE58\Runtime\Core\Public\Templates\SharedPointer.h:966-971 : TSharedPtr::operator= copie, puis échange.

6.3 Ce que (A) réapplique (raison de l'écarter)

  • UE58\Runtime\UMG\Private\Components\Widget.cpp:1444-1541 (UWidget::SynchronizeProperties) :
    • données d'accessibilité (:1451) ;
    • curseur (:1477-1480) ;
    • SetEnabled et SetVisibility par liaison (:1482-1483) ;
    • découpe (:1493), aimantation au pixel (:1496), direction (:1497), ForceVolatile (:1499) ;
    • opacité (:1501), transformée (:1503-1504) ;
    • infobulle recréée (:1506-1526) ;
    • accessibilité (:1528-1539).
  • EditableTextBox.cpp:130-150 : SetStyle, SetText(liaison), SetHintText(liaison), IsReadOnly, IsPassword, largeur minimale, comportements de focus et de validation, menu contextuel, clavier virtuel, justification, débordement, chargement des polices, ShapedTextOptions.
  • UE58\Runtime\Slate\Private\Widgets\Text\SlateEditableTextLayout.cpp :
    • :273-284 : SetText force la relecture (bForceBoundTextReview = true) ;
    • :4337-4377 : OnBoundTextChanged. Une relecture forcée passe outre le focus (:4343). Si le texte lié diffère du texte affiché, il le remplace (:4354, :4361). Avec le focus, le curseur saute en fin (:4364-4367), et OnTextChanged est émis si le texte a changé (:4370-4373).
  • Conclusion : sans liaison Text, l'effet est nul (le membre Text suit la saisie, EditableTextBox.cpp:406-413). Avec une liaison, le texte saisi peut être remplacé. Cette surface est inutile ici.

6.4 Garde de version

  • UE_VERSION_OLDER_THAN : UE58\Runtime\Core\Public\Misc\EngineVersionComparison.h:24 et UE55\…:18.
  • 5.5 :
    • UE55\Runtime\UMG\Public\Components\EditableTextBox.h:45-49 : section public, WidgetStyle sans Setter (:48) ;
    • :256 : SynchronizeProperties public (section public de :148 à :268) ;
    • Grep WidgetStyle sur cet en-tête : 1 ligne (:49), donc ni SetWidgetStyle ni GetWidgetStyle ;
    • UE55\…\EditableTextBox.cpp:117-129 : SynchronizeProperties → SetStyle(&WidgetStyle) ;
    • Grep void UEditableTextBox::SetWidgetStyle : 0.

7. Critères de VAL (commande → attendu)

  1. .\Tools\Build.ps1 -Lot STE-P1 (lp-builder, éditeur fermé) :
    • code 0 ;
    • ligne Using Visual Studio 14.50.35739 toolchain (…\MSVC\14.50.35717) ;
    • unités LPWidgetStyleLibrary.cpp et LPWidgetStyleLibrary.gen.cpp, ou leur unité unity, compilées ; UnrealEditor-LifePlay.dll liée ;
    • 0 error, 0 warning C4996 ;
    • « autres lignes » = 20 (HyperAIStudio, lp-build § 7).
  2. Diff (git status --short -- Source) : exactement 2 fichiers nouveaux (??), ASCII, fins de ligne LF (file Source/LifePlay/LPWidgetStyleLibrary.*), aucun autre fichier de Source touché.
  3. Graphe, après MCP :
    • find_nodes du titre du nœud Set WidgetStyle dans CharGen:EventGraph et StatMenu:EventGraph → 0 ;
    • get_node_infos des 4 nouveaux nœuds → liens du § 2.4 ;
    • compile_blueprint → 0 avertissement ; hyper_blueprint_debug_inspect → 0 diagnostic.
  4. CompileAllBlueprints (commandlet, éditeur fermé) → 0 erreur, 0 avertissement.
  5. PIE avec l'utilisateur, dans CharGen, panneau Save Preset, nom vidé :
    • 10 refus de suite sans plantage ;
    • flash rouge puis retour au blanc ;
    • texte noir lisible avant, pendant et après, avec et sans focus dans le champ. Même essai dans StatMenu si un refus y est accessible.
  6. Contrôle de non-régression du texte : pendant le Delay, cliquer dans le champ et taper. Le texte saisi est conservé et le curseur ne saute pas, comme avant.
  7. Contrôle optionnel : Saved\Crashes ne contient aucun nouveau rapport FCachedTypefaceData après l'essai (Grep FCachedTypefaceData::FCachedTypefaceData, 1 fichier attendu, l'ancien).

Fichiers à commiter (dépôt du jeu, branche ue5.8, par le gardien) : A Docs/Migration/etat/ST/STE/STE-P1-SPEC.md.

Tours : 14 / 60 (partie SPEC ; total SPEC et IMPL dans STE-P1-IMPL.md)