Data Layers¶
How Rephrased uses Unreal Data Layers with World Partition act maps and Level Instance rooms. Decided and tested in changelist 115139. Test log: 2026-W37 devlog.
Short version: everyone uses the six shared Editor Data Layers to hide clutter. Runtime Data Layers work inside rooms, but only create one when design specifies a real state swap, and follow the reference and Save/Load rules below.
Level setup this policy assumes¶
In the context of this document, A "Room" Level is defined as a sublevel (to help organize work in a smaller subregion, to help split up and manage work).
| Level | World Partition | Enable Streaming | Notes |
|---|---|---|---|
Act map, e.g. Content/Rephrased/Levels/Overworld/Lvl_Overworld |
on | on | Streams the rooms placed in it. |
Room/sub-region level (each artist), placed as a Level Instance (LI_ prefix) |
on | off | Loads as one unit, so a puzzle is never half loaded. |
- Streaming off for Level instances to allow edit in place.
- Leave the Level Instance actor's Runtime Behavior at
Partitioned. At runtime the room's actors are merged into the act map's streaming, which is why runtime Data Layers reach inside rooms. - Rooms must be World Partition enabled levels. Actors in a plain, non-World Partition room offer no Data Layers section at all.
Editor vs Runtime Data Layers¶
| Editor Data Layer | Runtime Data Layer | |
|---|---|---|
| Purpose | Hide or show groups of actors while working in the editor | Swap game state while playing (load / unload actors) |
| Affects the shipped game | No | Yes |
| Who creates one | Already set up (six shared layers) | Only when design specifies a state swap; engineer or lead reviews |
| Affects Save/Load | No | Yes, see Save/Load |
Default to an Editor layer. If you just want something out of the way while you work, it is an Editor layer.
The six Editor Data Layers¶
Shared assets in Content/Rephrased/DataLayers/. Every act map lists all six.
| Layer | Put in it | Outliner colour |
|---|---|---|
DL_Ed_Art |
Art and set dressing | green |
DL_Ed_Gameplay |
Runes and interactable gameplay actors | blue |
DL_Ed_Logic |
Trigger volumes and script / logic actors | orange |
DL_Ed_AudioVFX |
Audio and VFX emitters | purple |
DL_Ed_Blockout |
Blockout geometry | grey |
DL_Ed_Debug |
Debug helpers, test floors, markers | red |
Typical use:
- Designer: hide
DL_Ed_ArtandDL_Ed_AudioVFXto read the puzzle and rune logic in a room. - Artist: hide
DL_Ed_Gameplay,DL_Ed_LogicandDL_Ed_Debugto dress the room cleanly.
Rules:
- Assign actors with Details → Data Layers, or drag the actor onto the layer in the Data Layers Outliner. This works for actors inside a room while editing it in place from the act map.
- Hiding or showing a layer is your own editor state. It checks out nothing and does not affect teammates.
- Hiding a layer never deletes actors and does not break Level Instance editing.
- Do not add more Editor layers without asking the lead. Every new layer edits the map's shared WorldDataLayers file (see Perforce cost).
Runtime Data Layers¶
Status¶
Proven working on 2026-09-13 in PIE, in Lvl_DataLayerExample:
- A runtime layer swapped actors placed directly in the act map and actors inside a room (World Partition on, streaming off,
Partitioned). - Visuals and collision swapped together.
- Repeated toggles (A → B → A) logged no World Partition or Level Instance errors.
Design has confirmed at least one real state swap (a puzzle-completion state change). How a given puzzle maps to layers (whole map, one room, or part of a room) is a design decision for later tickets, not this policy. Until design specifies one, do not create production runtime layers.
Naming¶
DL_RT_<Scope>_<State>, for example DL_RT_Garden_Solved. Scope is the smallest area the swap covers (a room name, or the act for map-wide swaps).
Do not duplicate whole maps or rooms to represent a state. Put only the actors that differ between states in runtime layers.
Setting one up¶
- Create a Data Layer Asset in
Content/Rephrased/DataLayers/with Data Layer Type = Runtime. - Add it to the act map in the Data Layers Outliner and set its Initial Runtime State (
Activated,LoadedorUnloaded). - Assign the actors that belong to that state.
- Test in PIE with the console command
wp.Runtime.ToggleDataLayerActivation <LayerName>. The Output Log printsData Layer Instance '<name>' state changed: ...for each toggle.
States:
- Activated: the actors are in the world.
- Unloaded: the actors are destroyed. Activating the layer again loads fresh copies as authored in the editor.
- Loaded: the actors stay in memory but are not active in the world.
Initial States¶
- Activated: actors you want to show when the player gets to your map.
- unloaded: the actors here won't be loaded into memory, but takes some time to load. Good for alternative map states that affects a big region with many actors.
- Loaded: This is for content that we expect to be shown to the player very soon. Good for small, local sets of changes.
Reference rule¶
Tested with a probe actor that was always loaded and pointed at an actor inside a runtime layer:
| Reference type | Result |
|---|---|
Hard reference (Object Reference) |
Map Check error at PIE start: references an actor in a different set of runtime data layers. The target stays loaded when its layer is unloaded, so the swap silently fails. |
Soft reference (Soft Object Reference) |
No error. The layer unloads normally, and the reference finds the actor again after the layer is activated. |
Rules:
- Never hard-reference an actor in a different runtime layer. Treat that Map Check error as a blocker.
- Use soft references, and handle the reference being empty.
- Decide the current state from the Data Layer's runtime state, not from whether a soft reference resolves. After a layer unloads, the old actor still resolves as valid until garbage collection runs (we saw this last about 5 seconds, until
obj gc).
Save/Load: what the save stores¶
Implemented under SAVE-001; see Save / load. Runtime layers add two requirements, both
handled by URephrasedSaveSubsystem:
- Each runtime layer's current state: the layer asset and
Unloaded/Loaded/Activated. Restore these before restoring actor state. - Gameplay state of changeable actors inside runtime layers, for example a slotted rune, an opened door or puzzle progress. Unloading destroys the actors, so any change made during play is lost unless it is saved and re-applied after the layer loads.
Initial runtime states set in the editor are design data stored in the map, not save data.
The save stores each runtime layer by asset path plus its EDataLayerRuntimeState as a uint8, so a
future engine enum reorder becomes a migration rather than silent corruption. Restore sets the layer
states first, waits for UWorldPartitionSubsystem streaming to settle, and only then applies actor
state. Actors inside a layer that streams in later still get their state, because receivers pull their
own record at BeginPlay rather than being pushed to at load time.
Perforce cost¶
Tested with exclusive checkout:
| Action | What gets checked out |
|---|---|
| Hide / show a layer in the editor | Nothing |
| Assign an actor to a layer | Only that actor's __ExternalActors__ file |
| Create a Data Layer Asset | One new .uasset |
| Add a layer to a map, or change its Initial Runtime State | The map's WorldDataLayers actor file: one shared lock per map |
Because of that last row, adding layers or changing starting states should be rare and planned. Coordinate before doing it in a shared act map.
Example map¶
To find this in the content drawer, click on the little cogwheel on the top right corner of the content drawer, and check the box "developer content".
Content/Developers/Engineer/Ricky/Lvl_DataLayerExample (personal scratch, not shipping content):
- One cube per Editor layer (
Ed_Art_Cube…Ed_Debug_Cube) in a row near the PlayerStart. - Runtime test pair
RT_Control_StateA/RT_Control_StateBin the map, andRT_Room_StateA/RT_Room_StateBinsideRooms/LI_Test03, onDL_RT_Test_StateA(starts Activated) andDL_RT_Test_StateB(starts Unloaded), both inDevelopers/Engineer/Ricky/DataLayers/. - Debug floor, light and PlayerStart.
To try it: open the map, load the area around the origin in the World Partition Editor, hide an DL_Ed_* layer, then PIE and run wp.Runtime.ToggleDataLayerActivation DL_RT_Test_StateA.
Content/Rephrased/Levels/Overworld/Lvl_Overworld is the World Partition map (streaming on) with the six Editor layers ready for designers.
Open questions¶
- Behaviour in a cooked / packaged build is untested; everything above is PIE.
- Interaction with HLOD and with the stacked Cascade Town sheets is untested (revisit during the HLOD validation pass).
References¶
- Epic Games: World Partition - Data Layers
- Epic Games: One File Per Actor
- Epic Games: Asset Redirectors
- Content validation
- Content organization
Change history¶
- 2026-10-02 — Gabriel Li — Pointed the Editor vs Runtime table's Save/Load link at the current section heading (CORE-011).
- 2026-09-29 — Gabriel Li — The act map example is
Lvl_Overworld. - 2026-09-17 — Ricky Lu — SAVE-001: the Save/Load requirements are implemented; recorded how layer state is stored and the restore ordering.
- 2026-09-13 — Ricky Lu — Created the Data Layer policy: Editor layer set, runtime layer spike results, reference rule, Save/Load requirements, Perforce cost, example map.