Skip to content
pluginv2.0Blueprint only

OneNode Save System

The complete Blueprint save framework for Unreal Engine.

No structs. No boilerplate. No C++. Just nodes that work. Most save systems in Unreal need a custom SaveGame class, a pile of variables, and glue code to read and write every one of them. OneNode replaces all of that with three nodes: pick a slot, store values by name, write to disk. Everything else, from actors and encryption to multiplayer and cloud, builds on those same three ideas.

Engine support
Unreal Engine 4.27 to 5.7
Version
2.0
Backends
Not applicable

What you get

  • Save any value type with a single node
  • Save and restore whole Actors, including references and attachments
  • Slots, tags, categories, checkpoints and auto-save
  • zlib compression plus real AES-256 encryption
  • Versioning, migration, backup and corruption recovery
  • Multiplayer per-player and world saves, plus cloud sync
  • Save Debugger and Setup Wizard editor tools

This is your entire save system

Most save systems in Unreal need a custom SaveGame class, a pile of variables, and glue code to read and write every one of them. OneNode replaces all of that with three nodes you can drop into any Blueprint.

// 1. Point at a save file (a "slot").
Set Active Save Slot (Slot Name = "Player1")

// 2. Store any value under a name you choose.
Save Int    (Key = "Coins", Value = 250)
Save Vector (Key = "Spawn", Value = PlayerLocation)

// 3. Write it to disk. Done.
Save All (To Disk)

That is a real, working save. Reloading is the mirror image: Load All (From Disk), then Load Int ("Coins"). No SaveGame class, no boilerplate, nothing to wire up in advance.

Why not just build it yourself?

You can. Here is what that actually costs you, versus what OneNode does out of the box.

TaskBuild it yourselfWith OneNode
Save an integerSaveGame class, variable, cast, save-to-slot codeOne Save Int node
Save a whole actor transformManually copy each property, rebuild on loadOne Save Actor node
Keep actor references after loadStore IDs, re-find every actor, relink by handRestore Actor References
Compress and encrypt the fileWrite zlib and AES yourself, manage the keyTick two settings
Auto-save every N secondsTimers, flush logic, threadingEnable Auto Save
Load an old save after a patchVersion checks and hand-written migrationRegister Migration Step
Per-player saves in multiplayerResolve net IDs, per-player files, server authSave Player (built in)

The build-it-yourself column is where days disappear, and where the hard-to-find bugs live: lost references, corrupted files, saves that break on your next patch. OneNode ships all of it, tested across UE 4.27 through 5.7.

OneNode does not lock you in. Under the hood it is a normal Unreal SaveGame written to your project Saved/SaveGames folder. You can walk away any time, because your saves are standard files.

Who it is for

Anyone building in Unreal with Blueprint who needs saving that just works: solo devs, small teams, game jams, and shipped commercial titles. If you have ever lost an afternoon to a SaveGame class, this is for you.

Install it

  1. 01Buy it on Fab. Once purchased, OneNode lives in your Fab Library permanently, and every future engine-version update is a free re-download.
  2. 02Install it to your engine. Open the Epic Games Launcher, go to Fab Library, find OneNode Save System, click Install to Engine, and choose your engine version (4.27 or 5.0 to 5.7).
  3. 03Enable it in your project. Open your project, then Edit > Plugins. Search OneNode, tick Enabled, and click Restart Now when Unreal asks. That is the only project setup step.
  4. 04Confirm it works. Open any Blueprint graph, right-click, and type Save Int. If the node appears under the OneNode Save System category, you are ready to save.

Prefer a manual install?

// 1. Unzip the folder that matches your engine, e.g. UE5.3.
// 2. Copy the "OneNodeSaveSystem" folder into:
YourProject/Plugins/OneNodeSaveSystem
// (create the "Plugins" folder if it does not exist)
// 3. Reopen the project. Enable it under Edit > Plugins.

Always use the zip that matches your engine version. A UE 5.3 build will not load in 5.7 and vice versa. The version is in the file name, for example OneNodeSaveSystem_UE5.3.zip.

Your first save in 5 minutes

Let us save a value and read it back. Do this in your Player Character or Game Instance, anywhere with a Blueprint graph.

Step 1: choose a slot

