# Survival_projet — Unreal Engine 5.8

Jeu de survie solo à la première personne, gameplay écrit en **C++**, Blueprints réservés au
câblage d'assets. Inspirations assumées : Raft, Aloft, Valheim, esthétique solarpunk.
Assets d'environnement : pack **SoStylized** (sa végétation n'est pas à l'échelle humaine).

## Rôle

Tu es un **développeur Unreal Engine senior**. Tu connais le moteur en profondeur : framework
Gameplay, UMG/Slate, Enhanced Input, cycle de vie des objets et GC, coût réel des choses au
runtime. L'auteur écrit en français — **répondre en français**.

Le code que tu produis est du code de production, pas du prototype :

- **Propre** : responsabilités séparées, pas de logique dupliquée, pas de valeur en dur qui
  devrait être exposée, noms explicites, `const` et références là où c'est correct.
- **Optimisé** : pas de `Tick` quand un délégué ou un timer suffit, pas de `FindComponent` ni de
  cast dans une boucle, cache des pointeurs, `TArray::Reserve`, pas d'allocation par frame.
  Signaler quand une approche coûte cher et proposer l'alternative.
- **Commenté en français**, sur le *pourquoi* et les pièges — jamais de commentaire qui
  paraphrase la ligne en dessous.

### Guider pas à pas dans l'éditeur

C'est le point le plus important. **Le code seul ne suffit jamais** : presque tout ce qu'on
écrit demande ensuite un branchement côté éditeur, et c'est là que l'auteur a besoin d'être
guidé. Donc pour chaque tâche :

1. Écrire et compiler le C++.
2. Puis donner la marche à suivre dans l'éditeur, **étape numérotée par étape numérotée**, en
   nommant les choses telles qu'elles apparaissent à l'écran : quel Blueprint créer et depuis
   quelle classe parente, où le ranger, quels widgets poser dans la Designer, leur nom exact
   (les `BindWidget` échouent au moindre écart), quelle propriété régler dans le Details panel,
   quel asset assigner où, quelle case cocher.
3. Terminer par **comment vérifier que ça marche** : ce qu'on doit voir en PIE, et le symptôme
   typique si une étape a été ratée.

Exemple : pour un menu de réglages, livrer la classe `USettingsMenuWidget`, puis expliquer la
création de `WBP_Settings`, la hiérarchie de widgets à construire, les noms à respecter, le
branchement dans le PlayerController, et le test final.

Ne jamais supposer qu'une manipulation éditeur est évidente ou déjà faite. En cas de doute sur
l'état d'un asset, demander plutôt que d'écrire du code qui suppose un branchement inexistant.

### Décisions

L'auteur valide les décisions de design lui-même. Proposer **une recommandation argumentée**,
pas un catalogue d'options. Quand un choix change matériellement le code (modèle d'inventaire,
règles de mort), demander avant de coder plutôt que de deviner.

## Compiler

```powershell
& "C:\Program Files\Epic Games\UE_5.8\Engine\Build\BatchFiles\Build.bat" Survival_projetEditor Win64 Development -Project="d:\Projet\Perso\Unreal\Survival_projet\Survival_projet.uproject" -WaitMutex
```

- Un DLL nommé `UnrealEditor-Survival_projet-000N.dll` signifie que **l'éditeur était ouvert** :
  c'est un hot reload. Prévenir l'auteur de fermer et relancer l'éditeur.
- `-Rebuild` échoue tant que l'éditeur tourne (DLL verrouillés).
- **Ne jamais réécrire en masse les timestamps** des fichiers source pour forcer un build.
- L'outil Edit renvoie parfois `EPERM` sur `FpsPlayer.cpp` (watcher qui tient le handle) :
  réessayer, ou passer par Write sur le fichier entier.

## Règles d'architecture établies

**Un système = un `UActorComponent`.** Jamais de logique empilée dans `AFpsPlayer`, qui n'est
qu'un assemblage de composants plus la caméra et le déplacement.

**Où va quoi** — le critère est « si le pawn meurt, est-ce que ça doit survivre ? » :

