---
title: AFS_Core_Loading
product: Advanced Framework Pro
version: 1.0
engine: Unreal Engine 5.8
updated: 2026-10-05
canonical: https://docs.human-codeable.com/plugins/afs-core-loading.html
---

System

# AFS_Core_Loading

Level flow: the level data asset, game mode, transition actors, player start positions and the libraries that switch levels in editor, listen-server and client contexts.

#### What it gives you

- One data asset describing a level's game mode, pawns and maps
- Correct level switching in editor, on a listen server and on clients
- Customisable loading transitions
- Indexed player start positions for multiplayer

#### Requires

None

#### Required by

None

12 assets36 API members

## Description

`PDA_Level` is the centre of this plugin. It names the game mode, the pawn class per platform, the persistent map, any streaming maps, the transition actor and a minimum transition time. Because the pawn decision lives here rather than in the map, the same map can serve VR, desktop and mobile.

`ML_Loading.Loading_SwitchLevel` handles the three cases that usually get written three times: in the editor it fades and calls `OpenLevel`; with authority it fades every player and issues a `servertravel`; on a client it fades and opens locally.

`FL_Loading` caches the active level data asset in the object registry subsystem, so any Blueprint can ask what level it is in without a hard reference.

## Setup

See [Create a new level](../workflows/create-new-level.html) for the full walkthrough.

1. Create a `PDA_Level` and fill in the game mode, pawn classes and maps.
2. Place a `BP_MapInfo` actor in the map pointing at the data asset.
3. Place `BP_PlayerPosition` actors as spawn points; mark one **Default Position**.

## Usage

### Switching level

Call `ML_Loading.Loading_SwitchLevel` with the target `PDA_Level`. Pass **Listen Server** true when the host should stay listening.

### Customising the loading screen

Derive from `BP_Transition`, override `StartLoading` and `LoadingFinished`, and set your class as **Transition Class** on the level data asset.

### Finding the current level

Call `FL_Loading.getLevelInfo` from anywhere.

## Key properties

| Property | When to change |
|---|---|
| `Pawn Select` | Force Desktop while iterating; Dynamic for shipping |
| `Min Transition Time` | Raise to avoid a jarring flash when loading is fast |
| `Streaming Maps` | Fill only when you actually stream; a non-empty list triggers the loading transition |
| `Player Index` / `Default Position` | On `BP_PlayerPosition`, for multiplayer spawn assignment |

## Extending

Derive from `BP_Transition` for custom loading visuals, and implement `BPI_PlayerPosition` to make your own actor a valid spawn point.

## Multiplayer notes

Multiplayer

Level switching on a listen server uses `servertravel` so all clients follow. `bUseSeamlessTravel` is enabled on the shipped game mode.

## Example map

`Map_Examples_Lobby` switches between every other example map using this system.

## Troubleshooting

**The wrong pawn spawns.** `Pawn Select` is set to a Force option, or the map has no `BP_MapInfo`.

**Level switch does nothing in the editor.** The editor path strips the play-in-editor prefix via `getLevelPathFromReference`; a manually built travel URL will not.

## API reference

Every blueprint asset in this plugin. Expand an asset to see its members.

### Blueprints/MapInfo

**BP_MapInfo**1 members

extends `Actor`

Level marker naming the level data asset this map belongs to. Drop one into a map and set Level Key; the loading library looks it up the first time anything asks which level is running and caches it, so the game mode, the pawn choice and the streaming maps all come from the right data asset.

| Kind | Name | Signature | Description |
|---|---|---|---|
| var | `Level Key`Info | `PDA_Level` | The level data asset describing this map. Place one Map Info actor per level so any Blueprint can discover the level's configuration. |

### Blueprints/PlayerPosition

**BP_PlayerPosition**5 members

extends `PlayerStart` · implements `BPI_PlayerPosition`

Player start the loading system understands. Place them where players should appear and give each one an index, or tick Default Position for the fallback everyone uses; the loading pawn matches a joining player to one of these and spawns the level's pawn on its transform. Teleport To Position moves a pawn here later through the teleport ability.