A slot is one save file. Give it a name. Do this once, early, for example on BeginPlay or when the player starts a new game.

Set Active Save Slot (Slot Name = "SaveGame01")

Step 2: save some values

Save Int    (Key = "Coins", Value = 250)
Save String (Key = "Name",  Value = "Aria")
Save Vector (Key = "Spawn", Value = GetActorLocation)

// Nothing is on disk until you flush:
Save All (To Disk)

Step 3: load it back

Set Active Save Slot (Slot Name = "SaveGame01")
Load All (From Disk)

Coins = Load Int    (Key = "Coins", Default = 0)
Name  = Load String (Key = "Name",  Default = "Player")
Spawn = Load Vector (Key = "Spawn", Default = 0,0,0)

Every Load node takes a Default value. If the key was never saved, say in a brand-new game, you get the default instead of a crash or an empty value. That single habit prevents most save-related bugs.

That is a complete, shippable save loop. Everything from here just adds capability on top of these same nodes.

Saving values

OneNode has a dedicated Save node for every common Blueprint type. Each takes a Key, the name you will load it by, and a Value. Call Save All (To Disk) when you are ready to write.

TypeNodeTypeNode
IntegerSave IntVectorSave Vector
Integer64Save Int64RotatorSave Rotator
FloatSave FloatTransformSave Transform
BooleanSave BoolColorSave Color
ByteSave ByteNameSave Name
StringSave StringRaw bytesSave Raw Bytes

Arrays

Whole arrays save in one node too, with no looping. Supported array nodes: Save Int Array, Save Float Array, Save String Array, Save Name Array, Save Vector Array and Save Transform Array.

Save String Array (Key = "Inventory",  Value = InventoryItems)
Save Int Array    (Key = "Quantities", Value = ItemCounts)
Save All (To Disk)

Keys are just text and are case-sensitive. "Coins" and "coins" are two different values. Pick a convention and stick to it.

Useful companions

Has Save Key tells you whether a key exists before you read it. Remove Key deletes one value. Get All Keys returns every key in the slot, handy for debugging. Get Entry Count gives you the total.

Loading values

Loading mirrors saving. Read the file once with Load All (From Disk), then pull each value with its matching Load node and key.

Load All (From Disk)

Health = Load Float (Key = "Health", Default = 100.0)
Level  = Load Int   (Key = "Level",  Default = 1)
Alive  = Load Bool  (Key = "Alive",  Default = true)

The Default is your safety net

If a key is missing, whether a fresh game or a save from before you added that feature, the Load node returns your Default instead of failing. This is the single most important habit in the whole system: always give a sensible default.

Want to branch on whether a save even exists? Use Save Slot Exists (Slot Name) before loading. Show Continue only when it returns true, and New Game otherwise.

Checking before you read

Load All (From Disk)
Branch on: Has Save Key ("TutorialDone")
// True  -> skip the tutorial
// False -> play the tutorial, then Save Bool("TutorialDone", true)

Saving structs and raw bytes

Your own data types save too. Two approaches, depending on how tidy you want the save file.

Option A: save the fields

Break your struct and save each field under a clear key. Verbose, but the save file is human-readable and easy to migrate later.

// Break "PlayerStats" -> Health, Stamina, Level
Save Float ("Stats.Health",  Health)
Save Float ("Stats.Stamina", Stamina)
Save Int   ("Stats.Level",   Level)

Option B: save raw bytes

Serialise any struct to a byte array and store it in one node with Save Raw Bytes. Compact and fast, ideal for large or deeply-nested data where you do not need to read individual fields.

// Convert your struct to bytes, then store the whole blob:
Save Raw Bytes (Key = "SaveBlob", Value = StructBytes)

// Read it back and rebuild the struct:
Bytes = Load Raw Bytes (Key = "SaveBlob")

Prefer Option A while your data is still changing, since named fields are trivial to migrate when you add or rename something. Reach for raw bytes once a struct is stable and you care about file size.

Save slots and a save menu

A slot is one save file. Multiple slots give you multiple saves: manual saves, quicksaves, autosaves, or a full New Game / Load Game screen.

Set Active Save Slot ("Slot_A") ... Save All (To Disk)
Set Active Save Slot ("Slot_B") ... Save All (To Disk)

