Skip to content

Save and front end

All · 15 min read · No code

What the player sees: boot cards, then a title screen with Continue, New Game, Load Game, Settings and Quit. In game, the menu's Save and Load open a list of four slots (an autosave and three manual slots), each with a thumbnail, the leader, the party's portraits, the place and the play time. Glowing save points autosave when the leader steps on them, and a load brings the party back exactly as it was, where it was.

A save captures the party, the bag, gold, quests, the leader's position, every unopened treasure chest on every map visited, and the records of any save participants (your own systems that store their state). The idea that makes the rest make sense: a load always starts a fresh world. XenoCore never undoes the current world in place; it opens the map again and restores the party into it.

What you can change

  • Make your own Blueprint remember something (a door that stays open): Make a system save.
  • Where New Game starts, and the boot cards: the title screen and BP_XenoCore_TitleState (see Settings).
  • Where save points are: place Game/BP_XenoCore_SavePoint in a level.
  • The place name a save shows for your map: Location Names in Project Settings › Game › XenoCore Save (do this for every new map; see the warning below).
  • How the save screen looks: duplicate it and point XenoCore UI › Save Screen at your copy.

How it fits together

Piece Kind Job
Save system Built in, alive from launch to quit (title screen included) Slots, writing, loading, autosave, play time, the slot thumbnail. Reach it in a Blueprint with Get Game Instance Subsystem › Xeno Core Save Subsystem
Game/BP_XenoCore_SavePoint Actor A pad that autosaves when the player stands on it
UserInterface/W_XenoCore_SaveScreen Screen, set by XenoCore UI › Save Screen The slot list, in Save or Load mode
XenoCore Save Participant Blueprint interface and actor component (same name in the editor) Let any actor, component or object store its own record in the save, under its own key
UserInterface/W_XenoCore_SaveRow Row widget One slot: thumbnail, leader, portraits, location, play time, date
UserInterface/HUD/W_XenoCore_AutosaveBadge HUD plate "Autosaving..." while an autosave writes
Maps/L_XenoCore_FrontEnd Map The front end. The project's default map and the editor's startup map
Experiences/B_XenoCore_FrontEnd_Experience Experience Adds BP_XenoCore_TitleState to the game state
UserInterface/BP_XenoCore_TitleState Game state component Plays the boot screens, then pushes the title screen
UserInterface/Boot/W_XenoCore_Boot_Studio, _Unreal, _Autosave, _Shaders Boot cards The pre-title sequence
UserInterface/W_XenoCore_TitleScreen Screen Continue, New Game, Load Game, Settings, Quit
UserInterface/Boot/W_XenoCore_LoadingScreen Widget The loading screen, set in Project Settings › Common Loading Screen

What is saved

Saved Details
Gold The party's purse
The bag One entry per item, as the item definition's class path, with the gems in its sockets (each gem by path, with its rolled strength)
Every character, active or reserve Level, experience toward next level, active slot, health as a fraction of max, equipment by slot, known Arts with level and cap, the Arts palette, Art Points, skill-tree progress (selected branch, and per branch: unlocked, skills learnt, SP into the next). See Skills
Party shape The leader's slot and the maximum active party size
Party tactics The party's orders and each member's own orders, by name. See Party tactics
Quests Each quest's status, objective counts and recorded requester, and the tracked quest
Position The leader's transform. The party re-forms around the leader
Treasure chests For every map visited: each unopened enemy-dropped chest (class, position, drop table, tier), each hand-placed chest that has been emptied, and any chest still holding items the bag had no room for. See Loot
Slot header Leader name and level, active members, location and chapter text, play time, save time, map, thumbnail
Time, weather, tutorials The clock, the weather roll and which tutorial cards have been seen. These are XenoCore's own save participants
Save participants One record per participant key: that participant's SaveGame-flagged variables (or whatever its C++ writes), plus its own data version. Records whose participant is absent this session are carried over, not dropped

Not saved: the rest of the world. Collectable orbs and enemies are back as the map authors them after every load, because a load reopens the map. Chests are the one exception: they are respawned from the file when their map begins play. Per-item state is not saved, apart from gem sockets; items are rebuilt from their definitions, which is exact today because nothing else changes an item after it is created. See the warning under Settings.

Every reference in the file is a path, and every enum is stored by name, not by number. An asset that no longer exists is skipped with a warning rather than crashing the load.

Older save files keep loading after a template update. A file written before a feature existed simply lacks its data: no participant records reads as "nothing saved yet", no tactics loads the Default Tactics, and no gems leaves every socket empty.

Lifecycle

Boot. The project opens L_XenoCore_FrontEnd. Its Experience adds BP_XenoCore_TitleState, which waits for Lyra's loading screen to lift, then shows each boot card in its Boot Screens list: fade in, hold, fade out. A, B, Escape or a click skips a card (it still fades). The shader card only appears if shaders are still compiling. The sequence plays once per launch; returning to the title goes straight to the title. The world behind stays black and silent until the title appears.

