# Agrandissement de salles — Synchronisation multijoueur ## Ce que fait ce pack Rend l'agrandissement de salle (clic [E] sur un panneau mural) **synchrone entre tous les joueurs** en multijoueur, tout en restant fonctionnel en solo. ## Architecture ``` Client joueur clique [E] │ ▼ PlayerInteraction.Ramasser() │ ▼ agr.DemanderAgrandir() ←─── [nouveau] │ ▼ SynchronisationAgrandissement.DemanderAgrandissement(salleId, direction) │ ├── Mode solo : execution directe locale │ └── Mode multi : │ ▼ PlayerAgrandissementBridge.CmdDemanderAgrandissement (sur le joueur local) │ ▼ Serveur : SynchronisationAgrandissement.TraiterDemandeServeur │ ├── Valide (pas deja agrandi dans cette direction) ├── Ajoute a la SyncList des agrandissements effectues │ ▼ RpcLancerAgrandissement(salleId, direction) │ ▼ Chaque client + serveur : AgrandirLocal(false) │ ▼ Animation identique chez tous (meme parametres → meme geometrie) ``` ## Script 1 — `SynchronisationAgrandissement.cs` (NOUVEAU) Contient deux classes : 1. **`SynchronisationAgrandissement`** — singleton NetworkBehaviour, orchestre tout 2. **`PlayerAgrandissementBridge`** — NetworkBehaviour a ajouter au prefab du joueur pour porter la `[Command]` ## Script 2 — `AgrandissementSalle.cs` (MODIFIÉ) Changements : - Nouvelle méthode `DemanderAgrandir()` : point d'entrée multi - Nouvelle méthode `AgrandirLocal(bool instantane)` : execute localement (avec ou sans anim) - `Agrandir()` conservée pour compat : équivaut à `AgrandirLocal(false)` - Toutes les coroutines d'animation (`ConstruireSol`, `ConstruireMurs`, `ConstruirePlafond`, `ConstruireEclairage`) acceptent un paramètre `skipVisuel` pour construire instantanément (rejeu client qui rejoint) - Gardes `DedicatedServerMode.IsDedicatedServer` sur la création de `Material`/`TextMesh`/debris - Layer `Emplacement` correctement appliqué aux emplacements de l'extension (il manquait dans l'original) ## Script 3 — `PlayerInteraction.cs` (MODIFIÉ) Un seul changement : ligne ~933, `agr.Agrandir()` remplacé par `agr.DemanderAgrandir()`. ## Étapes dans Unity ### 1. Remplacer les 3 scripts Copier dans `Assets/Scripts/` : - `SynchronisationAgrandissement.cs` (nouveau fichier) - `AgrandissementSalle.cs` (remplace l'existant) - `PlayerInteraction.cs` (remplace l'existant) ### 2. Ajouter `SynchronisationAgrandissement` à la scène Dans `Datacenter_01` : 1. Sélectionner le GameObject qui porte le `NetworkManager` 2. `Add Component` → `SynchronisationAgrandissement` 3. S'assurer que ce GameObject a un `NetworkIdentity` ; la plupart du temps le `NetworkManager` n'en a pas lui-même. Créer un enfant `SyncAgrandissement_Holder` avec un `NetworkIdentity` + le script si besoin. **Important** : pour que Mirror synchronise le `SyncList`, ce GameObject doit être spawné sur le réseau. Deux options : - **Option A (simple)** : le mettre dans `NetworkManager.spawnPrefabs` et le spawner au `OnStartServer` via un petit bootstrap - **Option B (scène)** : garder le GameObject dans la scène. Mirror va automatiquement le traiter comme un objet de scène avec `NetworkIdentity`. Dans ce cas, s'assurer que l'objet porte **un `NetworkIdentity`** et qu'il est présent **dès l'ouverture de la scène**. L'option B est ce que je recommande pour ton cas : Datacenter_01 est une scène fixe, tu ajoutes `SynchronisationAgrandissement` + `NetworkIdentity` sur un GameObject dédié, et Mirror le gère tout seul. ### 3. Ajouter `PlayerAgrandissementBridge` au prefab du joueur 1. Ouvrir le prefab du joueur (celui qui est dans `NetworkManager.playerPrefab`) 2. `Add Component` → `PlayerAgrandissementBridge` 3. Sauver le prefab Sans ce composant sur le joueur, les clients ne pourront pas envoyer leur `CmdDemanderAgrandissement` vers le serveur. ### 4. Rebuild - Client Windows (pour tester avec deux joueurs) - Dedicated Server Linux (pour déployer sur la Debian) ## Test à faire ### Test 1 — Mode solo 1. Lancer en éditeur (play mode normal, pas host) 2. Cliquer [E] sur un panneau d'agrandissement 3. **Attendu** : l'animation se lance comme avant, salle agrandie à la fin ### Test 2 — Mode host + client 1. Lancer l'éditeur en Host 2. Lancer un build client et le connecter 3. **Host** clique [E] sur un panneau 4. **Attendu** : les deux voient la même animation en même temps, les nouveaux emplacements apparaissent des deux côtés ### Test 3 — Client déclencheur 1. Host + client 2. **Client** clique [E] sur un panneau 3. **Attendu** : les deux voient l'animation, la SyncList côté serveur contient l'entrée ### Test 4 — Dedicated + 2 clients 1. Lancer le dedicated sur la Debian 2. Connecter 2 clients Windows 3. Un des clients clique [E] 4. **Attendu** : les 2 clients voient l'animation synchrone, le serveur logue la création de l'extension ### Test 5 — Rejoin 1. Dedicated + 1 client 2. Le client déclenche l'agrandissement 3. Un **2e client** se connecte APRÈS 4. **Attendu** : le 2e client voit l'extension instantanément (pas d'animation), l'état est cohérent ## Points d'attention ### GameEconomy Ton `GameEconomy` est en mode sandbox, donc les `TenterAchat` passent toujours. La validation économique serveur n'est pas implémentée dans ce pack, elle le sera quand tu sortiras du sandbox. ### Emplacements de baies Les `EmplacementBaie` de l'extension sont créés **localement sur chaque instance** (pas via `NetworkServer.Spawn`). C'est cohérent avec le pattern actuel de `SalleDatacenter.GenererEmplacementsBaies()` qui fonctionne déjà en multi. Les baies qui seront placées dessus continueront d'utiliser le flux `CmdPlacerBaie` qui spawne bien via `NetworkServer.Spawn` dans `BoutiqueReseau.TraiterPlacementBaieServeur`. ### Colliders sol + murs Ils sont créés **partout (serveur et clients)** car ils sont nécessaires pour : - Le CharacterController du joueur (marcher dans la nouvelle zone) - La physique des objets posés - Les raycasts d'interaction Pas de risque de "tomber dans le vide" côté serveur. ### Néons Sur le dedicated server, les `Light` ne sont pas créées (gain CPU + logs plus propres). Les clients les créent normalement. C'est sans impact gameplay. ## Workflow de debug Côté serveur dedicated, les logs à surveiller : ``` [SyncAgrandissement] Agrandissement valide : 1_Nord (total : 1) ``` Côté client : ``` [SyncAgrandissement] Rpc recu, execution agrandissement : salle 1 direction Nord AgrandissementSalle: PHASE 3 - Début construction sol AgrandissementSalle: PHASE 7 - Construction complète ! ``` Si tu vois : ``` [SyncAgrandissement] Mur introuvable : salle 1 direction Nord ``` Ça veut dire que le `salleId` ou la direction ne correspondent à aucun mur dans la scène. Vérifier que `SalleDatacenter.salleId` est bien = 1 (ou que le fallback "n'importe quel mur dans la bonne direction" trouve un match). Si tu vois : ``` [PlayerAgrandissementBridge] Instance SynchronisationAgrandissement introuvable cote serveur ! ``` Ça veut dire que le GameObject qui porte `SynchronisationAgrandissement` n'a pas bien été spawné côté serveur. Vérifier qu'il est présent dans la scène **au démarrage** (option B) ou dans `NetworkManager.spawnPrefabs` + spawné au `OnStartServer` (option A). ## Bugs connus limités 1. **Chat spam si plusieurs clients déclenchent en même temps** : si 2 clients cliquent [E] sur le même panneau dans la même frame, le serveur validera le premier et rejettera le second (log warning "deja agrandi"). Pas grave pour les joueurs. 2. **Anim qui démarre décalée** : la latence réseau entre Cmd et Rpc peut faire que les clients voient l'animation avec ~50-200ms de retard entre eux. Acceptable en coop standard. 3. **Animation coupée si un client disconnect pendant l'anim** : comme c'est local sur chaque client, ça ne casse rien pour les autres. Le joueur qui reconnect verra l'extension déjà construite via le rejeu. ## À implémenter plus tard (pas dans ce pack) - Validation économique serveur-side (quand tu sortiras du sandbox) - Persistence des agrandissements dans le SaveManager - Support multi-salles pour l'agrandissement (actuellement `SynchronisationAgrandissement` trouve `FindObjectOfType()`, donc ça ciblera toujours la salle 1 ; à affiner quand tu auras plusieurs salles agrandissables)