Torna al Blog

Come padroneggiare l'Asset Stripping per Unreal Engine Dedicated Server (Step by Step)

Pubblicato il 17 marzo 2026
Come padroneggiare l'Asset Stripping per Unreal Engine Dedicated Server (Step by Step)

Avvii il tuo Unreal Engine dedicated server appena compilato, aspettandoti un processo headless leggero. Esegui un memory profile ed eccoli lì: migliaia di oggetti UMaterial, UTexture e USoundWave che occupano la RAM del tuo server.

La documentazione ufficiale afferma che un server headless non renderizza elementi visivi. Allora perché il tuo server sta accumulando megabyte di dati di texture?

Ogni sviluppatore indie conosce il momento in cui i costi di hosting iniziano a minacciare il budget. Quando una macchina bare-metal può ospitare solo 10 istanze del tuo gioco invece di 50 a causa del memory bloat, la tua architettura backend è compromessa.

In questo approfondimento, analizzeremo come funziona realmente l'unreal engine dedicated server asset stripping, perché i ghost assets rimangono in memoria e come strutturare il tuo C++ e i Blueprint per eliminarli completamente.

L'anatomia di un "Ghost Asset" su un Dedicated Server

Per risolvere il problema, devi prima capire cosa fa l'Unreal Automation Tool (UAT) quando esegui il cook per il target Server.

Quando uno sviluppatore vede UTexture o UMaterial in un profilo di memoria del server, la prima ipotesi è che l'engine non sia riuscito a fare lo stripping dell'asset. Questo è vero solo in parte.

Unreal Engine separa gli asset in due parti distinte:

  1. Il UObject Wrapper: Metadati, proprietà e dati di reflection.
  2. Il Bulk Data: Il carico pesante (dati pixel compressi DXT per le texture, vertex buffers per i mesh, dati PCM per l'audio).

Quando cucini un dedicated server, il cooker elimina correttamente i bulk data. I dati di rendering spariscono. Tuttavia, il wrapper UObject rimane.

Se un Blueprint Class Default Object (CDO) ha una hard reference a una UTexture2D, il server deve istanziare l'UObject UTexture2D per soddisfare il sistema di reflection ed evitare crash da null pointer. Anche se i bulk data sono eliminati e la texture occupa solo 1KB invece di 10MB, l'overhead di istanziare 50.000 di questi UObjects si traduce in un memory bloat significativo e in un sovraccarico per il Garbage Collection.

Audio e Particelle seguono la stessa logica?

Sì. Se hai una hard reference a un USoundCue o un UNiagaraSystem, il server caricherà l'UObject. I pesanti dati audio PCM vengono eliminati, ma l'oggetto esiste.

Con i sistemi particellari, questo è pericoloso. Sebbene il rendering visivo venga saltato, se un sistema particellare contiene logica eseguita dalla CPU (come simulazioni Niagara complesse), il server potrebbe eseguire il tick di quella logica, consumando cicli CPU preziosi.

Step 1: Profiling del Memory Bloat del Server

Prima di smontare il codice, servono numeri concreti. Non puoi ottimizzare ciò che non puoi misurare.

Avvia il tuo dedicated server pacchettizzato con i seguenti argomenti da riga di comando:

-LLM -LLMCSV -memoryprofiler

Una volta avviato, apri la console del server ed esegui:

memreport -full

Cerca Obj List nel file .memreport generato. Vedrai probabilmente qualcosa di simile:

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

Anche se 2.5MB sembrano pochi, è solo la dimensione grezza dell'oggetto. Considerando l'allineamento della memoria e le dipendenze a cascata, una piccola catena di riferimenti visivi può gonfiare un server da 150MB a oltre 600MB.

Per approfondire la gestione delle risorse, leggi la nostra analisi su architecting zero-waste servers.

Step 2: Eliminare le Hard References con i Soft Pointers

La causa principale dei ghost assets sono le hard references. Se la tua classe ACharacter ha un hard pointer a un ritratto UI, il server caricherà quell'asset.

La soluzione C++: TSoftObjectPtr

Sostituisci i riferimenti hard visivi/audio con soft references. Queste memorizzano solo il percorso dell'asset; l'UObject non viene caricato finché non chiami LoadSynchronous() o usi lo Streamable Manager.

MALE: Hard Reference (Carica sul Server)

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

BENE: Soft Reference (Il Server resta pulito)

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

Step 3: Forzare NeedsLoadForServer

Puoi dire al sistema di packaging di ignorare componenti puramente visivi sovrascrivendo NeedsLoadForServer.

bool UMyVisualCustomizationComponent::NeedsLoadForServer() const
{
    return false; // Garantisce che il componente sia rimosso dalla memoria del server
}

Step 4: Stripping via Configurazione

In DefaultEngine.ini, puoi escludere intere cartelle dal cook:

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

In YourGameServer.Target.cs, puoi disabilitare l'audio engine:

bDisableAudio = true; 

Best Practices per l'ottimizzazione della memoria

  1. Separare Mesh di Collisione da Mesh Visivi: Usa un UStaticMesh semplificato per il server.
  2. Audit dei Construction Scripts: Usa Switch Has Authority per evitare che il server istanzi effetti visivi.
  3. Isolare i Data Assets: Separa i dati statistici (server/client) dai dati visivi (solo client).
  4. Automatizzare il Profiling in CI/CD: Controlla l'impronta di memoria a ogni build.

Scalare il tuo Backend ottimizzato

Ridurre l'impronta del server da 800MB a 180MB è una vittoria tecnica enorme. Puoi ospitare 4-5 volte più istanze, riducendo i costi di AWS o Google Cloud.

Ma orchestrare questi server è complesso. Con horizOn, questi servizi sono pre-configurati. Carica la tua build Linux ottimizzata e horizOn gestirà l'auto-scaling e l'orchestrazione globale.

Conclusioni

L'asset stripping di Unreal Engine è potente ma dipende dalla tua architettura. Usando soft pointers e separando i dati visivi dal gameplay, otterrai le performance necessarie per il multiplayer.

Pronto a scalare? Prova horizOn gratuitamente o consulta la nostra documentazione API.


Fonte: Stripping asset on dedicated server