Title screen.

  • Continue loads the newest loadable file, autosave included. It is disabled when there are no saves.
  • New Game tells the subsystem a new game is starting, then opens New Game Map (L_XenoCore_GaurPlain).
  • Load Game opens the save screen in Load mode.
  • Settings pushes Lyra's settings screen.
  • Quit quits.

The title screen keeps the world running behind it, so the scene animates.

Saving. From the in-game menu, Save opens the save screen in Save mode. The autosave row is listed but cannot be saved over. Saving is refused while any enemy is engaged in a fight: picking a slot then shows Lyra's message box, Save / You cannot save right now., with an OK button. Writes are asynchronous; the screen's "do not turn off the power" notice lasts exactly as long as the write.

Autosave. A save point autosaves when the player (not a following party member) steps on it. If a fight refuses the save, it keeps retrying every Retry Interval while the player stands there. The HUD's autosave badge shows while the write runs. Save points are the only autosave trigger in the template.

Loading. The save system keeps the file, travels to its map (even the current one), and restores in a fixed order as the world comes up: levels and experience first (so members spawn at their saved level), then quests, then the bag, then the roster. Each character's equipment and health are restored as that character's body is created. While restoring, the usual new-game seeding (starting roster, starting items, starting equipment) stands down, or the party would arrive holding two of everything. The leader is placed once the leader's final body exists.

The loading screen stays up until the world is fit to be seen, not just loaded: the party's bodies exist and are posed, the save is restored, and the world has gone quiet (no shaders, assets or grass still being built) for a few rendered frames. That is what stops T-posed characters and pop-in on the first frame. It holds the first reveal of a map only; after it lifts, nothing brings it back until the next map. If the world never goes quiet it gives up after a timeout and logs a warning. The timings have no Project Settings page; see the last rows of Settings.

Save participants restore last, after all of the above, so a participant that reads the party or the bag sees the loaded state. The save system then fires On Save Loaded with the slot index (Get Loaded Slot Index returns it afterwards). A participant that registers later (an actor streaming in) gets its record the moment it registers, and one that unregisters (streams out, or its level is left) has its current state recorded first, so it comes back as it was.

Which participants are saved. Without registering: the player controller, the player state, the game state, and every component on them, if they implement the interface. Anything else: actors with a XenoCore Save Participant component, and objects passed to Register Save Participant. Each is stored under a key: its own Save Key or Get Save Participant Key if set; otherwise map plus actor name for a placed actor, or the class name for anything else.

Deleting. On the Load screen, a slot that holds a file offers Delete in the footer. It asks for confirmation in a popup over the screen before the file goes. The autosave can be deleted this way too.

Leaving. Return to Title and Quit in the in-game menu ask for confirmation only when something has been played since the last save, autosave or load. Return to Title opens the project's default map.

The slot thumbnail is captured when the in-game menu opens, before the menu is drawn. A save written later uses that picture.

The slot's location and chapter. A save row names the map it was written on, from Location Names in Project Settings › Game › XenoCore Save, and prints Default Story Text as its chapter line. A map with no entry prints no location, and the row draws cleanly without it. Calling Set Location Text on the save system overrides the name for the current map only (for a region inside a large map); the override lapses once the party is on another map. Set Story Text replaces the chapter line until it is called again with an empty string.

Respawn after defeat. Stepping on a save point also records it as the party's respawn point, which a party wipe returns to. This happens on every visit, even when the pad does not save again.

Settings