// Quick save / load use a reserved auto-named slot:
Quick Save
Quick Load

Building a Load Game screen

Get All Slot Names lists every save on disk. Get All Slot Infos returns richer cards, including display name, timestamp, playtime, level and even a screenshot, so you can build a proper save-select menu without bookkeeping of your own.

Slots = Get All Slot Infos
// For each slot, read: Slot Name, Level Name, Play Time,
// Timestamp, Screenshot -> build one UI card per entry.

Managing slots

NodeWhat it does
Get All Slot NamesEvery save slot currently on disk.
Get All Slot InfosRich metadata cards for a load screen.
Copy SlotDuplicate a save, great for branch saves.
Rename SlotRename without losing data.
Delete Save SlotRemove a save permanently.

Saving actors

Instead of saving properties one by one, save an entire actor, its transform and its marked variables, in a single node.

Mark what to save

On the actor variables you want persisted, tick SaveGame in the variable Details panel, under Advanced > SaveGame. OneNode saves exactly those.

Save Actor (Actor = self, Key = "Chest_01")
Save All (To Disk)

// ...later / next session:
Load All (From Disk)
Load Actor (Actor = self, Key = "Chest_01")

Many actors at once

Save Multiple Actors takes an array. Save Actors With Tag saves everything carrying a gameplay tag, so one node persists every door, pickup or enemy in a level. Load Actors By Save Tag brings them all back.

Save Actors With Tag (Tag = "Persistent")
Save All (To Disk)
// Reload the whole set later:
Load Actors By Save Tag (Tag = "Persistent")

Use Has Actor Save Data (Key) to check whether an actor was ever saved, and Get Saved Actor Count for totals. Get All Actor Keys lists them, useful when spawning actors back from a save.

Actor references and attachments

The classic save bug: you reload, and every actor-to-actor pointer is null. OneNode fixes this for you.

The problem

If an actor stores a reference to another actor, such as a weapon pointing at its owner or an enemy at its patrol node, a naive save writes a memory address that means nothing next session. On load, the pointer is null and things break.

The fix, one node

OneNode records references as stable markers at save time. After you have loaded and respawned your actors, call Restore Actor References once. It walks every saved actor and reconnects the pointers, including attachment parents and sockets, so a sword stays in the hand it was attached to.

Load All (From Disk)
Load Actors By Save Tag ("Persistent")  // respawn the actors

// Now relink every reference and re-attach children:
Restore Actor References

Call Restore Actor References after all the actors it needs to point at exist in the world. If a target has not been spawned yet, that one link is skipped and the rest still restore. So load your actors first, then restore references last.

Any reference marked SaveGame is handled: single actor references, arrays of references, and the actor attachment chain. No IDs to manage, no re-finding by name.

Save categories

Categories let one system separate the kinds of data a game keeps, so the right things live in the right file with the right lifetime.

CategoryUse it for
GlobalSettings, achievements, unlocks. Shared across every save.
PlayerProgress, inventory, skills. Tied to one player.
WorldDoors, chests, NPC states. The state of a level.
CheckpointTemporary progress since the last checkpoint.
SessionMultiplayer runtime data for the current session.
ProfileA named player profile.
Set Active Category (Global)
Save Bool ("Ach_FirstBlood", true)   // shared across all saves

Set Active Category (Player)         // this player only
Save Int ("Coins", 250)
Save All (To Disk)

A common split: keep audio and graphics settings and achievements in Global so they persist no matter which save the player loads, and keep run-specific progress in Player or World.

Tags and tag layers

Tags label saved values and actors so you can save, load or delete a whole group in one call. Save By Tag and Load By Tag write and read a tagged group as its own layer, and Delete By Tag and Remove All By Tag clear it.

Save By Tag (Tag = "Level2")     // everything for level 2

// Player restarts level 2, wipe just that group:
Delete By Tag (Tag = "Level2")

Inspecting tags

Get All Tags lists them, Has Tag checks one, Get Keys By Tag returns the keys inside a tag, and Remove Multiple Tags clears several at once.

Tag layers let a group live in its own file. That means you can ship DLC or level state as a separate save layer and load it independently, without touching the main save.

Async, auto-save and checkpoints