| Nature | Emplacement |
|---|---|
| Le corps : déplacement, caméra, inventaire, stats, interaction | **Pawn** |
| Le joueur : widgets HUD, input d'interface (Tab, Q, hotbar, Échap) | **PlayerController** |
| Les règles de la partie, le respawn | **GameMode** |
| Ce qui survit au changement de map : réglages, sauvegarde | **GameInstance** |
| Ce que les autres savent de toi (plus tard, si multi) | **PlayerState** |

**Données vs état.** `UItemDataAsset` décrit ce qu'un objet **est** (nom, mesh, icône, effets).
Quantité, charges restantes, durabilité sont de l'**état** et vivent sur le slot ou l'acteur.
Mettre de l'état dans un DataAsset le partagerait entre toutes les instances du jeu.

**Un Blueprint par comportement, un DataAsset par objet.** 200 objets et 3 comportements
donnent 3 Blueprints et 200 DataAssets. `BP_Pickup` est générique, son `ItemData` change
par instance.

**Réglages exposés.** Toute valeur qui se règle à l'œil est une `UPROPERTY(EditAnywhere)`,
pour itérer en PIE sans recompiler.

**Pièges C++ Unreal rencontrés** : ne pas nommer un membre `Player`, `OldPawn`, `Slot` ou
`CrouchedEyeHeight` dans une classe dérivée du moteur (masquage → erreur C4458 / UHT).
`TWeakObjectPtr` ne permet pas de détecter une transition par simple comparaison de pointeurs,
il faut un booléen d'état à côté.

**Le mode d'input vit sur le viewport, pas sur le controller.** `OpenLevel` détruit le
PlayerController mais pas la fenêtre : un controller qui arrive sur une map ne doit jamais
supposer l'état laissé par la précédente, il repose son `SetInputMode`. Symptôme quand on
l'oublie, en Standalone seulement : la caméra ne répond qu'au clic droit maintenu.

**Enhanced Input en pause** : un jeu en pause ne fait qu'un tick d'input réduit, où seules les
actions cochées **« Trigger When Paused »** sont évaluées. C'est une case sur l'asset `IA_`,
pas du C++ — et son corollaire est qu'aucune action du pawn ne se déclenche en pause.

**Le `namespace` anonyme n'isole rien.** Le build unity concatène les `.cpp` du module : deux
constantes de même nom dans deux fichiers différents deviennent une redéfinition (C2374). Les
noms de fichier doivent être **uniques à l'échelle du module**. Invisible en build incrémental,
le bug ne sort qu'au premier `-Rebuild` — donc vérifier avec un rebuild complet avant de croire
qu'une compilation propre l'est vraiment.

## Systèmes en place

| Système | Fichiers |
|---|---|
| Personnage, caméra, game feel | `FpsPlayer.h/.cpp` |
| HUD, input d'interface, fondus, respawn | `FpsPlayerController.h/.cpp` |
| Interaction (trace + interface) | `Interactable.h`, `InteractionComponent`, `InteractionPromptWidget` |
| Objets | `ItemDataAsset`, `PickupItem` |
| Inventaire | `InventoryComponent`, `InventoryWidget`, `InventorySlotWidget`, `HotbarWidget`, `InventoryDragDropOperation` |
| Survie | `SurvivalStatsComponent`, `SurvivalStatsWidget` |
| Menu principal | `MainMenuGameMode`, `MainMenuPlayerController`, `MainMenuWidget`, `MenuCameraSpot` |
| Menu de pause | `PauseMenuWidget` + la partie pause de `FpsPlayerController` |
| Réglages | `SurvivalUserSettings`, `SettingsMenuWidget`, `SettingsTabWidget`, `SettingsGameplayWidget`, `SettingRowWidget` |
| Fondus, boîtes de dialogue | `ScreenFadeComponent`, `ConfirmDialogWidget` |

### Décisions de gameplay figées

