Often mod creators want to save data specific to their plugin. Saving to the base game data is dangerous, and using config files can get very messy. So TR Tools has a way to easily save and load custom data.
To begin using the custom save data system, include the following code in your plugin:
using TinyResort;
public static TRModData modData;
private void Awake() {
modData = TRData.Subscribe(fileName, globalSave);
}
This tells TR Tools to create save files specific to your plugin with the given file name. Try to keep the file name unique to your mod to prevent issues with conflicting mods. It will automatically save every time the game saves and the data will be loaded every time the game loads. The save file created will be in a “Mod Data” folder in the standard Dinkum save folder.
If “globalSave” is true, then this will be outside the save slots folders and the data will be used for all slots. If it is false (the default), then the file will be created for each save slot folder and data will be specific to each slot.
If you some data to be local to specific save files and other data to be global, used for all save files, then you can Subscribe twice, setting the returned value to two different variables. You can use the same file name for both, but set globalSave to true for one and to false for the other.
Example below:
using TinyResort;
public static TRModData localData;
public static TRModData globalData;
private void Awake() {
localData = TRData.Subscribe("MyFirstMod", false);
globalData = TRData.Subscribe("MyFirstMod", true);
}
Additionally, if you want to have multiple save files each containing different save data (maybe your mod adds pets and you want each pet's data to be in a separate save file), you can subscribe as many times as you want with different file names each time. Just remember, the file name should be unique, to prevent mod conflicts. So instead of naming your file “Rover”, you'd want to name it something more like “MyPetMod_Rover”.
For any variables to be saved, you have to set their values in your save data.
Calling modData.SetValue(name, value);
will save a value with the given name. The value can be any type of serializable object (ie. int, float, string, a class/struct marked serializable, etc).
If you want to get a saved value, you would call the modData.GetValue(name, defaultValue);
which will return the value it gets. If the value you're trying to get hasn't been saved yet, it will return the default value that you passed in. Keep in mind that this function returns an ‘object’, so you'll want to cast it to the proper variable type.
To ensure all data is properly saved and loaded, you want to make sure you use SetValue for all your saved variables in the preSaveEvent and use GetValue for all those variables in the postLoadEvent. See the next section for more info.
There are a few events that are invoked at specific points in the base game's process of saving. These are:
TRData.preSaveEvent | Invoked before the base game saves. (This is where your mod data is saved automatically.) |
TRData.postSaveEvent | Invoked just after the base game finishes saving. |
TRData.preLoadEvent | Invoked just before the base game loads a save file. |
TRData.postLoadEvent | Invoked just after the base game loads a save file. (This is where your mod data is loaded automatically.) |
TRData.initialLoadEvent | Invoked before loading (and before the preLoadEvent), but only when loading into a slot from the main menu. |
TRData.cleanDataEvent | Invoked right before the base game saves (after the preSaveEvent). See next section for more info. |
TRData.injectDataEvent | Invoked both after loading (after the postLoadEvent) and when finished saving (just before postLoadEvent). See next section for more info. |
You can assign any of your methods to be automatically called during these events as follows: TRData.preSaveEvent += ExampleMethod;
If you need to call your method with any number of arguments, then you would instead do: TRData.preSaveEvent += delegate { ExampleMethod(exampleArgument); };
Adding custom items to the game (or especially objects to the world) can cause issues with the base game's save file. For example, say your mod adds a new kind of chest object to the world and the player places it, so it's position is saved to the base game save file normally. If the player then deletes your mod at any point, when they try to load the save file it will be corrupted.
To avoid these issues, you need to do the following:
TRData.cleanDataEvent += ExampleMethod;
What you have to remove depends on what your mod adds. You might need to remove your item from the player's inventory or delete it from the player's world, for instance.TRData.injectDataEvent += ExampleMethod;
If your mod adds an object to the world, this is where you'd spawn it back into it's position with it's appropriate contents.If you're using a framework for adding custom objects/items to the game, this might not be necessary. For instance, using the the TR Tools Custom Licenses system, you don't need to worry about saving/loading or cleaning/injecting data because the framework already handles all of that.
Once you've subscribed, the game will automatically save and load whenever the game saves and loads. However, if you want your mod's data to be saved at other times as well, then you can manually call: modData.Save();
You can also manually load by calling: modData.Load();
Note that if you are in the main menu, you can only save or load data if your save is global.