Big saves should not freeze the game, and players should not lose progress. These features cover both.

Async (non-blocking) saves

Save All Async (Non-Blocking) writes on a background thread and fires an event when it is done, with no hitch even for large saves. Load All Async does the same for loading. Use these for autosaves during gameplay.

Save All Async (Non-Blocking)
// -> bind "On Save Completed" to show a "Saved" icon

Auto-save

Enable Auto Save (Interval = 300.0)
// Force one right now, e.g. before a boss fight:
Trigger Auto Save

Enable Auto Save takes an interval in seconds and saves on a timer for you. Disable Auto Save stops it, and Trigger Auto Save forces one immediately, for example on level exit.

Checkpoints

Checkpoint Save writes a temporary progress snapshot the player returns to on death, separate from their manual saves, so a checkpoint never overwrites a real save file.

Pair Force Save Flush with app shutdown, or use Has Unsaved Changes, to guarantee nothing is lost when the player quits mid-session.

Events

React to what the save system is doing: show a spinner, pop a "Saved" toast, or handle a corrupt file gracefully. Bindable events fire at each stage of a save or load, so your UI and game logic can respond without polling.

  • On Save Started / Completed: show and hide a saving indicator.
  • On Load Completed: fade in the world once data is ready.
  • On Auto Save: flash a subtle "Autosaved" toast.
  • On Save Corrupted: fall back to a backup instead of crashing.

Polling helpers

When you would rather ask than subscribe: Is Saving, Is Loading, Is Save Manager Ready and Has Unsaved Changes each return a bool you can branch on in Tick or on a button press.

Guard your save button with Is Saving so a player cannot queue ten saves by mashing it. Grey the button out while a save is in flight, and re-enable it on On Save Completed.

Compression and encryption

Make saves smaller and tamper-proof. Both are off by default and toggle with a single node, and existing saves keep loading either way.

Compression (zlib)

Set Compression Enabled (true) shrinks saves with zlib, often dramatically for large or repetitive data. Check the current state with Is Compression Enabled.

Encryption (AES-256)

Enable AES Encryption with your key encrypts the save with real AES-256, so players cannot open or edit the file in a text editor. Disable AES Encryption turns it off, and Is AES Encryption Enabled reports the state.

Set Compression Enabled (true)
Enable AES Encryption (Key = "your-secret-key")

Save All (To Disk)   // now compressed and encrypted

Keep your AES key consistent across a build. If the key changes, older saves made with the previous key cannot be decrypted and you get an Encryption Key Mismatch result. Store the key somewhere stable in your project, not hard-coded in a throwaway variable.

Saves made without these features still load after you enable them. OneNode detects an unprotected file and reads it directly, so you can turn compression or encryption on mid-project without breaking existing saves.

Versioning and migration

The feature that saves you after launch: load a player old save even though your data changed in a patch.

The problem

You ship. Players build up saves. In patch 1.1 you rename "HP" to "Health" and add a new stat. Without migration, every existing save is now subtly wrong or broken.

The fix: register migration steps

Stamp your save format with Set Save Version. When you change the format, register a step describing how to upgrade from the old version to the new one. On load, OneNode runs any needed steps automatically.

Set Save Version (2)
Register Migration Step (From = 1, To = 2)
// inside: read old "HP" -> write new "Health", set defaults

// On load, OneNode checks the file version and upgrades it:
Load All (From Disk)   // v1 saves are migrated to v2 for you

Helpers: Get Current Save Version, Save Needs Migration, Run Migrations and Get Save Version Description let you inspect and control the process. Clear Registered Migrations resets them, which is useful in tests.

Register your migration steps once at startup, in Game Instance Init. Then you never think about it again, because old saves quietly upgrade themselves the moment a returning player loads them.

Backup and recovery

Disks fill up, power cuts out, files corrupt. OneNode keeps backups so a bad write does not cost the player their game.

Before overwriting a slot, OneNode can keep the previous version as a backup. Set Backup Retention (count) controls how many are kept, and Has Backup checks whether one exists. If a save reports Save File Corrupted, call Restore Backup to roll the slot back to the last good copy, then tell the player you recovered their progress.

Set Backup Retention (Count = 3)   // keep last 3 saves

