Retour au Blog

Maîtriser l'Asset Stripping pour Unreal Engine Dedicated Server (Guide étape par étape)

Publié le 17 mars 2026
Maîtriser l'Asset Stripping pour Unreal Engine Dedicated Server (Guide étape par étape)

Vous lancez votre Unreal Engine dedicated server fraîchement compilé, en espérant un processus léger et headless. Vous effectuez un memory profile, et là, surprise : des milliers d'objets UMaterial, UTexture et USoundWave occupent la RAM de votre serveur.

La documentation officielle stipule qu'un serveur headless ne calcule pas de visuels. Alors pourquoi votre serveur monopolise-t-il des mégaoctets de données de textures ?

Tout développeur indie connaît ce moment où les coûts d'hébergement menacent la survie du projet. Quand une machine bare-metal ne peut héberger que 10 instances de votre jeu au lieu de 50 à cause du memory bloat, c'est votre architecture backend qui est compromise.

Dans cette analyse technique, nous allons disséquer le fonctionnement réel de l'unreal engine dedicated server asset stripping, comprendre pourquoi des ghost assets restent en mémoire, et comment architecturer votre C++ et vos Blueprints pour les éradiquer.

L'anatomie d'un "Ghost Asset" sur un Dedicated Server

Pour corriger le problème, il faut d'abord comprendre ce que fait l'Unreal Automation Tool (UAT) lors du cook pour la cible Server.

Lorsqu'un développeur voit UTexture ou UMaterial dans un profil de mémoire de serveur, il suppose souvent que l'engine a échoué à stripper l'asset. Ce n'est que partiellement vrai.

Unreal Engine sépare les assets en deux parties :

  1. Le UObject Wrapper : Les métadonnées, propriétés et données de réflexion.
  2. Le Bulk Data : Les données lourdes (pixels compressés DXT pour les textures, vertex buffers pour les meshes, données PCM pour l'audio).

Lors du cook d'un dedicated server, le cooker réussit à stripper le bulk data. Les données de rendu disparaissent. Cependant, le UObject wrapper reste.

Si un Blueprint Class Default Object (CDO) possède une hard reference vers une UTexture2D, le serveur doit instancier l'UObject UTexture2D pour satisfaire le système de réflexion et éviter les plantages de pointeurs nuls. Même si le bulk data est supprimé et que la texture ne consomme que 1 Ko au lieu de 10 Mo, l'overhead de l'instanciation de 50 000 de ces UObjects génère un memory bloat et une surcharge du Garbage Collection significatifs.

L'audio et les particules suivent-ils la même logique ?

Oui. Si vous avez une hard reference vers un USoundCue ou un UNiagaraSystem, le serveur chargera l'UObject. Les données audio PCM lourdes sont supprimées, mais l'objet existe.

C'est particulièrement dangereux avec les systèmes de particules. Bien que le rendu visuel soit ignoré, si un système contient une logique CPU (simulations Niagara complexes ou événements de collision), le serveur pourrait exécuter ce tick de logique s'il n'est pas configuré correctement, consommant des cycles CPU précieux.

Étape 1 : Profilage du Memory Bloat du serveur

Avant de modifier votre code, il vous faut des chiffres concrets. On ne peut pas optimiser ce qu'on ne peut pas mesurer.

Lancez votre dedicated server packagé avec les arguments suivants :

-LLM -LLMCSV -memoryprofiler

Une fois le serveur lancé, ouvrez la console et exécutez :

memreport -full

Cherchez Obj List dans le fichier .memreport généré. Vous verrez probablement ceci :

Class UTexture2D: 1452 Objects, 1.25 MB
Class UMaterial: 840 Objects, 0.85 MB
Class USoundWave: 620 Objects, 0.45 MB

Bien que 2,5 Mo semblent peu, ce n'est que la taille brute des objets. Avec l'alignement mémoire, les name pool strings et les dépendances en cascade, une petite chaîne de références visuelles peut faire gonfler un serveur de 150 Mo à plus de 600 Mo.

Pour plus d'infos sur la gestion agressive des ressources, lisez notre analyse sur l'architecture des serveurs zero-waste.

Étape 2 : Rompre les Hard References avec les Soft Pointers

La cause principale des ghost assets est l'usage de hard references. Si votre classe ACharacter possède un hard pointer vers un portrait d'UI, le serveur chargera cet asset.

La solution C++ : TSoftObjectPtr

Remplacez vos références visuelles/audio par des soft references. Elles stockent uniquement le chemin de l'asset. L'UObject n'est chargé en mémoire que lors d'un appel à LoadSynchronous() ou via le Streamable Manager.

MAUVAIS : Hard Reference (Charge sur le serveur)

UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "UI")
UTexture2D* HeroPortrait;

BON : Soft Reference (Le serveur reste propre)

UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "UI")
TSoftObjectPtr<UTexture2D> HeroPortraitSoft;

Côté client, vérifiez le net mode et chargez de manière asynchrone :

void AHeroCharacter::PlayUltimateVFX()
{
    if (GetNetMode() == NM_DedicatedServer) return;
    
    if (UltimateAbilityVFXSoft.IsPending())
    {
        UNiagaraSystem* LoadedVFX = UltimateAbilityVFXSoft.LoadSynchronous();
        // ... logique de spawn
    }
}

Étape 3 : Forcer NeedsLoadForServer

Vous pouvez dire au système de packaging d'ignorer totalement certains composants visuels en surchargeant NeedsLoadForServer.

bool UMyVisualCustomizationComponent::NeedsLoadForServer() const
{
    return false; // Garantit que le composant est supprimé de la mémoire serveur
}

Étape 4 : Stripping via la Configuration

Dans votre DefaultEngine.ini, vous pouvez exclure des répertoires entiers du cook :

[/Script/UnrealEd.ProjectPackagingSettings]
+DirectoriesToNeverCook=(Path="UI/Widgets")

Dans votre YourGameServer.Target.cs, vous pouvez désactiver le moteur audio :

bDisableAudio = true; 

Bonnes pratiques pour l'optimisation mémoire

  1. Séparer les Meshes de Collision des Meshes Visuels : Utilisez un UStaticMesh simplifié et invisible pour le serveur.
  2. Auditer les Construction Scripts : Utilisez Switch Has Authority pour éviter que le serveur n'instancie des effets visuels.
  3. Isoler les Data Assets : Séparez les stats (serveur/client) des visuels (client uniquement).
  4. Automatiser le Profiling en CI/CD : Vérifiez l'empreinte mémoire à chaque build.
  5. Modules ServerOnly et ClientOnly : Séparez physiquement le code pour empêcher les références croisées.

Passer à l'échelle avec un Backend optimisé

Réduire l'empreinte de votre serveur de 800 Mo à 180 Mo est une victoire technique majeure. Vous pouvez héberger 4 à 5 fois plus d'instances, réduisant drastiquement vos coûts AWS ou Google Cloud.

Mais orchestrer ces serveurs est un défi. Avec horizOn, ces services sont pré-configurés. Téléchargez votre build Linux optimisée, et horizOn gère l'auto-scaling et l'orchestration mondiale.

Conclusion

L'asset stripping d'Unreal Engine est puissant mais dépend de votre architecture. En migrant vers les soft pointers et en séparant les données visuelles du gameplay, vous obtiendrez les performances requises pour le multijoueur.

Prêt à scaler ? Essayez horizOn gratuitement ou consultez notre doc API.


Source : Stripping asset on dedicated server