{"id":2371,"date":"2025-11-16T22:41:06","date_gmt":"2025-11-16T22:41:06","guid":{"rendered":"https:\/\/golemitegames.com\/?post_type=docs&#038;p=2371"},"modified":"2025-11-21T20:47:24","modified_gmt":"2025-11-21T20:47:24","password":"","slug":"save-manager","status":"publish","type":"docs","link":"https:\/\/golemitegames.com\/index.php\/docs\/save-manager\/","title":{"rendered":"Save Manager"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\" style=\"font-size:22px;text-transform:capitalize\">Introduction<\/h2>\n\n\n\n<p>This Manager class handles saving the data from this asset, which includes the <a href=\"https:\/\/golemitegames.com\/index.php\/docs\/resource-node\/\" title=\"Resource Node\">Resource Node<\/a>, <a href=\"https:\/\/golemitegames.com\/index.php\/docs\/item-container\/\" title=\"Item Container\">Item Container<\/a> and <a href=\"https:\/\/golemitegames.com\/index.php\/docs\/crafter\/\" title=\"Crafter\">Crafter<\/a> components. <br><br>All of these components self register themselves with this manager to make sure they are saved if they still exist.<br><br>It uses the ISaveable interface, alongside the <a href=\"https:\/\/golemitegames.com\/index.php\/docs\/saveable-object\/\" title=\"Saveable Object\">SaveableObject<\/a> component. The former must be implemented on any class to be saved, and the <a href=\"https:\/\/golemitegames.com\/index.php\/docs\/saveable-object\/\" title=\"Saveable Object\">SaveableObject<\/a> must also be component on the same gameobject as the 3 main components mentioned above. This will also add a <a href=\"https:\/\/golemitegames.com\/index.php\/docs\/unique-id\/\" title=\"Unique ID\">UniqueID<\/a> component, which is essential for saving and loading. You should not need to do anything with either of these classes. You can assign a new or copy an ID if you wish but should not need to. <br><br>Save data is located in the Application.persistentDataPath with the scene name as .json file. <br><br>Note &#8211; It does not save anything apart from what is specified. It is meant to be used alongside other saving and loading systems if building the main components into the scene at runtime. This system has no building functionality, so if this functionality is present in your game, you will need to custom load this data back onto the objects.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" style=\"font-size:22px;text-transform:capitalize\">Setting up<\/h2>\n\n\n\n<p>There is a prefab Save Manager located in \/prefabs\/Managers or the main prefab for the ResourceAndProductionManager also contains this manager.<br><br>Setting up otherwise is as simple as adding the component to a gameobject.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" style=\"font-size:22px;text-transform:capitalize\">Settings<\/h2>\n\n\n\n<p><strong>Save On Exit<\/strong><br>If enabled, runs the SaveGame method OnApplicationQuit.<br><br><strong>Load On Play<\/strong><br>If enabled, runs the LodGame method OnStart.<br><br><strong>Auto Save Interval Minutes<\/strong><br>Loops Auto saving after a certain number of minutes have passed. Suggested values of above 5 minutes are recommended for performance.  <\/p>\n\n\n\n<h2 class=\"wp-block-heading\" style=\"font-size:22px;text-transform:capitalize\">Combining Loading and Saving with your own (easy)<\/h2>\n\n\n\n<p>If you are not placing any new assets at runtime from this asset, then the normal SaveGame and LoadGame functions should serve just fine. <br><br>1. Get the <a href=\"https:\/\/golemitegames.com\/index.php\/docs\/unique-id\/\" title=\"Unique ID\">UniqueID<\/a> of the component and save it alongside the rest of your system data. You can get this via the <a href=\"https:\/\/golemitegames.com\/index.php\/docs\/unique-id\/\" title=\"Unique ID\">UniqueID<\/a> component itself or via the <a href=\"https:\/\/golemitegames.com\/index.php\/docs\/saveable-object\/\" title=\"Saveable Object\">SaveableObject<\/a> component. <br><br>2. Use your custom loading logic to completly load your game. <br><br>3. Ones fully loaded back in to the scene (instantiated), assign the ID string back onto the <a href=\"https:\/\/golemitegames.com\/index.php\/docs\/unique-id\/\" title=\"Unique ID\">UniqueID<\/a> using AssignNewID. <br><br>4. Use LoadGame() in the SaveManager to load all data back onto the instantiated gameobjects.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" style=\"font-size:22px;text-transform:capitalize\">Combining Loading and Saving with your own (Advanced)<\/h2>\n\n\n\n<p>If you are not placing any new assets at runtime from this asset, then the normal SaveGame and LoadGame functions should serve just fine. <br><br>There are several important functions available to you if you wanted to custom load this assets components. <br><br>If you are placing\/removing these components at runtime, its crucial to make sure you gather the data you need and follow the next steps. <br><br>1. Get the <a href=\"https:\/\/golemitegames.com\/index.php\/docs\/unique-id\/\" title=\"Unique ID\">UniqueID<\/a> of the component and save it alongside the rest of your system data. You can get this via the <a href=\"https:\/\/golemitegames.com\/index.php\/docs\/unique-id\/\" title=\"Unique ID\">UniqueID<\/a> component itself or via the <a href=\"https:\/\/golemitegames.com\/index.php\/docs\/saveable-object\/\" title=\"Saveable Object\">SaveableObject<\/a> component. <br><br>2. Use that <a href=\"https:\/\/golemitegames.com\/index.php\/docs\/unique-id\/\" title=\"Unique ID\">UniqueID<\/a> to get the asset data back from the saved .json file using one of the following methods<\/p>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-csharp\" data-lang=\"C#\" data-show-lang=\"0\"><code>\/\/This is per ID\npublic void LoadObject \n{\n    \/\/ResourceNodeSaveData resourceSaveData = GetSavedData&lt;ResourceNodeSaveData&gt;(&quot;182f2134-9037-4dda-b3ed-4f8c54410161&quot;);\n    \/\/Debug.Log(resourceSaveData.currentHp);\n}\n\n\/\/This is the whole save file\npublic void LoadObjects\n{\n    var data = SaveManager.Instance.TryGetSaveData();\n\n    if (data == null)\n    {\n        Debug.Log(&quot;No save file found for this scene.&quot;);\n        return;\n    }\n\n    \/\/Use your saved ID here \n    string savedID = &quot;182f2134-9037-4dda-b3ed-4f8c54410161&quot;;\n\n    if (data != null && data.TryGetValue(savedID, out object objectData))\n    {\n        \/\/This is the object you are loading, just get the ISaveable interface from it\n        ISaveable target = loadedGameobject.GetComponent&lt;ISaveable&gt;();\n \n        if (target != null && objectData != null)\n        {\n            target.RestoreState(objectData);\n\n            \/\/Reassign your ID back on for future saving\n            target.GetComponent&lt;UniqueID&gt;().AssignNewId(savedID);\n        }\n    }\n}\n\n\/\/This is the whole save file\n\/\/Should run on Start\n\/\/Similar for getting the save data above, but you can automatically run it when the game is saved\npublic void Start() \n{\n    SaveManager.Instance.OnGameSaved += (data) =&gt;\n            {\n                foreach (var kvp in data)\n                {\n                    \/\/You could store your keys here\n                    Debug.Log($&quot;Saved Key: {kvp.Key}, Value: {kvp.Value}&quot;);\n                }\n            };\n}\n\n\/\/This is the whole save file\n\/\/Should run on Awake, not Start so we hook into the event before the game is loaded on Start\n\/\/Similar for getting the save data above, but you can automatically run it when the game is loaded\npublic void Awake() \n{\n    SaveManager.Instance.OnGameLoaded += (data) =&gt;\n            {\n                foreach (var kvp in data)\n                {\n                    Debug.Log($&quot;Saved Key: {kvp.Key}, Value: {kvp.Value}&quot;);\n                }\n            };\n}\n\n<\/code><\/pre><\/div>\n\n\n\n<p>After you have loaded the object, make sure to also reassign the ID back to <a href=\"https:\/\/golemitegames.com\/index.php\/docs\/unique-id\/\" title=\"Unique ID\">UniqueID<\/a> using AssignNewID.<\/p>\n\n\n\n<p>To summarise &#8211; <br><br>1. Store the ID in your own saving logic<br><br>2. During your own loading phase when you are loading gameobjects back into the scene, use the stored ID to get the saved data using the above methods.<br><br>3. Get the ISaveable interface from the gameobject that is now placed in the scene. Call the saveableObject.RestoreState(data) function with the data returned from the Dictionary. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\" style=\"font-size:22px;text-transform:capitalize\">Scripting<\/h2>\n\n\n\n<p>There are a few public methods to assist with saving and loading <\/p>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-csharp\" data-lang=\"C#\" data-show-lang=\"0\"><code>\/\/\/ &lt;summary&gt;\n\/\/\/ Register an ISaveable to save with the SaveManager\n\/\/\/ &lt;\/summary&gt;\n\/\/\/ &lt;param name=&quot;saveable&quot;&gt;The ISaveable to be saved&lt;\/param&gt;\npublic void RegisterSaveable(ISaveable saveable)\n\n\/\/\/ &lt;summary&gt;\n\/\/\/ Removes the ISaveable to be saved\n\/\/\/ &lt;\/summary&gt;\n\/\/\/ &lt;param name=&quot;saveable&quot;&gt;&lt;\/param&gt;\npublic void UnregisterSaveable(ISaveable saveable)\n\n\/\/\/ &lt;summary&gt;\n\/\/\/ Saves the current Resource and Production assets using the ISaveables list\n\/\/\/ &lt;\/summary&gt;\n\/\/\/ &lt;param name=&quot;filename&quot;&gt;&lt;\/param&gt;\npublic void SaveGame(string filename = &quot;savegame.json&quot;)\n\n\/\/\/ &lt;summary&gt;\n\/\/\/ Loads the current save and reapplies the current\n\/\/\/ &lt;\/summary&gt;\n\/\/\/ &lt;param name=&quot;filename&quot;&gt;&lt;\/param&gt;\npublic void LoadGame(string filename = &quot;savegame.json&quot;)\n\n\/\/\/ &lt;summary&gt;\n\/\/\/ Tries to get the save data from the current scene\n\/\/\/ &lt;\/summary&gt;\n\/\/\/ &lt;param name=&quot;filename&quot;&gt;Optional override if you saved the game with a custom file name&lt;\/param&gt;\n\/\/\/ &lt;returns&gt;A Dictionary&lt;string, object&gt; of saveable objects&lt;\/returns&gt;\npublic Dictionary&lt;string, object&gt; TryGetSaveData(string filename = &quot;savegame.json&quot;)\n\n\/\/\/ &lt;summary&gt;\n\/\/\/ Loads and returns the saved data for a specific UniqueID directly from the save file.\n\/\/\/ Does not require LoadGame() to have been called.\n\/\/\/ Returns null if no entry or type mismatch is found.\n\/\/\/ &lt;\/summary&gt;\npublic T GetSavedData&lt;T&gt;(string uniqueId, string filename = &quot;savegame.json&quot;) where T : class<\/code><\/pre><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Introduction This Manager class handles saving the data from this asset, which includes the Resource Node, Item Container and Crafter components. All of these components self register themselves with this manager to make sure they are saved if they still exist. It uses the ISaveable interface, alongside the SaveableObject component. The former must be implemented [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"doc_category":[46],"doc_tag":[],"class_list":["post-2371","docs","type-docs","status-publish","hentry","doc_category-resource-and-production"],"acf":[],"aioseo_notices":[],"year_month":"2026-04","word_count":1101,"total_views":0,"reactions":{"happy":0,"normal":0,"sad":0},"author_info":{"name":"rickitz5h","author_nicename":"rickitz5h","author_url":"https:\/\/golemitegames.com\/index.php\/author\/rickitz5h\/"},"doc_category_info":[{"term_name":"Resource And Production","term_url":"https:\/\/golemitegames.com\/index.php\/docs-category\/resource-and-production\/"}],"doc_tag_info":[],"_links":{"self":[{"href":"https:\/\/golemitegames.com\/index.php\/wp-json\/wp\/v2\/docs\/2371","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/golemitegames.com\/index.php\/wp-json\/wp\/v2\/docs"}],"about":[{"href":"https:\/\/golemitegames.com\/index.php\/wp-json\/wp\/v2\/types\/docs"}],"author":[{"embeddable":true,"href":"https:\/\/golemitegames.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/golemitegames.com\/index.php\/wp-json\/wp\/v2\/comments?post=2371"}],"version-history":[{"count":12,"href":"https:\/\/golemitegames.com\/index.php\/wp-json\/wp\/v2\/docs\/2371\/revisions"}],"predecessor-version":[{"id":2550,"href":"https:\/\/golemitegames.com\/index.php\/wp-json\/wp\/v2\/docs\/2371\/revisions\/2550"}],"wp:attachment":[{"href":"https:\/\/golemitegames.com\/index.php\/wp-json\/wp\/v2\/media?parent=2371"}],"wp:term":[{"taxonomy":"doc_category","embeddable":true,"href":"https:\/\/golemitegames.com\/index.php\/wp-json\/wp\/v2\/doc_category?post=2371"},{"taxonomy":"doc_tag","embeddable":true,"href":"https:\/\/golemitegames.com\/index.php\/wp-json\/wp\/v2\/doc_tag?post=2371"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}