The Need for Level Streaming
Vast open worlds and intricately detailed massive stages provide players with the ultimate immersion. However, what plagues developers behind the scenes is maintaining performance.
"The game stutters every time I move across the map" "Loading times are too long and players are leaving"—these are eternal challenges in large-scale game development. This is because, in traditional single-level configurations, Unreal Engine (UE) tries to load the entire level (map) into memory at once.
The key to solving this problem and providing players with seamless, comfortable experiences is Level Streaming. This article thoroughly explains everything from level streaming basics to practical techniques for optimizing large-scale maps, for UE beginners to intermediate developers.
How Level Streaming Works and Its Benefits
Basic Concept
Level streaming is a feature that loads and unloads only the necessary levels (sub-levels) into memory based on the player's current location or game situation.
Instead of treating a large-scale world as one giant level, you divide it into multiple smaller levels (sub-levels) and manage them from the main persistent level.
| Element | Description |
|---|---|
| Persistent Level | The main level that's always loaded in memory. Manages the game's core elements (game mode, UI, etc.) and controls sub-levels. |
| Sub-Level | Levels that are loaded and unloaded into the persistent level, composing specific parts of the map (areas, buildings, dungeons, etc.). |
Benefits
Implementing level streaming provides the following main benefits:
- Reduced Memory Usage: Loading only necessary assets significantly reduces overall game memory usage.
- Shorter Load Times: Reduces initial load time when starting the game, decreasing player wait time.
- Seamless Experience: Enables smooth gameplay continuation without loading screens when transitioning between areas.
- Improved Team Development Efficiency: Dividing the map allows multiple developers to work on different areas simultaneously.
Implementing Level Streaming
There are mainly two types of level streaming: "manual control via Blueprint/C++" and "automatic control via World Composition/World Partition." Here we'll explain the most basic manual control implementation.
Creating and Setting Up Sub-Levels
- Create Levels: Create new levels for each area you want to stream, separate from the main level (persistent level) (e.g.,
SubLevel_Forest,SubLevel_Town). - Add to Persistent Level: Open the persistent level and open the Levels panel from "Window" > "Levels."
- Add Sub-Levels: Select "Add Existing Level" from the Levels panel's "Levels" menu and add the created sub-levels.
- Set Streaming Method: Right-click the sub-level in the Levels panel and select "Blueprint" from "Change Streaming Method." This allows you to control loading with the nodes described below.
Load/Unload Control via Blueprint
Implement processing to load sub-levels when the player enters a specific trigger volume.
Blueprint Example for Loading
Load a level when the player enters a trigger volume (e.g., Box Collision).
// Trigger Volume Event Graph
// 1. On Component Begin Overlap event
// 2. Cast To Character from Other Actor pin (or Get Pawn from Player Controller)
// 3. On Cast success, connect to Load Stream Level node
// - Level Name: "SubLevel_Forest"
// - Make Visible After Load: True
// - Should Block on Load: False
Blueprint Example for Unloading
Unload a level when the player exits the trigger volume.
// Trigger Volume Event Graph
// 1. On Component End Overlap event
// 2. Cast To Character from Other Actor pin
// 3. On Cast success, connect to Unload Stream Level node
// - Level Name: "SubLevel_Forest"
Key Point: Setting Should Block on Load to False performs loading asynchronously, minimizing frame rate drops (stuttering).
Optimization Techniques and Best Practices
Level streaming is powerful, but incorrect settings can actually worsen performance. Here we introduce optimization techniques for maximizing effectiveness with large-scale maps.
Adjusting Load Timing and Distance
The most important thing is to start loading slightly before the player needs it, and unload as soon as it's no longer needed.
- Adjusting Load Start Distance: If the player gets too close to the level boundary, loading won't complete in time, causing assets to appear in front of them (pop-in phenomenon). Place trigger volumes well ahead of level boundaries to ensure loading time.
- Adjusting Unload Distance: It's generally fine to unload immediately after the player leaves an area. However, if the player might quickly return, consider adding a delay before unloading.
Common Mistake: Overusing Should Block on Load
Setting Should Block on Load to True on the Load Stream Level node pauses game execution until loading completes. This should only be used in limited situations like loading screens or right before events that require loading completion.
Best Practice:
For seamless movement in large-scale maps, always set it to False and use asynchronous loading. If you need to wait for loading completion, use the Completed event derived from the Load Stream Level execution pin to execute subsequent processing.
Using World Partition (UE5 and Later)
From Unreal Engine 5 onward, World Partition, an evolution of level streaming, is recommended.
World Partition automatically divides large worlds into grids and automatically streams and unloads necessary cells based on the player's camera and distance. This eliminates the need for manual trigger setup, dramatically improving development efficiency and performance.
💡 Choosing Between World Partition and Traditional Streaming
Scenario Recommended Method Vast Open Worlds World Partition (grid-based automatic streaming) Indoor Scenes/Dungeons Traditional level streaming (manual control triggered by doors or passages) Area Switching During Specific Events Traditional level streaming (explicit control via Load Stream Level)When using World Partition, use Data Layers to group actors and control streaming. Basically, grid-based automatic streaming is assumed rather than manual
Load Stream Level.
For large-scale open worlds in UE5, we strongly recommend using World Partition unless there's a specific reason not to.
Feedback During Loading
Even when using asynchronous loading (Should Block on Load: False), loading processes consume CPU resources. Providing visual feedback to indicate loading has started (e.g., small icon at screen edge, notification when loading completes) can reduce player frustration.
Key Points for Level Streaming
Level streaming is an essential technique for realizing large-scale game worlds in Unreal Engine.
| Key Point | Description |
|---|---|
| Basics | Divide maps into sub-levels and load/unload only what's needed. |
| Implementation | Use Load Stream Level / Unload Stream Level nodes combined with trigger volumes. |
| Optimization | Set Should Block on Load to False and ensure asynchronous loading. |
| UE5 | For large-scale maps, prioritize World Partition's automatic streaming over manual streaming. |
Utilize this knowledge and techniques to build vast game worlds free of stuttering that make players want to explore endlessly.