Skip to content

Player Resources and Save Data

Brandon edited this page Jun 30, 2026 · 2 revisions

In this tutorial we will make some data persist, that is, when the player exits a run and re-enters it, or when the player restarts battle or undoes a turn, how do we get data to persist?

This wasn't an issue with the previous section on Custom Tracked Values as when you save/load the game state, every action taken in battle gets replayed and will rebuild the tracked values state. Additionally, with SimpleGlobalTrackedValueHandler the value is reset at the end (and start) of the battle the value isn't designed to persist.

We will cover how to make a Custom Tracked Value that persists, like Dragon's Hoard, we will also show how to make custom data that persists.

Player Resources

PlayerResource is a class similar to SimpleGlobalTrackedValueHandler, except it only stores a current value and its value does not reset at the end of a battle, it persists throughout the run even if the player saves/loads the game.

To set up a PlayerResource requires a few steps:

  1. A tracked value must be created and fetched from the framework.

  2. Create an instance of PlayerResource giving it a name, and an optional associated clan.

  3. Register the PlayerResource with the SaveDataRegistry

Going off the previous tutorial we had this code to associate a TrackedValue with a SimpleGlobalTrackedValueHandler.

            Railend.ConfigurePostAction(
                c =>
                {
                    var trackedValueRegister = c.GetInstance<IRegister<CardStatistics.TrackedValueType>>();
                    EphemeralCardsPurged = trackedValueRegister.GetValueOrDefault(MyPluginInfo.PLUGIN_GUID.GetId(TemplateConstants.TrackedValueTypeEnum, "EphemeralCardsPurged"));
                    EphemeralCardsPurged.SetTrackedValueHandler(new SimpleGlobalTrackedValueHandler());
                });

To switch to a PlayerResource the last line should be replaced by these 4 lines

var classRegister = c.GetInstance<IRegister<ClassData>>();
var myClan = classRegister.GetValueOrDefault(MyPluginInfo.PLUGIN_GUID.GetId(TemplateConstants.Class, "ClassBasic"));
var handler = new PlayerResource("EphemeralCardsPurged", myClan);
EphemeralCardsPurged.SetTrackedValueHandler(handler);
SaveDataRegistry.Register(MyPluginInfo.PLUGIN_GUID, handler);
  1. We get the ClassRegister which stores custom clans defined in mods.

  2. We get the Clan named ClassBasic (Which should be defined provided you use the mod template with a minimal clan enabled)

  3. We create a PlayerResource instance which stores our value for us along with serialization/deserialization with the game's save data.

  4. We register the PlayerResource with SaveDataRegistry so that it gets saved. This step is required as without it the functions in PlayerResource that handle save/load won't be called. Objects must be registered with the SaveDataRegistry in order to be saved.

Custom Save Data

We can create custom save data by implementing the ISaveData interface, and then registering the object with the SaveDataRegistry

ISaveData has these following functions to be implemented.

    public string Key { get; }
    public bool ShouldSerialize();
    public string Serialize();
    public void Deserialize(string data);
    public void Reset();
  • Key is the key for the save data, it is used to identify which ISaveData is associated to the data. The key must be unique across your mod, no two items must share a key.

  • ShouldSerialize determines if there is data needed to be saved. Please keep the save data minimal, for instance if this save data is associated with a clan, then you should not save anything if the run does not have said clan as primary or allied.

  • Serialize this function performs the serialization (saving) of the data to a string.

  • Deserialize this function deserializes a string and loads the data.

  • Reset this function should reset the state of your save data, this is called when starting a new run.

Once you have your ISaveData class implemented, just register it with the SaveDataRegistry

Do note that if any of the functions fail due to an exception then your data will not be saved to disk this is to protect the game's base save data.

Clone this wiki locally