| Kind | Name | Signature | Description |
|---|---|---|---|
| var | `Player Index`Parameter | `int` | Which player this start position belongs to. Positions are claimed in order, so give each start a distinct index for multiplayer. |
| var | `Default Position`Parameter | `bool` | Marks this as the fallback start used when no position matches the joining player's index. |
| var | `Use Fade`Settings | `E_Teleport_Fade` | Whether teleporting a player to this position fades the camera. |
| fn | `FindFreeIndex`Parameter | `()` | Claims the next unused player index for this position. |
| event | `OnTeleportFinished_Event` | `(Pawn: Pawn)` | Internal handler fired once a pawn has finished teleporting to this position. |

### Blueprints/Transition

**BP_Transition**2 members

extends `Actor`

Base class for the loading screen shown while streaming maps load. The loading pawn spawns whichever transition class the level data asset names, calls Start Loading, then Loading Finished once the maps are in, then destroys it. Empty by design: subclass it to build a transition of your own, or name the default one instead.

| Kind | Name | Signature | Description |
|---|---|---|---|
| event | `StartLoading` | `()` | Called when loading begins. Override in a subclass to show your own loading visuals. |
| event | `LoadingFinished` | `()` | Called when loading completes and the minimum transition time has elapsed. Override to dismiss your loading visuals. |

**BP_Transition_Default**2 members

extends `BP_Transition`

Ready-made loading screen: a sky dome, a grid floor, a directional light and a world-space widget carrying the loading throbber, which follows the camera's height so it stays in view. Name it as Transition Class on a level data asset to use it as it stands, or copy it as the starting point for a branded one.

| Kind | Name | Signature | Description |
|---|---|---|---|
| event | `LoadingFinished` | `()` | Fades out the default loading screen and destroys the transition actor. |
| event | `StartLoading` | `()` | Shows the default loading screen and begins its animation. |

### DataAssets

**PDA_Level**11 members

extends `PrimaryDataAsset`

Data asset describing one playable level: the game mode, the desktop, VR and mobile pawns to choose between, the persistent and streaming maps, the loading screen class and the least time it stays up. Make one per level and point a map info actor at it. Get Pawn To Spawn picks the pawn for the current device, or you can force one.

| Kind | Name | Signature | Description |
|---|---|---|---|
| var | `Game Mode`Pawn | `class<GameMode>` | Game mode loaded with this level. Passed on the travel URL so it applies to networked travel as well. |
| var | `Pawn Select`Pawn | `E_Pawn_Select` | How the pawn is chosen. Dynamic detects VR, then mobile, then desktop; the Force options override that for testing. |
| var | `Default Pawn Desktop`Pawn | `class<Pawn>` | Pawn class possessed when the level is entered on a desktop machine. Only consulted when Pawn Select resolves to desktop; leave it empty and the level loads with no pawn on that platform. |
| var | `Default Pawn VR`Pawn | `class<Pawn>` | Pawn class spawned when a head-mounted display is present. |
| var | `Default Pawn Mobile`Pawn | `class<Pawn>` | Pawn class spawned on iOS and Android. |
| var | `Name`Information | `text` | Display name for this level, shown in navigation and loading UI. |
| var | `Transition Class`Transition | `class<BP_Transition>` | Transition actor spawned while streaming maps load. Subclass it to customise the loading screen. |
| var | `Min Transition Time`Transition | `float` | Shortest time the loading screen stays up, in seconds. Prevents a jarring flash when loading is fast. |
| var | `Persistant Map`Streaming Level | `SoftWorldReference` | The map opened immediately when switching to this level. |
| var | `Streaming Maps`Streaming Level | `SoftWorldReference[]` | Maps streamed in after the persistent map opens. If this list is non-empty a loading transition is shown while they load. |
| fn | `getPawnToSpawn` | `(out PawnToSpawn: class<Pawn>)` | Resolves which pawn class to spawn, applying the Pawn Select rule against the current platform. |

### Game

**BP_GameMode**0 members

extends `GameMode`

Game mode the loading system expects: its default pawn is the loading helper, which runs the transition and then spawns the real pawn from the level data asset, and seamless travel is on. Name it on a level data asset, and subclass it rather than the engine's Game Mode when your project wants its own game state or player controller.

No editor-visible members; this asset configures defaults only.

### Helper

**BP_Helper_Pawn_Loading**7 members

extends `Pawn`

Temporary pawn every player possesses before the real one exists. It fades the camera down, spawns the level's transition actor, streams the level's maps in, waits out the minimum transition time, then has the server spawn the level's pawn at a matching player position and destroys itself. Spawned by the framework game mode; not something to place.