Setting Where it lives What it does
Point Name Placed save point › XenoCore › Save Named in the log for every autosave this pad causes
Retry Interval Placed save point › XenoCore › Save Seconds between retries while saving is refused. Default 1
Rearm On Exit Placed save point › XenoCore › Save Save again on later visits. Default on
Respawn Offset, Is Respawn Point Placed save point › XenoCore › Save Where a wiped party reappears, relative to the pad (a capsule centre, default 100 up), and whether this pad records itself as the respawn point at all
Location Names Project Settings › Game › XenoCore Save › Save Rows One entry per map: the place name a save written there shows. Stored in Config/DefaultGame.ini
Default Story Text Project Settings › Game › XenoCore Save › Save Rows The chapter line on every save row until Set Story Text is called
Boot Screens BP_XenoCore_TitleState › XenoCore › Title The boot cards, in order. Reorder, add or remove
Title Screen Class same The title screen widget
Title Reveal Time, Boot Gap Time same Fade-in of the title scene, and black between cards
Fade In Time, Hold Time, Fade Out Time Each boot card › XenoCore › Boot That card's timing
Movie W_XenoCore_Boot_Unreal (a movie card) The clip it plays
Minimum Show Time W_XenoCore_Boot_Shaders So a queue that empties at once does not flash the card
New Game Map W_XenoCore_TitleScreen › XenoCore › Title Where New Game starts
Settings Screen Class same The settings screen (Lyra's by default)
Autosave badge labels and hold times W_XenoCore_AutosaveBadge class defaults "Autosaving...", "Saved", "Save failed", the warning line
Loading Screen Widget Project Settings › Common Loading Screen The loading screen
TimeoutSeconds, SettleSeconds, SettleFrames, CompileTimeoutSeconds, TextureStreamingMaxSeconds Text only: your project's Config/DefaultGame.ini, section [/Script/XenoCoreRuntime.XenoCoreWorldReadySubsystem] (no Project Settings page) How long the loading screen waits for a quiet world (defaults 20 s overall, 0.75 s and 10 quiet frames, 180 s of compiling, 4 s of texture streaming). Close the editor before editing the file
Game Default Map, Editor Startup Map Project Settings › Maps & Modes L_XenoCore_FrontEnd

Console commands (development builds): XenoSave <slot>, XenoLoad <slot>, XenoSaveDump, and XenoCore.Boot.ForceShaderScreen 1 to preview the shader card. The command-line switch -XenoCoreSkipBoot skips the boot cards. See Console commands.

Fails silently: your map's saves show no location

Location Names only lists the sample maps. A save written on a map of yours prints an empty location until you add an entry for it in Project Settings › Game › XenoCore Save. Nothing is logged. Add the entry when you create the map.

Adding per-item state breaks saving

If you give items state of their own (durability, charges), the save does not know about it and loaded items come back fresh. Items are not save participants: saving that state needs a programmer to extend the save file.

Fails silently: two participants on one key

Every copy of a spawned actor gets the same derived key (its class). Only one is saved; the rest log an error (duplicate save participant key). Give each copy its own Save Key.

A save key is forever

Records are matched by key. Renaming a key, or re-placing a level actor whose key comes from its name, leaves old saves holding a record nobody claims, and the actor starts with its defaults.

Never renumber the save version

This is for whoever extends the save file in C++. Save format versions (EXenoCoreSaveVersion) are appended, never renumbered: a shipped version number is sitting in a player's save file. A participant's own Get Save Data Version follows the same rule.

Extending it

  • More or different boot cards: duplicate a card from UserInterface/Boot/ into your folder, change it, and add it to Boot Screens. A movie card takes a Movie.
  • A different first map: set New Game Map on your copy of the title screen and point Title Screen Class at it.
  • More save points: place BP_XenoCore_SavePoint. Set its mesh on a child Blueprint to restyle it.
  • Saving your own data (for example a door that stays open): tick SaveGame on the variables and add a XenoCore Save Participant component, or implement the interface on a controller component. No C++, and no change to XenoCore's file version: each participant carries its own Get Save Data Version and migrates in On Save Data Restored. See Make a system save.
  • React to any load: bind On Save Loaded on the save system. It fires once the whole load, participants included, is applied.
  • A different save screen: duplicate W_XenoCore_SaveScreen and set XenoCore UI › Save Screen. The menu's Save and Load entries and the title screen open whatever it names.
  • Save from a Blueprint: call Save To Slot or Request Autosave on the save system. Both return false when saving is refused.
For programmers: classes

UXenoCoreSaveSubsystem (game-instance subsystem) owns slots, writes and loads. The file is UXenoCoreSaveGame (a ULocalPlayerSaveGame) with a header and a body; its format version is EXenoCoreSaveVersion (InitialRelease = 1, WorldChests = 2, ParticipantData = 3, PartyTactics = 4, Gems = 5). Participants implement IXenoCoreSaveParticipant or carry UXenoCoreSaveParticipantComponent; C++ may override CaptureSaveData / RestoreSaveData. Screens and widgets derive from UXenoCoreSaveScreenBase, UXenoCoreSaveRowBase, UXenoCoreAutosaveBadgeBase, UXenoCoreTitleScreenBase, UXenoCoreBootScreenBase and UXenoCoreLoadingScreenBase; the front end's state is UXenoCoreTitleStateComponent; save points are AXenoCoreSavePoint. The loading-screen hold is UXenoCoreWorldReadySubsystem.

Why it's built this way

For programmers
  • A game-instance subsystem. Loading travels to a map, and a world subsystem would be destroyed halfway through its own job. It is also alive on the title screen, which is what lets Continue and Load work there.
  • Epic's ULocalPlayerSaveGame. It brings the data version, pre-save and post-load hooks, and async writes. It writes the version at save time, which avoids a known sample bug where a version set in a constructor is never serialized.
  • Header and body split. The save list loads every file it shows. A body that fails to migrate still leaves a row the player can see and overwrite, instead of an empty list that looks like lost saves. A file from a newer build shows its row but refuses to load.
  • Participants rather than a list. XenoCore's own systems are captured by name, in a fixed order. A buyer's system is not in that list and should not have to be: it writes an opaque, versioned record under its own key, so the file format never changes when a system is added.
  • A fresh world on load. Resetting every orb and enemy for free means no code has to undo world state in place. Chests are the exception because unopened chests are meant to wait for the player; the save stores what each chest will roll from, never its items, so a reload does not let the player see a chest's contents in advance.
  • Health as a fraction. Max health depends on level and gear, both restored after health is read, so saved points could exceed the new maximum.
  • The front end is Lyra's pattern. Lyra's own front end puts a state component on the game state through its Experience; XenoCore's does the same with its own component, so the title map itself stays empty.

Next: UI shell and HUD · Events you can listen to