diff --git a/Patchs/fix_bridge/PlayerAgrandissementBridge.cs b/Patchs/fix_bridge/PlayerAgrandissementBridge.cs
new file mode 100644
index 0000000..21b1fc0
--- /dev/null
+++ b/Patchs/fix_bridge/PlayerAgrandissementBridge.cs
@@ -0,0 +1,27 @@
+// PlayerAgrandissementBridge.cs
+
+using UnityEngine;
+using Mirror;
+
+///
+/// Bridge Mirror : composant a ajouter au prefab du joueur pour qu'il puisse
+/// envoyer une Cmd d'agrandissement vers le serveur (car les [Command] ne peuvent
+/// etre appelees que depuis un NetworkBehaviour porte par le joueur local).
+///
+/// A placer sur : le prefab du joueur (celui assigne dans NetworkManager.playerPrefab).
+/// Sans ce composant sur le joueur, les clients ne pourront pas demander d'agrandissement.
+///
+public class PlayerAgrandissementBridge : NetworkBehaviour
+{
+ [Command]
+ public void CmdDemanderAgrandissement(int salleId, string direction)
+ {
+ if (SynchronisationAgrandissement.Instance == null)
+ {
+ Debug.LogError("[PlayerAgrandissementBridge] Instance SynchronisationAgrandissement introuvable cote serveur !");
+ return;
+ }
+
+ SynchronisationAgrandissement.Instance.TraiterDemandeServeur(salleId, direction);
+ }
+}
diff --git a/Patchs/fix_bridge/README_FIX.md b/Patchs/fix_bridge/README_FIX.md
new file mode 100644
index 0000000..07058a2
--- /dev/null
+++ b/Patchs/fix_bridge/README_FIX.md
@@ -0,0 +1,29 @@
+# Fix : PlayerAgrandissementBridge introuvable dans Add Component
+
+## Cause
+
+Unity exige qu'un MonoBehaviour/NetworkBehaviour soit dans un fichier `.cs` portant SON nom pour être exposé dans `Add Component`. Les 2 classes étaient dans le même fichier `SynchronisationAgrandissement.cs` — Unity exposait seulement la 1re.
+
+## Ce que contient ce fix
+
+1. **`SynchronisationAgrandissement.cs`** (nettoyé)
+ → La 2e classe `PlayerAgrandissementBridge` a été retirée
+
+2. **`PlayerAgrandissementBridge.cs`** (nouveau fichier)
+ → Contient uniquement la classe du bridge, dans son propre fichier
+
+## Actions à faire dans Unity
+
+1. **Remplacer** `Assets/Scripts/SynchronisationAgrandissement.cs` par la nouvelle version
+
+2. **Ajouter** `Assets/Scripts/PlayerAgrandissementBridge.cs` (nouveau fichier)
+
+3. **Attendre la compilation** (quelques secondes)
+
+4. **Ouvrir le prefab du joueur** et `Add Component` → taper `PlayerAgrandissementBridge` → il apparaît maintenant ✅
+
+## Vérif
+
+Si le composant n'apparaît TOUJOURS pas après ces étapes :
+- Regarder la console Unity pour des erreurs rouges de compilation
+- `Assets` → `Reimport All` (en dernier recours)
diff --git a/Patchs/fix_bridge/SynchronisationAgrandissement.cs b/Patchs/fix_bridge/SynchronisationAgrandissement.cs
new file mode 100644
index 0000000..feffb04
--- /dev/null
+++ b/Patchs/fix_bridge/SynchronisationAgrandissement.cs
@@ -0,0 +1,261 @@
+// SynchronisationAgrandissement.cs
+
+using UnityEngine;
+using Mirror;
+using System.Collections.Generic;
+
+///
+/// Singleton NetworkBehaviour qui synchronise les agrandissements de salle entre
+/// le serveur dedicated et tous les clients.
+///
+/// Pattern :
+/// 1. Un client clique [E] sur un panneau d'agrandissement
+/// -> AgrandissementSalle.DemanderAgrandir() trouve le singleton et appelle CmdAgrandir(id)
+/// 2. Cote serveur, CmdAgrandir valide (pas deja agrandi) et diffuse RpcLancerAgrandissement(id)
+/// 3. Chaque client (+ serveur) recoit le Rpc et execute l'animation locale d'Agrandir()
+/// en parallele. Tous voient la meme animation car les parametres sont identiques.
+/// 4. Un client qui rejoint en cours de partie recoit la SyncList des agrandissements deja
+/// faits et les rejoue instantanement (sans animation).
+///
+/// A placer : en composant sur le GameObject du NetworkManager (ou tout objet avec
+/// NetworkIdentity configure pour exister des le demarrage reseau).
+///
+/// L'identifiant d'un agrandissement est "salleId_direction", ex: "1_Nord".
+///
+public class SynchronisationAgrandissement : NetworkBehaviour
+{
+ public static SynchronisationAgrandissement Instance { get; private set; }
+
+ // Liste synchronisee des agrandissements deja effectues
+ // Format des entrees : "salleId_Direction" (ex: "1_Nord", "2_Est")
+ private readonly SyncList _agrandissementsEffectues = new SyncList();
+
+ private void Awake()
+ {
+ if (Instance != null && Instance != this)
+ {
+ Debug.LogWarning("[SyncAgrandissement] Instance deja existante, destruction de ce duplicata");
+ Destroy(this);
+ return;
+ }
+ Instance = this;
+ }
+
+ private void OnDestroy()
+ {
+ if (Instance == this) Instance = null;
+ }
+
+ // ============================================================
+ // CLIENT : appel par AgrandissementSalle.DemanderAgrandir()
+ // ============================================================
+
+ ///
+ /// Appele par un client qui veut agrandir. Envoie la demande au serveur.
+ /// En mode solo (pas de Mirror actif), execute directement localement.
+ ///
+ public void DemanderAgrandissement(int salleId, string direction)
+ {
+ string id = ConstruireId(salleId, direction);
+
+ // Mode solo (pas de serveur Mirror demarre) : execution directe locale
+ if (!NetworkServer.active && !NetworkClient.active)
+ {
+ Debug.Log($"[SyncAgrandissement] Mode solo, execution locale directe : {id}");
+ ExecuterAgrandissementLocal(salleId, direction, false);
+ return;
+ }
+
+ // Mode multi : Cmd vers serveur
+ // Il faut que le client ait authority. On passe par le player local qui
+ // porte ce role, ou directement si on est serveur nous-meme.
+ if (NetworkServer.active)
+ {
+ // Host ou dedicated : on est serveur, on peut traiter directement
+ TraiterDemandeServeur(salleId, direction);
+ }
+ else if (NetworkClient.active && NetworkClient.connection != null)
+ {
+ // Client pur : on doit passer par un PlayerBridge qui porte isLocalPlayer
+ PlayerAgrandissementBridge bridge = TrouverBridgeLocal();
+ if (bridge != null)
+ {
+ bridge.CmdDemanderAgrandissement(salleId, direction);
+ }
+ else
+ {
+ Debug.LogError("[SyncAgrandissement] Aucun PlayerAgrandissementBridge trouve sur le joueur local !");
+ }
+ }
+ }
+
+ // ============================================================
+ // SERVEUR : validation + broadcast
+ // ============================================================
+
+ ///
+ /// Appele cote serveur (soit par un host qui joue, soit par le bridge d'un client).
+ /// Valide et diffuse aux clients.
+ ///
+ [Server]
+ public void TraiterDemandeServeur(int salleId, string direction)
+ {
+ string id = ConstruireId(salleId, direction);
+
+ // Validation
+ if (_agrandissementsEffectues.Contains(id))
+ {
+ Debug.LogWarning($"[SyncAgrandissement] Demande refusee, deja agrandi : {id}");
+ return;
+ }
+
+ // Enregistrer dans la liste synchronisee (pour rejoin)
+ _agrandissementsEffectues.Add(id);
+ Debug.Log($"[SyncAgrandissement] Agrandissement valide : {id} (total : {_agrandissementsEffectues.Count})");
+
+ // Diffuser a tous les clients (le host le recoit aussi)
+ RpcLancerAgrandissement(salleId, direction);
+ }
+
+ // ============================================================
+ // CLIENTS : reception du Rpc
+ // ============================================================
+
+ [ClientRpc]
+ private void RpcLancerAgrandissement(int salleId, string direction)
+ {
+ Debug.Log($"[SyncAgrandissement] Rpc recu, execution agrandissement : salle {salleId} direction {direction}");
+ ExecuterAgrandissementLocal(salleId, direction, false);
+ }
+
+ // ============================================================
+ // REJOIN : un nouveau client rejoue l'etat actuel
+ // ============================================================
+
+ public override void OnStartClient()
+ {
+ base.OnStartClient();
+
+ // Ne pas rejouer sur le host (il est deja a jour, c'est lui le serveur)
+ if (NetworkServer.active) return;
+
+ // Le SyncList n'est pas forcement deja rempli a ce moment-la.
+ // On se branche sur ses callbacks et on rejoue les entrees existantes.
+ _agrandissementsEffectues.Callback += OnAgrandissementsListChanged;
+
+ // Rejouer immediatement les entrees deja presentes
+ if (_agrandissementsEffectues.Count > 0)
+ {
+ Debug.Log($"[SyncAgrandissement] Client rejoint : rejeu de {_agrandissementsEffectues.Count} agrandissement(s) passe(s)");
+ foreach (string id in _agrandissementsEffectues)
+ {
+ RejouerInstantane(id);
+ }
+ }
+ }
+
+ public override void OnStopClient()
+ {
+ base.OnStopClient();
+ _agrandissementsEffectues.Callback -= OnAgrandissementsListChanged;
+ }
+
+ private void OnAgrandissementsListChanged(SyncList.Operation op, int index, string oldItem, string newItem)
+ {
+ // On ignore les changements qui arrivent par le flux normal (deja gere par Rpc)
+ // Ce callback ne sert qu'au cas ou la SyncList est modifiee avant que le client recoive
+ // le Rpc correspondant (race condition rare). Dans ce cas on rejoue aussi.
+ // En pratique on s'en remet surtout au rejeu initial dans OnStartClient().
+ }
+
+ private void RejouerInstantane(string id)
+ {
+ int salleId;
+ string direction;
+ if (!DecomposerId(id, out salleId, out direction))
+ {
+ Debug.LogWarning($"[SyncAgrandissement] Id mal forme : {id}");
+ return;
+ }
+ ExecuterAgrandissementLocal(salleId, direction, true);
+ }
+
+ // ============================================================
+ // EXECUTION LOCALE (cote serveur ET cote client)
+ // ============================================================
+
+ ///
+ /// Execute l'agrandissement sur l'instance locale : trouve le bon mur et lance Agrandir().
+ /// Si instantane=true, skip les animations (pour rejoin).
+ ///
+ private void ExecuterAgrandissementLocal(int salleId, string direction, bool instantane)
+ {
+ AgrandissementSalle mur = TrouverMurAgrandissement(salleId, direction);
+ if (mur == null)
+ {
+ Debug.LogWarning($"[SyncAgrandissement] Mur introuvable : salle {salleId} direction {direction}");
+ return;
+ }
+
+ if (mur.estAgrandi || mur.enAnimation)
+ {
+ Debug.Log($"[SyncAgrandissement] Agrandissement deja lance ou termine localement, skip");
+ return;
+ }
+
+ mur.AgrandirLocal(instantane);
+ }
+
+ private AgrandissementSalle TrouverMurAgrandissement(int salleId, string direction)
+ {
+ AgrandissementSalle.DirectionAgrandissement dirEnum;
+ if (!System.Enum.TryParse(direction, out dirEnum)) return null;
+
+ AgrandissementSalle[] tous = FindObjectsOfType();
+ foreach (var a in tous)
+ {
+ if (a.direction != dirEnum) continue;
+ SalleDatacenter salle = FindObjectOfType();
+ if (salle == null) continue;
+ if (salle.salleId == salleId) return a;
+ }
+
+ // Fallback : si aucun salleId ne matche (salle mono, pas encore enregistree
+ // par le GestionnaireMultiSalles au moment de l'appel), on renvoie n'importe
+ // quel mur dans la bonne direction.
+ foreach (var a in tous)
+ {
+ if (a.direction == dirEnum) return a;
+ }
+
+ return null;
+ }
+
+ private PlayerAgrandissementBridge TrouverBridgeLocal()
+ {
+ PlayerAgrandissementBridge[] tous = FindObjectsOfType();
+ foreach (var b in tous)
+ {
+ if (b.isLocalPlayer) return b;
+ }
+ return null;
+ }
+
+ // ============================================================
+ // HELPERS ID
+ // ============================================================
+
+ private static string ConstruireId(int salleId, string direction) => $"{salleId}_{direction}";
+
+ private static bool DecomposerId(string id, out int salleId, out string direction)
+ {
+ salleId = -1;
+ direction = "";
+ if (string.IsNullOrEmpty(id)) return false;
+ int sep = id.IndexOf('_');
+ if (sep <= 0 || sep >= id.Length - 1) return false;
+ if (!int.TryParse(id.Substring(0, sep), out salleId)) return false;
+ direction = id.Substring(sep + 1);
+ return true;
+ }
+}