Skip to content
AI & Agents
Skill

/ue-world-level-streaming

Use this skill when working with World Partition, level streaming, level travel, OpenLevel, ServerTravel, data layer, world subsystem, level instance, sub-level, seamless travel, open world, or HLOD. See references/streaming-patterns.md for configuration patterns by game type.

From plugin
unreal-engine-skills
30527 skills
Install
$ npx -y skills add quodsoler/unreal-engine-skills --skill ue-world-level-streaming --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/ue-world-level-streaming

Context preview

The summary Claude sees to decide when to auto-load this skill.

Use this skill when working with World Partition, level streaming, level travel, OpenLevel, ServerTravel, data layer, world subsystem, level instance, sub-level, seamless travel, open world, or HLOD. See references/streaming-patterns.md for configuration patterns by game type.

SKILL.md

ue-world-level-streaming.SKILL.md
name: ue-world-level-streaming
description: "Use this skill when working with World Partition, level streaming, level travel, OpenLevel, ServerTravel, data layer, world subsystem, level instance, sub-level, seamless travel, open world, or HLOD. See references/streaming-patterns.md for configuration patterns by game type."
metadata:
  version: 1.0.0

UE World & Level Streaming

You are an expert in Unreal Engine's world management and level streaming systems.

---

Context

Read `.agents/ue-project-context.md` before advising. Pay attention to:

  • **Engine version** — World Partition is UE5 only; sub-level streaming works in both UE4 and UE5.
  • **Build targets** — Dedicated server has no rendering-driven streaming; streaming must be server-safe.
  • **World size** — Determines whether World Partition or manual sub-level streaming is appropriate.
  • **Multiplayer** — Seamless travel requirements and per-player streaming radius.

---

Information to Gather

Before recommending a streaming approach, confirm:

1. **World size and type**: Is this an open world (World Partition), a set of discrete levels, or a hub-and-spoke map? 2. **Multiplayer**: Are you running a dedicated server? Are per-player streaming radii needed? 3. **Streaming control**: Does gameplay code need to control load/unload explicitly, or should proximity drive it? 4. **Level travel**: Non-seamless (lobby flows), seamless (multiplayer round transitions), or no travel? 5. **Persistent data**: What must survive a level transition — player state, inventory, session state?

---

World Partition (UE5)

Enabling World Partition

Enable via the Level menu: **World -> World Partition -> Convert Level**. Once enabled, all actors in the level are managed by World Partition's grid. The level can no longer have traditional sub-levels. Use **One File Per Actor (OFPA)** for collaborative editing: each actor is saved as its own `.uasset` under `__ExternalActors__`.

Runtime Data Layers

Data layers replace the old sub-level toggle pattern. A runtime data layer can be loaded/unloaded at runtime without traveling to a new map.

// MyGameMode.cpp
#include "WorldPartition/DataLayer/DataLayerManager.h"

void AMyGameMode::ActivateDungeonDataLayer()
{
    UDataLayerManager* DLMgr = UDataLayerManager::GetDataLayerManager(GetWorld());
    if (!DLMgr) return;

    // Get by asset reference (set up in editor as a UDataLayerAsset)
    UDataLayerAsset* DungeonLayer = DungeonDataLayerAsset.LoadSynchronous();
    DLMgr->SetDataLayerRuntimeState(DungeonLayer, EDataLayerRuntimeState::Activated);
}

void AMyGameMode::DeactivateDungeonDataLayer()
{
    UDataLayerManager* DLMgr = UDataLayerManager::GetDataLayerManager(GetWorld());
    if (!DLMgr) return;

    UDataLayerAsset* DungeonLayer = DungeonDataLayerAsset.LoadSynchronous();
    DLMgr->SetDataLayerRuntimeState(DungeonLayer, EDataLayerRuntimeState::Unloaded);
}

**Data layer states:**

  • `Unloaded` — not loaded, not visible.
  • `Loaded` — loaded into memory, not visible (pre-warming).
  • `Activated` — loaded and visible (fully active).

Streaming Sources

Each player controller is a streaming source by default. For custom sources (cinematic cameras, AI directors), implement `IWorldPartitionStreamingSourceProvider`.

HLOD

HLOD provides distant merged-mesh representations of World Partition cells. Configure HLOD layers in the World Partition editor; build before shipping via **Build -> Build World Partition HLODs**. Without HLOD, content beyond the streaming radius is simply absent.

Converting Sub-Levels to World Partition

Use **Tools -> World Partition -> Convert Level**. Actors migrate into the persistent level under WP management. Audit cross-level references beforehand — hard references to converted actors become invalid.

World Partition and Multiplayer

In a multiplayer session, each player controller acts as a streaming source with a configurable radius. The server streams based on server-side sources; clients receive visibility updates via `AServerStreamingLevelsVisibility`. On dedicated servers, rendering-based streaming does not apply — streaming is driven by server-side sources only.

Streaming radius is configured per-partition in the World Partition editor UI (`LoadingRange` on `URuntimePartition`), not via ini.

---

Level Streaming (Manual Sub-Levels)

ULevelStreaming State Machine

From `LevelStreaming.h`, the full state sequence is:

Removed -> Unloaded -> Loading -> LoadedNotVisible -> MakingVisible -> LoadedVisible -> MakingInvisible -> LoadedNotVisible
                                      |
                                 FailedToLoad   (check logs; level asset missing or corrupt)

Query state with:

ULevelStreaming* StreamingLevel = /* ... */;
ELevelStreamingState State = StreamingLevel->GetLevelStreamingState();

switch (State)
{
    case ELevelStreamingState::Unloaded:         /* not in memory */ break;
    case ELevelStreamingState::Loading:          /* async load in progress */ break;
    case ELevelStreamingState::LoadedNotVisible: /* in memory, not rendered */ break;
    case ELevelStreamingState::MakingVisible:    /* adding to world */ break;
    case ELevelStreamingState::LoadedVisible:    /* fully active */ break;
    case ELevelStreamingState::MakingInvisible:  /* removing from rendering */ break;
    case ELevelStreamingState::FailedToLoad:     /* check logs */ break;
}

UGameplayStatics: LoadStreamLevel / UnloadStreamLevel

For Blueprint-friendly async streaming with latent actions (from `GameplayStatics.h`):

// MyActor.cpp — async load using FLatentActionInfo
#include "Kismet/GameplayStatics.h"

void AMyActor::StreamInRoom(FName LevelName)
{
    FLatentActionInfo LatentInfo;
    LatentInfo.CallbackTarget = this;
    LatentInfo.ExecutionFunction = FName("OnRoomLoaded");
    LatentInfo.Linkage = 0;
    LatentInfo.UUID = GetUniqueID();

    UGameplayStatics::LoadStreamLevel(
        this
Read more
Ships withunreal-engine-skills

A collection of 27 AI agent skills for Unreal Engine C++ development. Built for game developers who want AI coding agents to help write correct, production-quality UE5 C++ code.

Get the whole plugin

Other skills on unreal-engine-skills.