117 lines
20 KiB
Markdown
117 lines
20 KiB
Markdown
Fiche STE-ORG5-I1 — Niveau N3 — 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-ORG5-I1-IMPL : bonus d'orgasme ORG5, version minimale (V-min) en C++ dans deux fichiers neufs (2026-10-14)
|
||
|
||
Périmètre tenu : deux fichiers neufs et ce livrable ; aucun fichier existant modifié, aucun asset, ni éditeur, ni MCP, ni commandlet, ni build. **Aucun refus du crochet** (commandes Bash sans `>`, sans `python -c`, sans heredoc). Le code n'est **pas compilé** (build commun, fiche BUILD à venir) : tout ce qui suit sur la compilation est « proposé, non compilé ».
|
||
|
||
## 1. Fichiers modifiés (chemins, lignes)
|
||
| Fichier | Lignes (LF, sans BOM) | Contenu |
|
||
|---|---|---|
|
||
| `D:\Game\LifePlay-master 5.8\Source\LifePlay\LPBonusRewardSubsystem.h` | 119 | en-tête d'origine et de licence (l. 1-10), description V-min, accroche H1, réglage (l. 12-33) ; `ULPBonusRewardSettings` `UCLASS(config = Game)`, `bDisabled = false` (l. 45-55) ; `FLPBonusStat` (l. 57) ; `FLPBonusPending` (l. 64) ; `ULPBonusRewardSubsystem : UGameInstanceSubsystem` (l. 72-) |
|
||
| `D:\Game\LifePlay-master 5.8\Source\LifePlay\LPBonusRewardSubsystem.cpp` | 667 | outils de réflexion dans l'espace de noms nommé `LPBonusReward` (l. 14-173) ; `Initialize` (l. 175 : contrôle de formule, ligne de réglage, minuterie `FTSTicker` 0,1 s) ; `Table` 20 clés (l. 207) ; `RewardChange` (l. 232) ; `CheckFormula` (l. 243) ; `Overlaps` (l. 269) ; `Pick` (l. 287) ; `Tick` / `Poll` (l. 334, 345) ; `FirePending` (l. 434) ; `OnOrgasm` (l. 451) ; `AttractionAllowed` (l. 488) ; `IsInterestedIn` (l. 527) ; `QueryStat` (l. 567) ; `ModifyStat` (l. 603) ; `PersonName` (l. 638) ; `WarnOnce` (l. 659) |
|
||
|
||
Contrôles (sortie brute) :
|
||
- `od -An -v -tx1 <f> | tr ' ' '\n' | grep -c '^0d$'` → `.h CR=0 LF=119`, `.cpp CR=0 LF=667` ; 3 premiers octets `2f 2f 20` (pas de BOM), comme `LPUserSettings.h` (`CR=0 LF=59`, même début).
|
||
- Grep `\{ TEXT\("[a-z_]+-?"\), \{` dans le `.cpp` → `20` (les 20 lignes de la table) ; Grep `Users|<nom>` dans `LPBonusReward*` → `0`.
|
||
- 5 lignes non ASCII dans le `.cpp` (accents des formats de journal imposés par la SPEC § 2.4 : contrôle, réglage, désactivé, récompense éligible) ; même pratique que `LPDirectControlSubsystem.cpp:449` (« » dans un `TEXT`, compilé en 5.8).
|
||
|
||
### 1.1 Choix du sous-système
|
||
`UGameInstanceSubsystem` + `FTSTicker` à 0,1 s (précédent `LPColorGradeSubsystem.h:51`, `.cpp:76-82`). Raisons : `SexOn`, `SexPersons`, `CurrentTags`, `PlayerCharacter` sont sur GI ; le sous-système vit toute la session, sans dépendre d'un monde ; aucun tick d'acteur à créer. Coût (estimé) : hors scène, une recherche de propriété (`SexOn`) par tick ; en scène, une par personne (`Sex_OrgasmCounts`) plus `SexPersons` : quelques recherches de `FName` dans les listes de propriétés de GI et de Person, 10 fois par seconde, de l'ordre de la microseconde ; aucun appel Blueprint hors orgasme.
|
||
|
||
### 1.2 Accroche (H1, documentée, sans nœud Blueprint)
|
||
- **Aucun nœud Blueprint n'est nécessaire** pour V-min : le C++ lit l'état par réflexion. Aucune lecture du journal, aucun crochet de texte.
|
||
- Sondage (`Poll`, l. 345) : `GI.SexOn` faux → mémoire des compteurs vidée ; vrai → pour chaque personne valide de `GI.SexPersons` : premier passage = mémorisation sans récompense ; hausse de `Sex_OrgasmCounts` → copie de `GI.CurrentTags`, armement d'un orgasme en attente à t + 0,2 s (remplace l'attente en cours, comme `RetriggerableDelay`) ; baisse → resynchronisation sans récompense ; personne sortie de la scène → oubliée.
|
||
- `FirePending` (l. 434) : à échéance, personne valide → `OnOrgasm` : ligne `orgasme de`, puis `désactivé` (réglage) **ou** tirage `Pick` → `aucune récompense éligible` **ou** `QueryStat` + `RewardChange` + `ModifyStat(Stat, Change, false, false)` sur la **première** récompense retenue, puis la ligne `<nom> <stat> <±valeur> (x=…, tags=…)` (marqueur V6).
|
||
- Règle commune ORG4 / ORG5 (SPEC fin de fichier, `STE-ORG4-SPEC.md:265-269`) : un incrément de `Sex_OrgasmCounts` arme une seule attente, qui donne au plus une récompense appliquée ; `Endsex` sans `Cum` n'incrémente pas le compteur et ne déclenche rien ici.
|
||
|
||
### 1.3 Appels et lectures par réflexion, preuves
|
||
| Élément | Nom | Type exigé par le code | Preuve |
|
||
|---|---|---|---|
|
||
| GI | `SexOn` | `FBoolProperty` | précédent `LPDirectControlSubsystem.cpp:460-464` |
|
||
| GI | `SexPersons` | `FArrayProperty` d'objets | précédent `LPShowCoupleSubsystem.cpp:80-96`, `:303` |
|
||
| GI | `PlayerCharacter` | `FObjectPropertyBase` | précédents `LPDebugSubsystem.cpp:481`, `LPOutdoorRoomSubsystem.cpp:334` |
|
||
| GI | `CurrentTags` | `FArrayProperty` de `FStrProperty` | SPEC E1 (`MakeStruct StringArray(Strings = GI.CurrentTags)`, `Person.uexp:21184` de l'auteur) ; nom présent dans `O\BPs\GI.uasset` (SPEC annexe A point 10) ; **type chez nous estimé** |
|
||
| Person | `Sex_OrgasmCounts` | `FIntProperty` | `Person__EventGraph.txt:16118-16125` (macro `IncrementInt`), `:15908-15911` (remise à `0`) |
|
||
| Person | `isPlayer` | `FBoolProperty` | `L6f_dump_Person.txt:558-559` (variable reliée à `IfThenElse.Condition`) |
|
||
| Person | `Name_First` | `FTextProperty` ou `FStrProperty` | SPEC § 2.4 (texte chez l'auteur, `Cursor.uexp:22666`) ; type chez nous non lu, les deux acceptés |
|
||
| Person (fonction) | `QueryStat(Stat, WithoutBuff, RNG)` → `Value`, `Bonus` | `Stat` chaîne, `WithoutBuff` et `RNG` booléens, `Value` réel en sortie | `L6f_dump_Person.txt:20-29` ; appel de l'auteur `QueryStat(Stat, false, false)` (SPEC E6d) |
|
||
| Person (fonction) | `ModifyStat(Stat, Change, DifficultyAdjusted, NoDisplay)` → `Value` | `Stat` chaîne, `Change` réel d'entrée, deux booléens | `L6f_dump_Person.txt:561-570` ; appel de l'auteur `ModifyStat(Stat, Change, false, false)` (SPEC E7) |
|
||
| GI (fonction) | `IsInterestedIn(WhoIsInterested, WhoInterests)` → `Interested` | deux objets de la classe du paramètre, booléen en sortie | `L6f_dump_GI.txt:23421-23424`, `:23442-23443` ; ordre retenu `WhoIsInterested = Person`, `WhoInterests = PlayerCharacter` (estimé, SPEC § 2.4) |
|
||
| GI (fonction) | `Overlaps(Array1, Array2, IfEmptyThenTrue)` | **non appelée** : réécrite en C++ (`Overlaps`, l. 269) | `L6f_dump_GI.txt:19622-19673` : `IfEmptyThenTrue ET (Len(A1)=0 OU Len(A2)=0)` → vrai ; sinon un élément de `Array1` dans `Array2` (`Array_Contains`) → vrai ; sinon faux |
|
||
|
||
Appels par `FindFunction` + `ProcessEvent`, paramètres trouvés **par nom** (`GetAuthoredName` ou `GetName`), mémoire `FMemory_Alloca_Aligned(ParmsSize, GetMinAlignment())` dans le cadre de l'appelant, mise à zéro, `InitializeValue_InContainer` puis `DestroyValue_InContainer` en sortie de portée (structure `FScopedParms`, même séquence que `LPDirectControlSubsystem.cpp:426-455`). Signature ou type inattendu : un avertissement `Bonus : …` par cause (liste des paramètres et de leurs types dans le message), abandon sans effet.
|
||
|
||
### 1.4 API moteur relues dans UE 5.8 (lecture, `D:\Game\Launcher\Engine\UE_5.8\Engine\Source\`)
|
||
- `FTSTicker` : `Runtime\Core\Public\Containers\Ticker.h:21` (`FTickerDelegate` bool(float)), `:32` (`FDelegateHandle`), `:45` (`AddTicker(delegate, InDelay)`), `:66` (`RemoveTicker`).
|
||
- `UGameInstanceSubsystem` / `GetGameInstance` : `Runtime\Engine\Public\Subsystems\GameInstanceSubsystem.h:16`, `:25`.
|
||
- `UKismetMathLibrary::FCeil(double)` → `int32` : `Runtime\Engine\Classes\Kismet\KismetMathLibrary.h:796` (`UE_INL_API`, `:180-183`), corps `KismetMathLibrary.inl:743-746` (`FMath::CeilToInt`) ; `MapRangeClamped` : `.h:836` (`ENGINE_API`), corps `Private\KismetMathLibrary.cpp:328-331` (`FMath::GetMappedRangeValueClamped`). Le code appelle ces deux fonctions elles-mêmes : arithmétique identique à celle des nœuds Blueprint.
|
||
- `Array_Shuffle` : `Runtime\Engine\Private\KismetArrayLibrary.cpp:338-352` (Fisher-Yates, `RandRange(i, LastIndex)`), variante par flux `:363-366` ; reproduit avec `FRandomStream::RandRange` (`Runtime\Core\Public\Math\RandomStream.h:209-214`, bornes incluses) ; graine `GenerateNewSeed` (`:105-108`).
|
||
- `Array_Contains` → `GenericArray_Find` (`KismetArrayLibrary.cpp:547-559`) → `Inner->Identical` ; `TProperty_WithEqualityAndSerializer::Identical` compare par `operator==` (`Runtime\CoreUObject\Public\UObject\UnrealType.h:1769`) : le C++ (`TArray<FString>::Contains`) utilise le même opérateur (estimé : l'héritage de `FStrProperty` depuis ce gabarit n'est pas relu).
|
||
- `UObject::FindFunction` `Runtime\CoreUObject\Public\UObject\Object.h:1258` ; `ProcessEvent` `:1490` ; `UStruct::GetMinAlignment` `Class.h:790` ; `FField::GetAuthoredName` `Field.h:903` ; `InitializeValue_InContainer` / `DestroyValue_InContainer` `UnrealType.h:1128`, `:1040` ; `FObjectPropertyBase::GetObjectPropertyValue_InContainer` / `SetObjectPropertyValue_InContainer` `UnrealType.h:2896`, `:2901` ; `StrProperty.h` inclus par `UnrealType.h:7815`.
|
||
- `FMemory_Alloca_Aligned` : `Runtime\Core\Public\GenericPlatform\GenericPlatformMemory.h:221`.
|
||
- `TArray::Swap(i, j)` `Runtime\Core\Public\Containers\Array.h:3536` ; `SetNum` `:2531` ; `TOptional::operator->` `Misc\Optional.h:384-390`, `Reset` `:235`.
|
||
- Formats de journal : indicateur `+` accepté (`Runtime\Core\Public\String\FormatStringSan.h:164`), conversions `f` et `g` (`:424`, `:426`).
|
||
|
||
### 1.5 Réglage
|
||
`ULPBonusRewardSettings` `UCLASS(config = Game)`, `UPROPERTY(config) bool bDisabled = false` : section `[/Script/LifePlay.LPBonusRewardSettings]`, clé `bDisabled`, de la config Game du projet (`Config\DefaultGame.ini`) ; section absente → valeur du code (faux, fonction active). Lu par `GetDefault<ULPBonusRewardSettings>()` ; **aucun `SaveConfig`** : rien n'est écrit, ni dans `Config\` ni dans `Saved\`. `DefaultGame.ini` n'est pas modifié (fiche § 3, consigne 2). Une ligne au démarrage donne la valeur lue : `Bonus : réglage bDisabled = vrai|faux (…)`.
|
||
|
||
### 1.6 En-tête
|
||
`.h` l. 1-10 : origine « comportement reconstruit d'après LifePlay 2023.04 de Vinfamy » (sans accents, comme les commentaires du module), licence MIT (`SPDX-License-Identifier: MIT`, texte court des droits et de la condition de mention), renvoi à `Licenses/Vinfamy_License.txt` (ligne 1 : « … are under MIT », relue). `.cpp` l. 1-3 : rappel de l'origine et de la licence.
|
||
|
||
### 1.7 Build.cs
|
||
**Inchangé, aucun module nouveau requis** : `Engine` (KismetMathLibrary, GameInstanceSubsystem, GameInstance), `Core` (Ticker, RandomStream, Optional), `CoreUObject` (réflexion) sont déjà des dépendances publiques (`Source\LifePlay\LifePlay.Build.cs:17`). Catégorie de journal `LogLifePlay` : `Source\LifePlay\LifePlay.h:9`.
|
||
|
||
## 2. Écarts à la SPEC (obligatoire)
|
||
| # | SPEC | Fait | Pourquoi |
|
||
|---|---|---|---|
|
||
| E1 | § 2.4 (b), § 2.5 : `UCLASS(config = GameUserSettings)`, ini utilisateur ; § 3 : désactivation par `bDisabled=True` dans l'ini utilisateur | `UCLASS(config = Game)`, valeur par défaut du code, rien écrit | consigne 2 de Big Boss (fiche § 3) : réglage dans `Config\`, rien dans `Saved\`. Conséquence : le moyen de désactiver **sans reconstruire** dans un jeu empaqueté n'est plus établi (point VAL-11) |
|
||
| E2 | § 2.4 : journal niveau `Display` | niveau `Log` (avertissements en `Warning`, contrôle de formule fautif en `Error`) | fiche § 4 : `UE_LOG(LogLifePlay, Log, …)`. Les formats de texte sont ceux de la SPEC ; dans le fichier de journal, `LogLifePlay: Bonus : …` au lieu de `LogLifePlay: Display: Bonus : …` ; le motif `Bonus :` de VAL 7.5 / 7.7 / 7.9 trouve les deux |
|
||
| E3 | § 2.4 sondage : « si `GI.SexOn` faux → vider le suivi » | la mémoire des compteurs est vidée ; un orgasme **déjà détecté** garde son tempo de 0,2 s et reçoit sa récompense même si la scène vient de finir | comme l'auteur (`RetriggerableDelay` indépendant de la scène, E3 / E10) ; évite de perdre la récompense de l'orgasme qui termine la scène |
|
||
| E4 | E3 : `RetriggerableDelay` (temps du monde) | tempo en temps réel (`FPlatformTime::Seconds`) | sous-système de GameInstance sans monde garanti ; différence seulement en pause ou en temps dilaté pendant les 0,2 s |
|
||
| E5 | E6c : la condition `attractiontoplayer` est évaluée quand la clé passe | `bAttractionAllowed` calculé avant `Pick` (signature de la SPEC), avec court-circuit : `isPlayer` → `PlayerCharacter` → présence dans `SexPersons` → `IsInterestedIn` (appel Blueprint) ; l'appel a lieu pour tout PNJ de scène avec le joueur, même si la clé n'est pas tirée | signature imposée (`bool bAttractionAllowed`) ; équivalent si `IsInterestedIn` est sans effet de bord (non relu en entier : VAL-9) |
|
||
| E6 | § 5 : fonction ou propriété absente = avertissement et abandon | sur le chemin `attractiontoplayer` (`isPlayer`, `PlayerCharacter`, `IsInterestedIn`), l'abandon porte sur **la clé** (refusée), le reste du tirage continue ; ailleurs, abandon de la récompense | la condition ne peut pas être prouvée vraie : clé refusée, comme si la condition était fausse ; avertissement unique écrit |
|
||
| E7 | § 2.4 (b) signatures | ajouts privés : `Poll`, `FirePending`, `AttractionAllowed`, `IsInterestedIn`, `PersonName`, `WarnOnce`, structure `FLPBonusPending` ; `CheckFormula` statique publique ; paramètre de `Pick` nommé `InRng` | découpage du sondage ; `InRng` évite un C4458 (paramètre qui masque le membre `Rng`) |
|
||
| E8 | § 2.4 formats | en plus : `Bonus : réglage bDisabled = …` au démarrage ; deux lignes `Verbose` (attente remplacée, personne disparue) invisibles par défaut ; avertissements préfixés `Bonus :` | diagnostic J1 ; un `LogStats -Pattern 'Bonus :'` compte aussi ces lignes (VAL-5) |
|
||
| E9 | § 2.4 contrôle de formule sur 7 valeurs | 7 valeurs + 1 cas de signe (50 avec `-` → −1,1) | contrôle du signe |
|
||
| E10 | § 2.4 : `QueryStat` sorties `Value`, `Bonus` | signature exigée stricte : `Stat` chaîne, `WithoutBuff` et `RNG` booléens, `Value` réel en sortie ; sinon avertissement et pas de récompense | règle « pas de repli silencieux » ; risque si `RNG` n'est pas booléen chez nous (VAL-8) |
|
||
|
||
## 3. Instantané (lot, manifeste)
|
||
sans objet : la fiche ne demande pas d'instantané et aucun fichier existant n'est touché (deux fichiers **neufs**). État de départ et d'arrivée relevés (`sk-change-safety` règles 2 et 10, invoqué après l'écriture des deux fichiers : écart de méthode sans effet, rien n'a été écrasé) :
|
||
- Avant : `git -C "D:/Game/LifePlay-master 5.8" status --short` → dans `Content`/`Source` : `M` `Content/BPs/GI.uasset`, `PC.uasset`, `Person.uasset`, `Room.uasset`, `Source/LifePlay/LPDebugSubsystem.cpp/.h`, `LPDirectControlSubsystem.cpp/.h`, `LPOutdoorRoomSubsystem.cpp/.h`, `LifePlay.cpp` ; `??` `LPCameraModeSubsystem.cpp/.h`, `LPSaveRelaunch.cpp/.h`.
|
||
- Après : `git -C "D:/Game/LifePlay-master 5.8" status --porcelain -- Content Source Config` → mêmes 11 `M`, 4 `??` d'avant, plus `?? Source/LifePlay/LPBonusRewardSubsystem.cpp` et `?? Source/LifePlay/LPBonusRewardSubsystem.h`. Différence = le changement prévu.
|
||
- Note pour VAL 7.1 : la SPEC comptait « 10 `M`, 4 `??` » ; `Content/BPs/PC.uasset` était déjà `M` à l'entrée de cette fiche (autre lot), donc 11 `M`.
|
||
- Journal du changement : `2026-10-14 | ORG5 V-min, 2 fichiers C++ neufs | Source/LifePlay/LPBonusRewardSubsystem.h, .cpp | retour arrière (proposé, non lancé) : déplacer les deux fichiers vers D:\Game\LifePlay_Backup_5.5\STE\ORG5-I1\ | instantané : sans objet (fichiers neufs) | vérification : git status ci-dessus`.
|
||
|
||
## 4. Ce qui n'a pas été fait
|
||
- Compilation (fiche BUILD du build commun) ; aucune vérification UHT ni MSVC.
|
||
- V-1 (panneau Slate, 3 boutons, choix), V-2 (case de réglage, onglet Lewd), H2 (nœud dans `GiveOrgasmReward`) : hors V-min.
|
||
- Section `[/Script/LifePlay.LPBonusRewardSettings]` dans `Config\DefaultGame.ini` : non ajoutée (fichier existant ; décision ultérieure).
|
||
- Formatage de nombre par `FText` (SPEC § 6, incertain) : sans objet en V-min (le journal utilise `%+.1f`) ; à lire pour V-1.
|
||
- Lecture complète de `GI.IsInterestedIn` (effets de bord) et des types réels des variables de GI et Person (lecture L-M2 de la SPEC) : non faites (pas de MCP).
|
||
|
||
## 5. Points à confirmer en VAL (un par ligne)
|
||
- VAL-1 : build du module `LifePlay` code 0 ; UHT accepte les structures C++ simples `FLPBonusStat` / `FLPBonusPending` dans l'en-tête et le membre `TOptional<FLPBonusPending>`.
|
||
- VAL-2 : aucun avertissement-erreur de masquage (C4456 / C4458) ni C4996 sur les deux fichiers ; `UKismetMathLibrary::FCeil` (`UE_INL_API`) se lie en Development.
|
||
- VAL-3 : `FMemory_Alloca_Aligned(ParmsSize, Alignment)` avec des `int32` locaux compile sans avertissement (macro `GenericPlatformMemory.h:221`).
|
||
- VAL-4 : table : 20 clés et 20 listes de tags identiques à SPEC § 1.2 (relecture ligne à ligne de `.cpp` l. 207-229) ; `RewardChange` dans l'ordre de SPEC § 1.3 ; `Pick` : 10 candidates, 3 au plus, `Overlaps(…, true)`, règle `attractiontoplayer`.
|
||
- VAL-5 : aucun widget créé (Grep `UUserWidget|SNew|AddViewportWidgetContent|CreateWidget` dans les deux fichiers = 0) ; les avertissements `Bonus :` ne comptent pas comme lignes de récompense dans 7.7.
|
||
- VAL-6 : journal de démarrage : 1 ligne `Bonus : contrôle formule OK`, 0 `Error` du sous-système, 1 ligne `Bonus : réglage bDisabled = faux`.
|
||
- VAL-7 : journal J1 : aucun avertissement `Bonus : pas de propriete …` ni `signature inattendue …` (types de `SexOn`, `SexPersons`, `CurrentTags`, `Sex_OrgasmCounts`, `isPlayer`, `Name_First`, `QueryStat`, `ModifyStat`, `IsInterestedIn` conformes).
|
||
- VAL-8 : `Person.QueryStat.RNG` est booléen (`L6f_dump_Person.txt:25` : relié à `RngActual`, type non lu) ; sinon aucune récompense ne sera appliquée.
|
||
- VAL-9 : `GI.IsInterestedIn` sans effet de bord sur GI ou Person (écart E5) et ordre `WhoIsInterested = PNJ` correct.
|
||
- VAL-10 : J1 par orgasme : 1 ligne `orgasme de`, puis 1 ligne `<stat> <±valeur>` ou `aucune récompense éligible` ; valeur conforme à SPEC § 1.3 pour le `x` journalisé ; la ligne « stat ±n » de `ModifyStat` apparaît en jeu.
|
||
- VAL-11 : désactivation : où écrire `bDisabled=True` pour qu'un jeu empaqueté la lise sans reconstruire (couche `Saved\Config\Windows\Game.ini` lue ou non) ; sinon seul `DefaultGame.ini` avant cuisson vaut (écart E1).
|
||
- VAL-12 : règle commune ORG4 / ORG5 : fin par `Endsex` sans `Cum` → 0 ligne ORG5 ; un orgasme → au plus 1 ligne de récompense appliquée par personne (V6).
|
||
- VAL-13 : 7.1 : `git status --porcelain -- Content Source Config` = état d'entrée (11 `M`, 4 `??`) + 2 `??` de cette fiche.
|
||
|
||
## 6. Fichiers à commiter
|
||
Dépôt du jeu `D:\Game\LifePlay-master 5.8`, branche `ue5.8` (après BUILD et VAL, sur ticket au gardien) :
|
||
- `A Source/LifePlay/LPBonusRewardSubsystem.h`
|
||
- `A Source/LifePlay/LPBonusRewardSubsystem.cpp`
|
||
- `A Docs/Migration/etat/ST/STE/STE-ORG5-I1-IMPL.md`
|
||
|
||
Tours : 28 / 45 (déclaré ; `python -I Tools/FicheStats.py --lot STE` fait foi)
|
||
|
||
## Constats
|
||
- Points à vérifier à la compilation : VAL-1 à VAL-3 ; code commun 5.5 / 5.8 non exigé (développement 5.5 arrêté), mais aucune API propre à 5.8 n'est utilisée (`FTSTicker`, `FDoubleProperty`, `UE_INL_API` existent depuis 5.0, estimé, non relu en 5.5).
|
||
- Un orgasme dans les 0,2 s d'un autre (deux personnes) : seul le dernier reçoit une récompense, comme l'auteur (SPEC E3) ; la règle commune (au plus une fois par personne) est tenue.
|
||
- À verser : `lp-ue-compat` § 1 (ou `ue-cpp-build` § 0) — en 5.8, le validateur de format de `UE_LOG` accepte l'indicateur `+` et les conversions `f` / `g` (`Core\Public\String\FormatStringSan.h:164`, `:424-426`) ; `UKismetMathLibrary::FCeil` est `UE_INL_API` (en ligne hors Debug, `KismetMathLibrary.h:180-183`) ; `FMemory_Alloca_Aligned` est dans `GenericPlatform\GenericPlatformMemory.h:221`. `sk-protocol` § 7 — compter les CR d'un fichier sans redirection : `od -An -v -tx1 <f> | tr ' ' '\n' | grep -c '^0d$'` (le `od -c | grep -c '\\r'` compte des lignes d'`od`, pas des octets : faux).
|