Optimiser les performances d'un serveur S&Box

Optimiser les performances d'un serveur S&Box

Source 2 + .NET 9 + C# : ce qui consomme vraiment du CPU et de la RAM sur S&Box, comment monitorer, et comment tuner l'allocation chez VeryCloud (et le gamemode côté code).

Introduction

S&Box est techniquement bien plus lourd que GMod : moteur Source 2, runtime .NET 9, physique avancée, scripts C# JIT-compilés. Comprendre ce qui consomme est la clé pour choisir le bon plan et tuner son gamemode. Ce guide te donne les leviers serveur et les bonnes pratiques côté développement.

Prérequis

  • Un serveur S&Box actif chez VeryCloud
  • Accès aux graphes ressources dans le panel Wisp
  • Si tu développes ton gamemode : connaissance C# de base

Étape 1 : Comprendre la charge S&Box

Les principaux consommateurs de ressources :

RessourceSource de charge
CPUPhysique Source 2, tick du gamemode, JIT .NET, IA, scripts
RAMAssets chargés, scènes complexes, NetList/NetDictionary, allocations C#
RéseauSync des entités, props physiques, Rpc custom
DisqueFaible en runtime (cloud packages cachés), pic au boot

Source 2 utilise mieux le multi-thread que Source 1, mais la majorité du gameplay reste sur un thread principal dont la fréquence du CPU compte plus que le nombre de cœurs.

Étape 2 : Monitoring depuis Wisp

Dans la Console du panel, tu as des graphes temps réel :

  • CPU usage : si tu satures un cœur (souvent visible en %), c'est le tick gamemode qui rame
  • Memory usage : si tu approches la limite RAM allouée à ton plan, c'est leak ou assets trop lourds
  • Disk I/O : devrait rester bas en runtime ; un pic continu indique souvent un mauvais logging

Étape 3 : Choisir le bon plan VeryCloud

Les offres S&Box VeryCloud sont calibrées pour différents profils :

PlanCPURAMIdéal pour
SboxDev2 vCPU2 GoTest, dev, friend party
SboxPlus4 vCPU8 GoSandbox public 16-24 joueurs
SboxPro10 vCPU32 GoGamemode lourd RP / Battle Royale 32+

Règle simple : si ton CPU plafonne >80% pendant les pics, monte d'un plan. Si la RAM est OK mais que ça tick mal, c'est l'horloge CPU qui manque.

Étape 4 : Optimisations côté gamemode (C#)

Si tu écris ton propre gamemode, quelques règles d'or :

Éviter les allocations dans la boucle tick

// MAUVAIS : alloue une liste à chaque tick
protected override void OnFixedUpdate()
{
    var players = new List<Player>();
    foreach (var c in Scene.GetAllComponents<Player>())
        players.Add(c);
}

// BON : réutilise la liste
private List<Player> _players = new();
protected override void OnFixedUpdate()
{
    _players.Clear();
    foreach (var c in Scene.GetAllComponents<Player>())
        _players.Add(c);
}

Utiliser [Sync] avec parcimonie

Chaque propriété [Sync] génère du trafic réseau. Synchronise uniquement ce qui doit vraiment être vu côté client.

[Rpc.Broadcast] vs [Rpc.Owner]

Préfère [Rpc.Owner] ou [Rpc.Host] quand un seul destinataire est concerné. Le broadcast envoie à tout le monde, coûteux à grande échelle.

Étape 5 : Réduire les assets côté serveur

Le serveur charge tous les modèles et matériels référencés par la scène, même s'il ne les rend pas. Quelques pistes :

  • Limiter le nombre de props uniques dans une map
  • Éviter les LOD inutiles côté serveur (la collision est ce qui compte vraiment)
  • Préférer des matériaux partagés entre props similaires

Étape 6 : Schedules pour des restarts planifiés

Pour éviter l'accumulation lente de mémoire (typique en .NET avec des GC LOH non collectés), planifie des restarts :

  1. Dans Wisp, ouvre Schedules
  2. Crée un schedule Daily ou Weekly
  3. Action : Power → Restart
  4. Heure : creuse (3h du matin par exemple)

Annonce le restart 5 min avant côté gamemode (say ou broadcast) pour éviter de couper une session en cours.

Étape 7 : Dépannage de pics CPU spécifiques

Si tu vois un pic CPU à 100% qui dure :

  1. Console → status : vérifie qu'il n'y a pas un nombre absurde d'entités
  2. Demande à un joueur de te dire ce qui se passe juste avant le pic (souvent un script de gamemode bouclé)
  3. Si tu as le code source du gamemode, regarde les OnFixedUpdate et les boucles longues
  4. Restart pour stopper l'effet immédiat, puis investigue à froid

Dépannage

RAM qui grimpe lentement et ne redescend pas

  • Memory leak C# (souvent dans des events souscrits jamais désouscrits)
  • Restarts planifiés en attendant de fixer le code
  • Profilage avec dotMemory ou perfview si tu peux récupérer un dump

TPS / framerate serveur qui chute avec beaucoup de joueurs

  • Trop d'allocations par tick (voir étape 4)
  • Trop de RPC broadcast
  • Sync de propriétés inutiles

Lag spikes périodiques

  • GC .NET en train de collecter — alloue moins
  • I/O disque (logs trop verbeux)

Commandes utiles

# Voir l'usage CPU/RAM dans la console Wisp
# -> graphique en haut de la vue Console

# Forcer un GC manuel (depuis le code C# du gamemode)
GC.Collect();
GC.WaitForPendingFinalizers();

Conclusion

Optimiser S&Box, c'est 80% du gamemode (code C#) et 20% de l'allocation serveur. Le hardware VeryCloud est calibré pour absorber du Source 2 sérieux, mais aucune machine ne compense un gamemode qui alloue 50 listes par tick. Profile, mesure, restart régulièrement.

Pour aller plus loin : profiling avec dotMemory, JetBrains Rider profiler, observability via Prometheus exporter custom dans ton gamemode.

Ressources

Rejoignez notre serveur communautaire Discord

Pour toute question, suggestion ou simplement pour discuter avec la communauté, rejoignez-nous sur Discord !

900+Membres