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.

By quodsoler · 810 installs

npx skills add quodsoler/unreal-engine-skills --skill ue-world-level-streaming

Source repository · Upstream listing

UE World & Level Streaming Target engine: UE 5.8 . APIs below are verified against the 5.8 headers; older forms are listed under "Deprecated — do not use". This skill covers how a UWorld is composed and swapped at runtime: World Partition grids, data layers, HLOD, level instances, classic sub level streaming, streaming volumes, and map travel. Everything here lives in the Engine module ( Engine/Source/Runtime/Engine ), so Core , CoreUObject and Engine in PublicDependencyModuleNames is all that is needed. The one exception is the Level Streaming Persistence plugin, which adds the LevelStreamingPersistence module. For end to end configurations per game type (open world, hub and spoke, procedural, chapter based, volume driven, dedicated server), see [streaming patterns](references/streaming patterns.md). Context Read .agents/ue project context.md if it exists (module names, conventions, enabled plugins, GAS/networking setup). Do not stop if it is missing. Identify the area from the request and the codebase. Ask only when two plausible readings would produce different code. Request is about… Go to Picking between World Partition and sub levels [Choosing a Streaming Model]( choosing a streaming model) Grid streaming, streaming sources, blocking loads, CVars [World Partition Runtime]( world partition runtime) Turning content on and off inside a partitioned world [Data Layers]( data layers) Reusable level chunks placed in the editor, packed actors [Level Instances]( level instances) LoadStreamLevel , ULevelStreaming , volumes, runtime instancing [Sub Level Streaming]( sub level streaming) OpenLevel , ServerTravel , ClientTravel , seamless travel [Level Travel]( level travel) Distant proxies for streamed out cells [HLOD]( hlod) Keeping actor changes across a streaming cycle [Level Streaming Persistence]( level streaming persistence) Per world managers, state that must survive travel [World Subsystems and Cross Level State]( world subsystems and cross level state) Choosing a Streaming Model Situation Use Why One large continuous map World Partition grid Automatic spatial cells, no manual sub level bookkeeping Optional content inside a partitioned map Data layers EDataLayerRuntimeState toggles without travel The same level asset placed many times in the editor ALevelInstance / APackedLevelActor Edited as a unit, packed into instanced meshes The same level package spawned many times at runtime ULevelStreamingDynamic::LoadLevelInstance Creates a uniquely named package per instance Discrete hand authored zones in a non partitioned map ULevelStreaming sub levels Explicit load and visibility control per zone Proximity driven interiors in a non partitioned map ALevelStreamingVolume Camera position driven, no gameplay code A different map entirely OpenLevel / ServerTravel Tears down and rebuilds the world World Partition and sub level streaming are mutually exclusive on the same persistent level. UWorld::IsPartitionedWorld() ( Engine/World.h:2968 ) reports which one is in play; AWorldSettings::GetWorldPartition() ( GameFramework/WorldSettings.h:837 ) returns the partition object (the WorldPartition member is protected). World Partition Runtime UWorldPartition ( WorldPartition/WorldPartition.h ) owns the runtime hash that turns actors into cells. UWorldPartitionSubsystem is the per world entry point and is a UTickableWorldSubsystem . UWorldPartitionRuntimeCell is the unit the hash produces. Query readiness at an arbitrary point with a query source instead of polling actors: EWorldPartitionRuntimeCellState is Unloaded , Loaded , Activated ( WorldPartitionRuntimeCell.h:202 ). Streaming sources Any object can drive streaming by implementing IWorldPartitionStreamingSourceProvider (a plain interface struct in WorldPartitionStreamingSource.h ) and registering it with the subsystem. For the common "this actor pulls cells in" case, add a UWorldPartitionStreamingSourceComponent instead — it already implements the provider and registers itself. The two virtuals to override are virtual bool GetStreamingSources(TArray<FWorldPartitionStreamingSource & StreamingSources) const and virtual const UObject GetStreamingSourceOwner() const . Register in BeginPlay with UWorldPartitionSubsystem::RegisterStreamingSourceProvider(this) and release in EndPlay with UnregisterStreamingSourceProvider(this) . A complete actor implementation is in [streaming patterns](references/streaming patterns.md custom streaming source provider). EStreamingSourceTargetState : Loaded (in memory, not added to the world) or Activated . EStreamingSourcePriority : Highest , High , Normal , Low , Lowest , Default (equals Normal ). TargetGrids plus EStreamingSourceTargetBehavior ( Include / Exclude ) restrict a source to named runtime grids. bBlockOnSlowLoading opts the source into the engine's blocking path when streaming falls behind. Leave it false for cosmetic sources. UWorldPartitionSubsystem::GetStreamingSources(const UWorldPartition , TArray<FWorldPartitionStreamingSource &) reads back everything currently registered. Runtime CVars CVar Effect wp.Runtime.EnableServerStreaming Server side cell streaming on dedicated and listen servers wp.Runtime.EnableServerStreamingOut Lets the server stream cells back out wp.Runtime.BlockOnSlowStreaming Blocks the game thread when a blocking source falls behind wp.Runtime.MaxLoadingStreamingCells Caps concurrent cell loads wp.Runtime.OverrideRuntimeLoadingRange Overrides a grid's loading range for testing wp.Runtime.ToggleDrawRuntimeHash2D Draws the cell grid on screen wp.Runtime.DumpStreamingSources Logs every registered streaming source wp.Runtime.HLOD Enables and disables HLOD proxies at runtime Data Layers Actors reference data layers through AActor::DataLayerAssets ( TArray<TSoftObjectPtr<UDataLayerAsset , GameFramework/Actor.h:1123 ). UDataLayerAsset is the authored asset, UDataLayerInstance is its per world instance, and UDataLayerManager is the runtime accessor, reachable from any object inside a partitioned world. EDataLayerRuntimeState ( DataLayerInstance.h:23 ): Unloaded , Loaded (in memory but not visible — use it to pre warm), Activated (loaded and visible). Other manager entry points: SetDataLayerInstanceRuntimeState(const UDataLayerInstance , EDataLayerRuntimeState, bool bInIsRecursive) , GetDataLayerInstanceEffectiveRuntimeState , GetDataLayerInstances() , GetDataLayerInstanceFromName(const FName&) , and the BlueprintAssignable delegate OnDataLayerInstanceRuntimeStateChanged . To sweep every instance: Authority: a runtime data layer with no load filter only responds to state changes made on the server, and the resulting state replicates. Client only layers must be changed on the client, server only layers on the server. The old world subsystem accessor still exists as a deprecated shim — see [Deprecated — do not use]( deprecated do not use); route everything through UDataLayerManager . Level Instances ALevelInstance ( LevelInstance/LevelInstanceActor.h ) places a .umap as a reusable chunk and implements ILevelInstanceInterface . ULevelInstanceSubsystem is the UWorldSubsystem that tracks them. ILevelInstanceInterface runtime members: LoadLevelInstance() , UnloadLevelInstance() , IsLoaded() , GetLoadedLevel() , GetLevelStreaming() , GetWorldAsset() , GetLevelInstanceID() , IsInitiallyVisible() . ULevelInstanceSubsystem runtime members: GetLevelInstance(const FLevelInstanceID&) , GetOwningLevelInstance(const ULevel ) , RequestLoadLevelInstance(ILevelInstanceInterface , bool bUpdate) , RequestUnloadLevelInstance(ILevelInstanceInterface ) , IsLoaded , IsLoading , ForEachActorInLevelInstance , GetLevelInstanceLevel . The editing entry points are WITH EDITOR only. ELevelInstanceRuntimeBehavior ( LevelInstanceTypes.h:56 ) picks how the instance reaches the runtime: Partitioned (actors move into the main partition grid; shown as "Embedded") or LevelStreaming (its own streaming level; shown as "Standalone"). APackedLevelActor ( PackedLevelActor/PackedLevelActor.h ) derives from ALevelInstance and bakes its static meshes into instanced mesh components. It reports ELevelInstanceRuntimeBehavior::None and loads no level at runtime. Sub Level Streaming ULevelStreaming state ELevelStreamingState ( Engine/LevelStreaming.h:110 ) is Removed , Unloaded , FailedToLoad , Loading , LoadedNotVisible , MakingVisible , LoadedVisible , MakingInvisible . Read it with GetLevelStreamingState() . The requested side is ELevelStreamingTargetState ( Unloaded , UnloadedAndRemoved , LoadedNotVisible , LoadedVisible ). Four BlueprintAssignable delegates, all with no parameters: OnLevelLoaded , OnLevelUnloaded , OnLevelShown , OnLevelHidden . Bind with AddDynamic to a no argument UFUNCTION() . Use SetIsRequestingUnloadAndRemoval(true) to drop the streaming level object entirely. Never mutate UWorld::StreamingLevels directly — use AddStreamingLevel , AddStreamingLevels , RemoveStreamingLevel , RemoveStreamingLevels and UpdateStreamingLevelShouldBeConsidered ( Engine/World.h:1073 1109 ), which maintain StreamingLevelsToConsider . Latent load and unload UGameplayStatics::LoadStreamLevel(const UObject WorldContextObject, FName LevelName, bool bMakeVisibleAfterLoad, bool bShouldBlockOnLoad, FLatentActionInfo LatentInfo) and UnloadStreamLevel(const UObject WorldContextObject, FName LevelName, FLatentActionInfo LatentInfo, bool bShouldBlockOnUnload) resume through FLatentActionInfo::ExecutionFunction , which is resolved by name through the reflection system . The callback therefore has to be a UFUNCTION() declared inside a class body in a header. LoadStreamLevelBySoftObjectPtr and UnloadStreamLevelBySoftObjectPtr take a TSoftObjectPtr<UWorld in place of the FName and are the packaging safe form. UGameplayStatics::FlushLevelStreaming(const UObject ) blocks until pending work completes; UWorld::FlushLevelStreaming(EFlushLevelStreamingType) gives finer control ( None , Full , Visibility ). Runtime level instancing ULevelStreamingDynamic loads one package repeatedly at different transforms. Prefer the params struct overload, because the by name overload cannot express a full FTransform . Tear an instance down with SetShouldBeVisible(false) , SetShouldBeLoaded(false) , then SetIsRequestingUnloadAndRemoval(true) . A generator that tracks its instances and binds OnLevelShown is in [streaming patterns](references/streaming patterns.md pattern 3 procedural and instanced level streaming). FLoadLevelInstanceParams members: World , LongPackageName , LevelTransform , OptionalLevelNameOverride ( const FString ), OptionalLevelStreamingClass , bLoadAsTempPackage , bInitiallyVisible , bAllowReuseExitingLevelStreaming , EditorPathOwner , LevelStreamingCreatedCallback . The Blueprint exposed overloads are LoadLevelInstance(UObject WorldContextObject, FString LevelName, FVector Location, FRotator Rotation, bool& bOutSuccess, const FString& OptionalLevelNameOverride, TSubclassOf<ULevelStreamingDynamic OptionalLevelStreamingClass, bool bLoadAsTempPackage) and LoadLevelInstanceBySoftObjectPtr , which takes a TSoftObjectPtr<UWorld in place of LevelName and the same tail parameters; a C++ only BySoftObjectPtr overload takes an FTransform ( Engine/LevelStreamingDynamic.h:94 ). Streaming volumes ALevelStreamingVolume drives sub levels from camer