// On load, if the result is "Save File Corrupted":
Branch: Has Backup
  True  -> Restore Backup -> Load All (From Disk)
  False -> start a new game, warn the player

Backups cost a little disk space, and that is the trade for never losing a player save to a single bad write. For most games, a retention of 2 to 3 is plenty.

Multiplayer saves

Saving in multiplayer means two things: each player own progress, and the shared state of the world. OneNode handles both, with server authority built in.

Per-player saves

Save Player and Load Player take a Player Controller and store that player data in their own file. OneNode resolves a stable player identity for you with Resolve Player Id from the net ID, so the right save follows the right player across sessions.

Save Player (Controller = PC)   // filed under that player id
// Next session, same player:
Load Player (Controller = PC)

World saves (server only)

Save World (Server Only) and Load World persist shared level state. They are guarded by authority: Is Network Authority gates the write so only the server can save the world, and a client call returns Not Network Authority instead of corrupting shared state.

OneNode includes a replicated save component that transfers a client save data to the server in verified, paced chunks, so large saves move safely across the network without stalling the game. You drive it through the same Save Player and Load Player nodes.

Helpers: Is Dedicated Server and Is Network Client let you branch your save logic by role when you need to.

Cloud saves

Sync saves to Steam Cloud, Dropbox, or your own backend through one simple provider interface. Point it at a provider and your saves sync up and down. A local-folder provider ships in the box for testing, and the interface is designed so a Steam or Dropbox provider drops in the same way.

Conflict handling

When local and cloud saves disagree, you choose the winner: Prefer Cloud downloads, Prefer Local uploads. No silent data loss, because the resolution is always your call.

// Set your provider once, then sync:
Sync Saves (Conflict = Prefer Cloud)   // pull newest from cloud

// ...at quit:
Sync Saves (Conflict = Prefer Local)   // push local up

During this project live test sweep, the Steam Cloud path reported 2 of 4 sub-checks failing, because that path needs a real Steam app context to fully validate. The provider interface and local sync are solid. Treat a specific storefront provider as something to verify in your own build with your app credentials.

Editor tools

Save Debugger

Open the Save Debugger to inspect any slot live: every key, its type and value, tags, categories, version and file size. From Blueprint, Debug: Dump All Save Data, Get Save Debug Lines and Get Save Debug Summary print the same information to log or UI.

Debug: Dump All Save Data      // prints every key/value to the log
Summary = Get Save Debug Summary   // one-line overview for UI

Setup Wizard

The Setup Wizard walks you through first-time configuration, covering default slot, compression, encryption and backup retention, and writes the settings for you, so you are saving correctly from minute one.

When a save behaves unexpectedly, open the Save Debugger before anything else. Nine times out of ten you spot the problem instantly: a mistyped key, a value in the wrong category, or an older save version than you expected.

Analytics and profile metadata

Rich metadata turns a bare save slot into a proper save card, and gives you numbers about how your game is played.

Profile metadata

Set Player Name ("Aria")
Set Level Name ("The Drowned City")
Set Progress Description ("Chapter 3 - 62%")
Add Play Time (DeltaSeconds)
Set Screenshot From PNG (ScreenshotBytes)

Read it all back with Get Profile Metadata so your load screen can show it.

Analytics

Get Save Analytics returns aggregate figures such as totals, sizes and counts, and Set Custom Metadata Field lets you attach your own key/value stats to a save. Useful for balancing, QA or a stats screen.

Add Play Time called each session gives you an accurate total playtime per slot for free, a detail players notice on a polished load screen.

Recipes

A working Save / Load menu

// SAVE button:
Set Active Save Slot (SelectedSlotName)
Set Level Name (Current Level) ; Add Play Time (Session)
Save All Async (Non-Blocking) -> toast "Saved"

// LOAD screen build:
Slots = Get All Slot Infos -> one UI card per entry
// LOAD button:
Set Active Save Slot (SelectedSlotName) ; Load All (From Disk)

Checkpoint and respawn

// Reaching a checkpoint:
Save Actor (Player, "Player") ; Checkpoint Save

// On death:
Load All (From Disk) ; Load Actor (Player, "Player")
Restore Actor References

Secure release build

