dcsim-gameserver/Patchs/sync_salles/README_SYNC_SALLES.md
2026-04-18 09:24:59 +00:00

6.7 KiB

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<string> 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 ComponentNetworkIdentity
    • 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