| Kind | Name | Signature | Description |
|---|---|---|---|
| fn | `FindStartingPlayerPosition` | `(PlayerIndex: int, out PlayerPosition: Actor)` | Finds the player start matching the given index, falling back to the default position. |
| fn | `RequiresLoading` | `(out RequiresLoading: bool)` | Returns whether this level still has streaming maps to load before gameplay can begin. |
| event | `Server_ControllerReady` | `(Controller: PlayerController)` | Tells the server this client's controller is ready, so the real pawn can be spawned. |
| event | `Client_LoadLevels` | `(Level: PDA_Level)` | Instructs this client to stream in the level's maps and show the transition while it happens. |
| event | `Server_LoadLevelInfo` | `()` | Asks the server for the level data asset so the client knows what to load. |
| event | `CheckForUnpossess` | `(Controller: Controller)` | Checks whether this placeholder pawn is still needed and destroys it once the real pawn has taken over. |
| event | `Server_DestroyPawn` | `()` | Asks the server to destroy this placeholder pawn. |

### Interfaces

**BPI_PlayerPosition**5 members

extends `Interface`

Contract the loading system uses to find where a player should appear: the spawn transform, the player index, whether this is the default position, and the calls made when a pawn spawns here or is teleported here. The framework's player position actor implements it; implement it on a spawn point of your own rather than changing the loading pawn.

| Kind | Name | Signature | Description |
|---|---|---|---|
| fn | `PlayerPosition_PawnSpawnedHere`Player Position | `(Pawn: Pawn)` | Notifies the position that a pawn has spawned there. |
| fn | `PlayerPosition_TeleportToPosition`Player Position | `(Pawn: Pawn)` | Teleports the given pawn to this position. |
| fn | `PlayerPosition_IsDefault`Player Position | `(out Default: bool)` | Returns whether this is the fallback position used when no index matches. |
| fn | `PlayerPosition_getIndex`Player Position | `(out Index: int)` | Returns the player index this position is reserved for. |
| fn | `PlayerPosition_getSpawnTransform`Player Position | `(out Transform: Transform)` | Returns the transform a pawn should spawn at for this position. |

### Libraries

**FL_Loading**3 members

extends `BlueprintFunctionLibrary`

Function library for the level info the loading system runs on. Get Level Info returns the current level data asset, falling back to the map info actor in the level and caching it in the object registry; Set Level Info replaces it before travel; and Get Level Path From Reference turns a soft world reference into the map name servertravel wants. Called statically.

| Kind | Name | Signature | Description |
|---|---|---|---|
| fn | `getLevelPathFromReference`Level | `(Level: World, __WorldContext: Object, out LevelPath: name)` | Converts a soft world reference into a travel path, stripping the editor play-in-editor prefix so server travel works from the editor. |
| fn | `setLevelInfo`Level Info | `(Context: Object, Level: PDA_Level, __WorldContext: Object)` | Stores the level data asset in the object registry so later lookups avoid searching the level. |
| fn | `getLevelInfo`LevelInfo | `(Context: Object, __WorldContext: Object, out Level: PDA_Level)` | Returns the level data asset for the current level, reading it from the object registry and falling back to the Map Info actor placed in the map. |

**ML_Comp_Loading**0 members

extends `ActorComponent`

Macro library holding Loading Switch Level for components: it fades every player's camera to black, then either opens the level data asset's persistent map with its game mode or, with authority outside the editor, servertravels the whole session there. Its macro appears in any actor component; the actor library does the same job for actors.

No editor-visible members; this asset configures defaults only.

**ML_Loading**0 members

extends `Actor`

Macro library holding Loading Switch Level for actors: it fades every player's camera to black, then either opens the level data asset's persistent map with its game mode or, with authority outside the editor, servertravels the whole session there. Call it from a portal, a menu button or an intro screen; the component library does the same job for components.

No editor-visible members; this asset configures defaults only.

### Widgets

**WBP_Loading**0 members

extends `WBP_Base`

Contents of the loading screen: a linear throbber above the word Loading, in a fixed-width overlay scaffold. The default transition actor draws it on its widget component. To change what a loading screen says, point your own transition class at a widget of your own rather than editing this one.

No editor-visible members; this asset configures defaults only.