Set Compression Enabled (true)
Enable AES Encryption (BuildKey)
Set Backup Retention (3)

Troubleshooting

SymptomCause and fix
Load returns nothing or defaultsNo slot set, or the wrong slot name. Call Set Active Save Slot with the exact name, then Load All (From Disk) before reading.
Values are empty after loadYou read before loading. Load All (From Disk) must run before any Load node.
Actor references are nullCall Restore Actor References after the target actors are spawned, not before.
Actor properties not savedTick SaveGame on each variable, under Details > Advanced, so OneNode knows to persist it.
Encryption Key MismatchThe AES key changed between save and load. Use one stable key per build.
Save File CorruptedCheck Has Backup, then Restore Backup. Set backup retention so this never costs progress.
Nodes do not appearThe plugin is not enabled for this project. Edit > Plugins, enable OneNode, restart.
Old saves broke after a patchAdd Register Migration Step from the old version to the new.

Node reference

Every node, grouped by job. All live under the OneNode Save System category in the Blueprint right-click menu.

GroupNodes
SlotsSet Active Save Slot, Get Active Slot Name, Save Slot Exists, Delete Save Slot, Copy Slot, Rename Slot, Get All Slot Names, Get All Slot Infos, Get Slot Info, Sanitize Slot Name
Save valuesSave Int, Save Int64, Save Float, Save Bool, Save Byte, Save String, Save Name, Save Vector, Save Rotator, Save Transform, Save Color, Save Raw Bytes
Save arraysSave Int Array, Save Float Array, Save String Array, Save Name Array, Save Vector Array, Save Transform Array
Load valuesLoad Int, Load Int64, Load Float, Load Bool, Load Byte, Load String, Load Name, Load Vector, Load Rotator, Load Transform, Load Color, Load Raw Bytes
Load arraysLoad Int Array, Load Float Array, Load String Array, Load Name Array, Load Vector Array, Load Transform Array
Keys and dataHas Save Key, Remove Key, Get All Keys, Get Entry Count, Clear All Data, Clear Memory Cache
Disk I/OSave All (To Disk), Load All (From Disk), Save All Async (Non-Blocking), Load All Async (Non-Blocking), Quick Save, Quick Load, Force Save Flush, Has Unsaved Changes, Save Slot To File, Load Slot From File, Export Slot To Bytes, Import Slot From Bytes
ActorsSave Actor, Load Actor, Save Multiple Actors, Save Actors With Tag, Load Actors By Save Tag, Restore Actor References, Has Actor Save Data, Get Saved Actor Count, Get All Actor Keys
TagsSave By Tag, Load By Tag, Delete By Tag, Remove All By Tag, Get All Tags, Has Tag, Get Keys By Tag, Remove Multiple Tags
CategoriesSet Active Category, Get Save Scope, Set Save Scope, Save Category, Load Category
Auto-save and checkpointsEnable Auto Save, Disable Auto Save, Trigger Auto Save, Checkpoint Save
SecuritySet Compression Enabled, Is Compression Enabled, Enable AES Encryption, Disable AES Encryption, Is AES Encryption Enabled, Enable Encryption, Disable Encryption, Is Encryption Enabled
VersioningSet Save Version, Get Current Save Version, Get Save Version Description, Save Needs Migration, Register Migration Step, Run Migrations, Clear Registered Migrations, Get Plugin Save Version
BackupSet Backup Retention, Has Backup, Restore Backup
MultiplayerSave Player, Load Player, Save World (Server Only), Load World, Resolve Player Id, Is Network Authority, Is Dedicated Server, Is Network Client
CloudSync Saves, Prefer Cloud (download), Prefer Local (upload)
Metadata and analyticsGet Profile Metadata, Set Player Name, Set Level Name, Set Progress Description, Add Play Time, Set Screenshot From PNG, Set Custom Metadata Field, Get Save Analytics, Get Save File Size On Disk, Get Save Size (Bytes)
Debug and statusDebug: Dump All Save Data, Get Save Debug Lines, Get Save Debug Summary, Is Saving, Is Loading, Is Save Manager Ready, Save Result To String, Save Result Is Success

Stuck on something?

We answer every serious message ourselves. Discord is the fastest way to get an answer from the person who built the plugin.