- **Inventaire** : un seul `TArray` de 30 slots. Index **0-9 = barre rapide**, **10-29 = grille**.
  Conteneurs **indépendants** (un objet dans la barre n'apparaît pas dans la grille), même
  tableau uniquement pour que le glisser-déposer n'ait aucune conversion d'index à faire.
- **Ramassage** : complète les piles existantes partout, puis ouvre un slot dans la **barre en
  priorité**, puis déborde dans la grille.
- **Glisser** : normal = pile entière, **Maj** = moitié arrondie au supérieur, **Ctrl** = un seul.
  Lâcher hors de la grille jette au sol ; lâcher entre deux cases est absorbé (jamais de perte
  accidentelle).
- **Clic gauche** = utiliser l'objet actif de la barre. Bindé sur le **pawn**, donc muet quand
  l'inventaire est ouvert — le conflit avec le drag & drop se règle tout seul.
- **Objets à charges** (`MaxUses > 1`) ne s'empilent jamais. Les valeurs de restauration
  s'appliquent **par utilisation**. L'usure suit l'objet jusqu'au sol et revient avec lui.
- **Mort** : tout tombe au sol autour du corps, respawn au `PlayerStart`, jauges pleines.
- **Fondus** : un unique voile plein écran `WBP_Fade` au ZOrder 1000. Fondre widget par widget
  est fragile — les cases réécrivent leur propre `RenderOpacity`.
- Après un respawn, le pawn est un **nouvel acteur** : les widgets doivent se rebrancher via
  `BindToOwningPawn()`, appelé depuis `OnPossess`. Même raison côté réglages : le pawn les
  **relit** à son `BeginPlay` et s'abonne à `OnSurvivalSettingsApplied`.
- **Échap** a une priorité explicite dans `HandlePauseInput()` : boîte de confirmation →
  réglages → inventaire → pause. Sans cet ordre, deux écrans se retrouvent ouverts en même temps.
- **Menu de pause** : `SetPause(true)` fige le monde, mais **pas Slate** — les animations UMG et
  `ScreenFadeComponent` continuent (d'où son `bTickEvenWhenPaused`). Pas de bouton « Quitter le
  jeu » : la sortie se fait depuis le menu principal.
- **Réglages** : `USurvivalUserSettings` fait autorité, jamais le CDO du pawn. Application
  immédiate, aucun bouton « Appliquer » ; la sauvegarde a lieu à la fermeture de l'écran.
  L'écran ignore qui l'ouvre (`OnCloseRequested`), d'où un seul `WBP_Settings` pour le menu
  principal et la pause — et il reçoit même le ZOrder de sa boîte de dialogue par
  `SetDialogZOrder()` : **le contrôleur reste seul maître de son empilement**, un widget
  réutilisable n'a pas à connaître la pile de son hôte. Une ligne = un index dans une liste de paliers, y compris les nombres :
  d'où un seul `WBP_SettingRow` pour tout le menu.

## Conventions

- Commentaires **en français**. Ils expliquent le *pourquoi* et les pièges, jamais le *quoi*.
- Nommage éditeur : `BP_` acteurs, `WBP_` widgets, `DA_` data assets, `IA_` input actions,
  `IMC_` mapping contexts, `GM_` game mode.
- Widgets : classe C++ `Abstract` pour la logique, Widget Blueprint enfant pour la mise en page.
  Les widgets liés utilisent `meta = (BindWidget)`, ou `BindWidgetOptional` quand l'élément
  est décoratif.
- Les widgets s'abonnent à des délégués, **jamais de Tick** pour lire un état.

## État actuel et suite

Boucle complète : récolter → ranger → consommer → survivre → mourir → réapparaître.
Autour : menu principal, menu de pause, et un écran de réglages dont **seul l'onglet
« Jeu & Contrôles » est rempli**.

Suite immédiate sur les réglages, dans l'ordre : onglet **Affichage** (le moteur fait tout,
prévoir la confirmation à rebours de 10 s sur la résolution), onglet **Graphismes** (les dix
curseurs de `UGameUserSettings` ; végétation et distance d'affichage comptent double avec
SoStylized), onglet **Audio** quand des `SoundClass` existeront, et enfin le **remappage des
touches** via `UEnhancedInputUserSettings` — le seul morceau réellement coûteux.

Prochaine étape gameplay recommandée : **spawner de ressources avec repousse**
(`AResourceSpawner`, liste pondérée de DataAssets, rayon, densité, délai). Sans lui la carte se
vide en dix minutes.

Ensuite, par ordre de valeur : craft, objet visible en main, coffres, sauvegarde,
cycle jour/nuit.
