# Sync multi des nouvelles salles (GestionnaireMultiSalles v2.0) ## Contexte Ton dernier test a révélé que j'avais synchronisé le mauvais système : - Tu utilises **`GestionnaireMultiSalles`** (achat "Nouvelle salle Ouest/Est/Nord/Sud" au Terminal) - J'avais synchronisé **`AgrandissementSalle`** (panneau mural, qui n'est plus utilisé) Ce pack corrige ça. ## Ce qui change Un seul fichier patché : **`GestionnaireMultiSalles.cs` v2.0** Changements : 1. La classe passe de `MonoBehaviour` à **`NetworkBehaviour`** 2. Ajout d'une **`SyncList`** qui contient les créations de salles (ex: `"1_Ouest"`, `"2_Nord"`) 3. Ajout d'un **`[ClientRpc] RpcLancerConstructionSalle`** qui broadcast l'ordre aux clients 4. `CreerNouvelleSalle` côté serveur : - Enregistre dans la SyncList (pour rejoin) - Broadcast le Rpc aux clients 5. Chaque instance (serveur + clients) exécute l'animation **localement** via `AnimationCreationSalleLocal` 6. Nouvelle méthode `OnStartClient` : les clients qui rejoignent en cours de partie relisent la SyncList et rejouent toutes les salles en mode **instantané** (pas d'animation) 7. Le code de génération est refactorisé : la partie "construire la géométrie de la salle + couloir" est extraite dans `CreerSalleGeometrie` pour être réutilisée par le flux normal ET le rejoin 8. Gardes `DedicatedServerMode.IsDedicatedServer` ajoutées partout où du Material/Light est créé (pas de shaders côté serveur) ## Setup Inspector **Important** : `GestionnaireMultiSalles` est maintenant un `NetworkBehaviour`, donc il a besoin d'un `NetworkIdentity` sur son GameObject. ### Étapes 1. Dans la scène `Datacenter_01`, trouver le GameObject qui porte le composant `GestionnaireMultiSalles` 2. Si ce GameObject n'a **pas** de `NetworkIdentity` : - `Add Component` → `NetworkIdentity` - Dans l'Inspector du `NetworkIdentity`, **ne coche rien** (ni "Server Only" ni "Local Player Authority" — c'est un objet serveur autoritaire qui synchronise via la SyncList) 3. Sauver la scène (`Ctrl+S`) ### Note sur les autres composants Tu peux **retirer** maintenant : - `SynchronisationAgrandissement` (de la scène) - `PlayerAgrandissementBridge` (du prefab joueur) - Les 2 fichiers `.cs` correspondants (si tu veux nettoyer) Puisque `AgrandissementSalle` n'est plus utilisé dans ta version actuelle, les 2 scripts que j'avais livrés hier ne servent plus à rien. Tu peux les garder dans le code mort s'il te semble possible d'y revenir plus tard. ## Actions à faire 1. **Remplacer** `Assets/Scripts/GestionnaireMultiSalles.cs` par la nouvelle version 2. **Vérifier / ajouter** `NetworkIdentity` sur le GameObject qui porte ce composant 3. **Sauver la scène** 4. **Build client Windows** (pour pouvoir tester) 5. **Build Dedicated Server Linux** et déployer sur la Debian ## Test à faire ### Test 1 — Solo (éditeur Play) 1. Lancer l'éditeur en Play (pas host) 2. Aller au Terminal, acheter "Nouvelle salle Ouest" 3. **Attendu** : le mur explose, couloir apparaît, salle Ouest se construit comme avant ### Test 2 — Host + Client 1. Éditeur en Host, un build Windows connecté en client 2. Le **host** achète "Nouvelle salle Est" 3. **Attendu** : les DEUX voient la même animation + couloir + salle créée ### Test 3 — Client déclencheur 1. Host + Client 2. Le **client** achète "Nouvelle salle Nord" 3. **Attendu** : les DEUX voient la même animation ### Test 4 — Dedicated + 2 clients 1. Dedicated sur Debian + 2 clients Windows 2. Un client achète "Nouvelle salle Sud" 3. **Attendu** : les 2 clients voient l'animation synchrone, le serveur logue la création ### Test 5 — Rejoin 1. Dedicated + 1 client 2. Le client achète "Nouvelle salle Ouest" 3. Un **2e client** se connecte APRÈS 4. **Attendu** : le 2e client voit la nouvelle salle + le couloir déjà construits (rejeu instantané, pas d'anim) ## Diagnostic Dans les logs, tu devrais voir : **Côté serveur** : ``` [MultiSalles] Salle enregistree dans SyncList : 1_Ouest (total : 1) [MultiSalles] Debut construction locale salle Ouest depuis Salle 1 (instantane=False) [MultiSalles] Mur DC_MurEst percé avec morceaux latéraux [MultiSalles] Nouvelle salle creee localement : Salle 2 (15x10m) direction Ouest ``` **Côté client** : ``` [MultiSalles] Rpc recu : construction salle Ouest depuis parent id=1 [MultiSalles] Debut construction locale salle Ouest depuis Salle 1 (instantane=False) [MultiSalles] Mur DC_MurEst percé avec morceaux latéraux [MultiSalles] Nouvelle salle creee localement : Salle 2 (15x10m) direction Ouest ``` **Si rien ne se passe côté client** malgré le Rpc envoyé : - Vérifier que le GameObject qui porte `GestionnaireMultiSalles` a bien un `NetworkIdentity` - Vérifier dans Mirror Inspector que le NetworkBehaviour est bien enregistré **Si "Salle parente id=X introuvable localement, skip"** : - Problème de timing : le client n'a pas encore sa salle 1 enregistrée - Pas grave dans 99% des cas (la salle 1 s'enregistre au démarrage via `SalleDatacenter.Start()`), mais si ça arrive à un client qui rejoint tardivement, le rejeu va skipper proprement ## Ce qui n'est PAS encore synchronisé - **Les équipements placés dans les nouvelles salles** : quand un joueur pose une baie dans la salle 2, ça passe par `BoutiqueReseau.TraiterPlacementBaieServeur` qui utilise bien `NetworkServer.Spawn`, donc **c'est déjà synchronisé**. Pas de travail. - **L'état "mur percé" dans la SyncList** : je ne track pas séparément les percements de mur, je track la création de salle. Le percement est fait automatiquement quand la salle est créée (dans `AnimationCreationSalleLocal`). Donc pas de divergence possible. - **L'ordre des salles créées** : la SyncList conserve l'ordre d'insertion. Si un client rejoint, il rejoue dans l'ordre → pas de conflit. ## Architecture en un schéma ``` Client achete "Nouvelle salle Ouest" au Terminal │ ▼ BoutiqueReseau.DemanderCommandeSalle │ ▼ PlayerBoutiqueCommande.CmdCommanderSalle (deja en place, aucun changement) │ ▼ [SERVEUR] BoutiqueReseau.TraiterCommandeSalleServeur │ ▼ [SERVEUR] GestionnaireMultiSalles.CreerNouvelleSalle │ ├── Ajoute "1_Ouest" a _sallesSyncList (→ sync auto aux clients) │ └── RpcLancerConstructionSalle(1, "Ouest") │ ├── [CLIENT 1] StartCoroutine(AnimationCreationSalleLocal(1, "Ouest", false)) ├── [CLIENT 2] StartCoroutine(AnimationCreationSalleLocal(1, "Ouest", false)) └── [HOST si applicable] skip (deja joue cote serveur) [NOUVEAU CLIENT qui rejoint plus tard] │ ▼ OnStartClient : lit _sallesSyncList → rejoue chaque entree en mode instantane=true ```