Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice
  2. Ever participated in one our Game Jams? Want pointers on your project? Our Evangelists will be available on Friday to give feedback. Come share your games with us!
    Dismiss Notice

Data Kit – The Reimagined Data Serialization System For Unity

Discussion in 'Assets and Asset Store' started by melgeorgiou, Jun 15, 2019.

  1. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    634
    Hi everyone,

    I'd like to introduce DataKit, a reimagined new approach to saving and loading your game’s data - soon to be released on the Asset Store!

    large_image_template website_PNG.png

    About DataKit v2.0

    Almost every game has data that needs to be saved and loaded. But let’s face it, working with data is often very abstract, difficult to visualise and down right tedious to debug. How about serialising different data types? That’s a whole other set of problems!

    DataKit is a unique cross-platform data serialization system to automatically handle most aspects of saving and loading your game’s data. Features include local and global data, save slots, save points, data groups, obfuscation, encryption and even automatic screenshots. Another great DataKit feature is the intuitive visual debugger, allowing you to view, edit, delete and restore your serialized data in real-time while testing your games in the Editor! DataKit is a powerful core asset that any game project could benefit from!

    Offering unique and intuitive visual editors, you can easily setup and debug the data you’d like to save. DataKit offers “Global Data” for storing things like graphics settings or In-App Purchases and “Local Data” for setting up what is saved in each save point. All of your data keys are organized into groups for better management and fast performance.

    Along with options to save your data to local files or directly into PlayerPrefs, you can also choose how many save slots and save points you’d like DataKit to manage for you. Save slots allow you to implement multiple characters or accounts. Save points are essentially snapshots of local data, allowing a user to load the state of the game at a previous point in time. DataKit can also manage deleting the oldest save points to keep within a maximum limit.

    Unlike systems such as PlayerPrefs which only support saving integers, floats and strings; DataKit allows you to serialize most common data types, even when using arrays and custom classes (see ‘Compatible Types’ in the documentation PDF for a full list). DataKit also offers a variety of ways to serialize references. As well as saving many reference types by value, the optional Reference Database system allows you to directly reference specific assets located in the Resources folder.

    DataKit also features some powerful obfuscation options! You can deter cheating by obfuscating your data with 128-bit AES Encryption or with the faster but less secure XOR algorithm. If you don’t need encryption, DataKit can literally strip it out of its own codebase using a simple platform define in Unity’ Player Settings.

    In short, DataKit is a powerhouse of a plugin that will give you new and intuitive ways to save, load and debug your game’s data!

    Features
    • Visually Setup & Debug Your Game’s Data!
    • Automatically Handle All File I/O!
    • Local & Global Data!
    • Data Groups & Keys!
    • Save Slots & Save Points!
    • Serialize Common Value & Reference Types!
    • Optional XOR Obfuscation!
    • Optional AES Encryption!
    • Optional Reference Database System!
    • Automatically Capture Screenshots!
    • Preload Data In Editor For Fast Testing!
    • Event Driven API!
    • Comes with 8 Fully Commented Example scenes!
    • Documentation PDF and High quality video tutorials!
    • Full source, No DLLs!
    • Fast and friendly email support!
    • Compatible with Unity 2018.x to 2019.x!

    Introduction Video

    Find out more about DataKit in this overview video:




    Promo Images

    Find out more about DataKit in these images:

    DataKit - Promo 01 - A New Approach To Saving Your Games.png DataKit - Promo 02 - Visually Create Data.png DataKit - Promo 03 - Easily Debug Your Data.png DataKit - Promo 04 - Save Points And Save Slots.png


    Tutorial Videos:


    Follow these tutorials to become a Data Kit pro! :)

    > DataKit Overview Video
    > Tutorial 1 - Setting And Debugging Data
    > Tutorial 2 - Reference Database
    > Tutorial 3 - Scripting With DataKit


    Documentation

    Take a look at the Data Kit manual here:

    > Documentation (PDF)


    WebGL Demo:

    Check out this WebGL demo to view the fully commented example scenes that come with DataKit:

    > DataKit Tech Demo (WebGL)


    Where To Get DataKit

    DataKit can be purchased from the Asset Store or my own site!

    Get DataKit From the Asset Store:
    Data Kit - The Reimagined Data Serialization System For Unity

    DataKit is also available on my site too which can be found here: http://www.unitygamesdevelopment.co...imagined-data-serialization-system-for-unity/



    Thanks for your interest! If you have any questions, feel free to ask! :)

    - Mel
     
    Last edited: Oct 1, 2019
    Gekigengar likes this.
  2. Duffer123

    Duffer123

    Joined:
    May 24, 2015
    Posts:
    1,060
    @melgeorgiou , hi, really interested in this asset - but what I really need is something which also saves scene gameobjects with their components and and component fields/properties values - which can change in runtime?
     
  3. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    634
    Hi @Duffer123,

    Firstly, thanks for your interest in DataKit! :)

    This is something I'll be looking into as DataKit moves forward, although to be honest it isn't the most efficient way of saving your games because there is usually a lot of redundant data that is saved along with it. All of this has an impact on performance and disk space. However, I know that some people prefer convenience over efficiency so I will be looking more closely at that as DataKit evolves! :)

    In the meantime, DataKit has some pretty cool example scenes that show how to save objects (even instantiated ones) in your scene using a more efficient approach!

    Hope this helps! :)

    - Mel
     
    Duffer123 likes this.
  4. Duffer123

    Duffer123

    Joined:
    May 24, 2015
    Posts:
    1,060
  5. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    634
  6. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    634
    DATA KIT v1.0 IS NOW LIVE ON THE ASSET STORE!

    DataKit v1.0 is now LIVE on the Asset Store!

    IMPORTANT: Please remember to backup your projects before installing! :)

    - Mel
     
    Duffer123 likes this.
  7. Onevisiongames

    Onevisiongames

    Joined:
    Aug 3, 2016
    Posts:
    8
    Looks very good so far!

    Any plans for integrations/compability for projects that are developed for PC but also ported to consoles? (Xbox One, PS4, Nintendo Switch)
     
  8. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    634
    Hi @Onevisiongames!

    Firstly, thanks for your interest in DataKit! :)

    As far as I know, DataKit *should* work on consoles ( although in honesty, I haven't been able to verify as I don't personally develop projects on those platforms ). I've tested on iOS, Android, Windows, Mac and WebGL so far.

    BTW: There is also a PlayerPrefs storage mode in DataKit. This is what DataKit uses for WebGL in order to circumvent saving to local files (which is forbidden on the platform). Instead, it uses PlayerPrefs as an intermediary without losing any DataKit functionality ( other than Unity's 1MB PlayerPrefs limit ). This should theoretically allow you to save data even if there was an issue that I'm not aware of.

    ... So yeah, I don't see why it wouldn't work but probably best to test early on to make sure!

    Hope this helps! :)

    - Mel
     
    Last edited: Jun 23, 2019
  9. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    634
    DATA KIT v1.0.1 IS NOW LIVE!

    Hi everyone!

    DataKit v1.0.1 is now LIVE on my site: here
    I'll let everyone know when DataKit v1.0.1 is approved by the Asset Store! :)

    ALWAYS BACKUP YOUR PROJECTS BEFORE UPDATING!

    IMPORTANT:
    When you open the package to install the update, make sure to DESELECT the 'DataKit Setup' and 'DataKit References' assets from the list. If you don't do this they will be overwritten with the default versions!


    WHAT'S NEW:

    This is an important maintenance update:

    - DataKit now handles corrupted data files when building save point maps.
    - Fixed potential memory leak when updating save point maps ( Texture2D Screenshots )
    - Fixed a memory leak in the mini Notifications UI in the demo scenes.
    - Fixed bug with Vector4's not saving the W value correctly.



    WHAT'S NEXT FOR DATAKIT?

    DataKit V2 has been in the works for several months and is almost ready! For now, I'll just say that it is a GARGANTUAN update that introduces some really cool and unique features. It will also be a FREE update to everyone who has purchased DataKit v1.x. I'll be releasing more details about the cool new features very soon! :)

    - Mel
     
    Last edited: Aug 26, 2019
  10. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    634
    DATA KIT v1.0.1 IS NOW LIVE ON THE ASSET STORE!

    DataKit v1.0.1 is now LIVE on the Asset Store!

    ALWAYS BACKUP YOUR PROJECTS BEFORE UPDATING FROM A PREVIOUS VERSION!

    IMPORTANT:
    When you open the package to install the update, make sure to DESELECT the 'DataKit Setup' and 'DataKit References' assets in the list. If you don't do this they will be overwritten with the default versions,

    Thanks! :)

    - Mel
     
  11. lynnetelfermc

    lynnetelfermc

    Joined:
    Jun 10, 2017
    Posts:
    1
    LOVE this! How do I customise the start screen? For example, Datakit StartupScreen scene? I can change the Full screen panel with the text and images I cannot find where the first splash screen is run or stored.
     
  12. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    634
    Hi @lynnetelfermc

    Firstly, thanks for purchasing DataKit! :)

    If you can send me a PM with your invoice ID I'll be happy to help!

    - Mel
     
  13. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    634
    DATA KIT v2.0 IS NOW LIVE!

    Hi everyone!

    DataKit v2.0 is now LIVE on my site: here

    ALWAYS BACKUP YOUR PROJECTS BEFORE UPDATING!

    IMPORTANT WARNINGS FIRST:


    There is a big change in DataKit v2.0 which means that older save game data from DataKit v1.x can no longer be loaded. If your game has already been released, do not upgrade your version of DataKit for that project. Otherwise, please back it up and follow the upgrade guide found in the new documentation here.

    Now that's out of the way, let's check out what's new! :)

    WHAT'S NEW:

    Here's an overview of the new update:

    - Implemented "External Assets". Users can now save assets into their own external files to keep DataKit's core save data lightweight and blazingly fast!
    - Reference Database V2: allows sub-assets (children), automatic updates when creating builds, optional initialization modes and support for Transforms (via GameObjects).
    - New multi-threading for loading, saving and deleting external files.
    - inspector types: byte, short, decimal, AnimationCurve, Gradient, Shader and Transform.
    - New updated serializable types now use constants to cache keys resulting in much better performance!
    - Save / Load Global Data independently in the Editor.
    - Debugging options for threads and external assets.
    - DataKit.IsReferenceDatabaseReady() API method to check whether the Reference Database is ready.

    Let's zero in on some of the bigger features:

    EXTERNAL ASSETS

    External assets allow you to save an asset to a data key (similar to the existing SetLocalAsset method) but have DataKit automatically link the key to an external file in your save point folder. No filepaths are needed, DataKit automatically handles everything and allows you to keep your core save game data small and blazingly fast! :)

    Note that External Assets are not compatible with WebGL builds so be sure to use them only if you're not going to need that platform.

    REFERENCE DATABASE V2

    The Reference Database has had a massive revamp which now allows it to not only track references in your Resources folders, but also specific child objects inside of those resources (the lack of child support was the biggest limitation in the previous version).

    ReferenceDatabaseV2.png

    There is also a much faster instantiation routine, with options to use the older method if preferred.

    NEW TYPES

    There are loads of new types that are available for real-time debugging in the Editor including byte, short, decimal, AnimationCurves, Gradients, Shaders and Transforms!

    PERFORMANCE IMPROVEMENTS

    All DataKit types have been updated to use constant strings to set and load keys (which reduces memory allocations and improves performance). Multi-threading has also been added for most file operations which makes loading, saving, switching save points, etc super fast behind the scenes!

    I hope everyone is looking forward to V2 - it is of course a free upgrade! :)

    Feel free to checkout the updated documentation in the meantime. I'll let everyone know when DataKit v2.0 is approved by the Asset Store! :)

    - Mel
     
    Last edited: Sep 28, 2019
  14. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    634
    DATA KIT v2.0 IS NOW LIVE ON THE ASSET STORE!

    DataKit v2.0 is now LIVE on the Asset Store!

    ALWAYS BACKUP YOUR PROJECTS BEFORE UPDATING FROM A PREVIOUS VERSION!

    IMPORTANT:
    There is a big change in DataKit v2.0 which means that older save game data from DataKit v1.x can no longer be loaded. If your game has already been released, do not upgrade your version of DataKit for that project. Otherwise, please back it up and follow the upgrade guide found in the new documentation here.

    Thanks! :)

    - Mel
     
  15. MoFaShi

    MoFaShi

    Joined:
    Oct 25, 2015
    Posts:
    35
    Hi, I have just bought this asset yesterday and have some questions about the Save Slots,
    1. how could I know which slot is to be used? I found there no methods like HasDataInSlot or similar methods.
    2. how could I delete all data from a Slot?
     
  16. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    634
    Hi @MoFaShi,

    I've replied to your PM - answers are over there!

    Thanks! :)

    - Mel
     
  17. indie_dev85

    indie_dev85

    Joined:
    Mar 7, 2014
    Posts:
    51
    hi Mel,

    I am looking forward to purchase a license of DataKit.

    Can datakit handle saving/loading data of multiple player units data so as to create a checkpoint type save system?
    (Assume a RTS example with a level having 10-15 different player troops)

    Thanks
     
  18. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    634
    Hi @indie_dev85

    Thanks for your interest in DataKit! :)

    Sure, as long as you design your data to store it I don't see why not :)

    Hope that helps!

    - Mel
     
  19. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,334
    Cool asset, I bought it.
    Would like to sync the data to a mysql server for a multiplayer game.
    The reason for syncing to a mysql server so that the data can be querried using sql statements.
     
  20. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    634
    Hi @EmeralLotus,

    Firstly, thanks for purchasing DataKit! :)

    Please send me a PM / email with your invoice ID and we can take it from there!

    Thanks,

    - Mel
     
  21. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    634
    DATA KIT v2.1 IS RELEASED!

    It should also be approved soon on the Asset Store!

    ALWAYS BACKUP YOUR PROJECTS BEFORE UPDATING FROM A PREVIOUS VERSION!

    This maintenance update provides fixes for Unity 2019.3.


    FOR USERS UPDATING: There are a lot of big changes in Unity 2019.3. Along with fixes for the new GUI, users should be aware of Unity's new AssetDatabaseV2 which may cause issues with DataKit's Reference Database:

    It is recommended that if you have already released your game and you need to upgrade to Unity 2019.3, you should NOT upgrade your AssetDatabase to V2 when asked. This is because the upgrade may change your original GUIDs (not much is known on how Unity updates the old AssetDatabase so it is best to play it safe). Generally speaking, if your game has already shipped, its usually best to avoid Unity updates altogether if at all possible!

    If your game hasn't been released yet, this shouldn't be much of an issue. After upgrading to Unity's AssetDatabaseV2, you should go to your ReferenceDatabase and find your assets again (this *may* affect your previous save points in the Editor but new save points should be fine).

    ... Of course, if you weren't saving data using the Reference Database you should also be fine!

    Thanks! :)

    - Mel
     
  22. magic_paw

    magic_paw

    Joined:
    Feb 7, 2020
    Posts:
    1
    Can I nowadays save whole Gameobject with the DataKit?


    I have a situation when I need to serialize/deserialize objects with references to another, dynamically created, objects.

    Like, lets say I have a house, which through the game produces units and has to keep track of those.
    When saving and then loading, I have to recreate this.
    I would like to avoid having to manually invent some kind of mapping between unit and house, then saving this mapping, then loading it, and assigning back.

    So instead I have all units being children of the house in the scene. This way GetComponentInChildren<Unit>() can give my house all the units its responsible for.
    But in order to do this, I need to serialize whole House Gameobject with all the children Unit objects.

    Is this something that DataKit is supporting?
    If yes, could you point me to an example, on the scripting side, how does the serialize call/setup will looks like with DataKit?
     
  23. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    634
    Hi @magic_paw,

    Firstly, thanks for your interest in DataKit! :)

    Unfortunately serialising entire Gameobjects is not directly supported in DataKit. In my testing, I've found that it is much slower, more memory intensive and requires huge amounts of disk space to save GameObjects directly due to unnecessary complexity.

    The 'mapping' approach you are trying to avoid (which DataKit can certainly help with) seems to me to be the most efficient way to solve your issue, although I fully understand the rationale of trying to find an easier way to do it! :)

    - Mel
     
  24. MoFaShi

    MoFaShi

    Joined:
    Oct 25, 2015
    Posts:
    35
    Cant work with Unity 2019.3.3f1, whenever I save game data, an error appears that said "
    Destroying assets is not permitted to avoid data loss.
    If you really want to remove an asset use DestroyImmediate (theObject, true);
    UnityEngine.Object:Destroy(Object)
    HellTap.DataKit.<CreateSavePointMapCoroutineLocalFiles>d__111:MoveNext() (at Assets/Hell Tap Entertainment/DataKit/Scripts/DataKitManager.cs:1075)
    UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
    HellTap.DataKit.<SaveCoroutine>d__6:MoveNext() (at Assets/Hell Tap Entertainment/DataKit/Scripts/DataKitSaver.cs:598)
    UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)"

    the demos cant work as well, please fix it, thank you.
     
  25. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    634
    Hi @MoFaShi,

    Nobody else has reported this, so thanks for letting me know. However, I've just tried to recreate your issue but everything seems to work fine on my side. I've tried on both Windows and Mac OS X using 2019.3.4 (as 2019.3.3 is no longer available on the hub).

    Could you please send me a PM with some extra info:

    - Unity Editor Platform ( Windows, Mac? )
    - Version of DataKit (are you using the latest v2.1?)
    - If you could put together a small project that recreates this issue, that would be very helpful.

    Thanks! :)

    - Mel
     
    Last edited: Mar 11, 2020
  26. f1chris

    f1chris

    Joined:
    Sep 21, 2013
    Posts:
    302
    Hi Mel,

    I own a few of your assets (Poolkit, Meshkit) and I have to say they’re fantastic. I’m sure DataKit is as well and it’s next in my list as I’m now needing a robust save system.

    My game is a big multi-scenes world. Scenes are loaded on streaming like mechanic. So when i reach a certain area, an additive scene is loaded and Poolkit is doing a great job spawning my NPCs & pickups.

    For sure now I’m at the point where when I leave a certain area, I want to save the NPCs still alive and reload them next time i ré-enter that area.

    I watched all your tutorials and I’m convinced DataKit can handle it graciously but just wanted your input on the most efficient way to make it work with Poolkit.

    Thx
    Chris
     
  27. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    634
    Hi Chris,

    Firstly, thanks for purchasing some of the other tools, much appreciated! Also, thanks for your interest in DataKit :)

    DataKit makes it easy to save lots of different kinds of data in a very streamlined and powerful way. As you are in charge of designing what data you're saving and when, much of the implementation will be down to what makes most sense for your specific game. This makes providing direct recommendations somewhat difficult but I'll offer a few general thoughts on some of the areas you mentioned:

    Loading in your scenes is something where you're likely to tinker the most as there is no example for that included. However, it should simply be a case of you saving the name or path of the current scene as it is loaded into a DataKit key. When a user creates the save point, the current scene name/path will be included too. When a user loads a save point, you would simply use that key to grab the path / name of the scene with your own streaming code.

    Handling NPCs is a common scenario and luckily there is a very detailed example included with DataKit showing one way to save/load instantiated GameObjects You would have to modify that slightly if you're using PoolKit to spawn these instances rather than instantiate them but the concept should more or less be the same. The same approach should also apply to pickups :)

    I hope this helps! :)

    - Mel
     
    Last edited: Apr 1, 2020
    Duffer123 likes this.
  28. f1chris

    f1chris

    Joined:
    Sep 21, 2013
    Posts:
    302
    Thanks Mel.

    Yes for the handling of the scenes, detecting when it’s loaded or unloaded is not a issue and I have mechanic already in place working flawlessly so this part should not be an issue. I will buy DataKit, probably today and starts playing with it and then come back with more questions for you ;-)
     
  29. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    634
    Hi Chris,

    Sounds good! :)

    - Mel
     
  30. f1chris

    f1chris

    Joined:
    Sep 21, 2013
    Posts:
    302
    Hi Mel,

    I'm having some issues to understand how DataKit works.

    I'm trying to save and load a list of prefabs previously spawned. Well in fact it's from your Poolkit script "SpawnerInstanceTracker". In the script there's a simple List of GameObject -> spawnedInstances

    I was under the impression that I would just add them to the DataKit database to be able to load/save that type of objects.

    Well in fact I'm a bit lost for now ;-)

    I have a suggestion for you : I think your Poolkit & DataKit would really benefit if you can give or market them together or provide a kind of integration. They're born to work together.
     
  31. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    634
    Hi Chris,

    Can you send me a PM / email with a little more information of what you're trying to do and we can take it from there?

    BTW: I'll look into providing some PoolKit / DataKit integration. I'm not exactly sure how I'd go about doing that but I'll certainly give it some more thought :)

    Thanks! :)

    - Mel
     
    Last edited: Apr 2, 2020
    f1chris likes this.
  32. f1chris

    f1chris

    Joined:
    Sep 21, 2013
    Posts:
    302
    I want to save each each or spawn area as a separate file when i exit that zone and the reload it when entering the zone.

    Is using different SaveSlots is the way to go ? Something scene1 one saved in saveslot #1, scene2 in saveslot #2 etc ???
     
  33. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    634
    Hi @f1chris ,

    Even though you probably could do it that way, dividing areas into save slots would probably be overkill and make things more complicated than it needs to be. One good way to think of it might be that save slots should normally be used to separate the entire data file of users / players / characters, etc. :)

    If you want spawn areas organised separately in your data, you would probably be better off using local data groups and storing your keys in there. That way you'd simply reload the data from the group or key rather than loading an entirely new file each time you want to grab that bit of data.

    There are lots of ways to implement this but I would probably approach it by having a data group with the name of the current level (or area if you're designing an open world game) and then have a key with the spawn area data in there - something like this:

    DataKit.SetLocalKey( "Level 1", spawnArea1 );

    The above will save the data of spawnArea1 into a local data group called "Level 1". Once it is set, you can reload it whenever you like after that.

    Hope that helps! :)

    - Mel
     
    Last edited: Apr 11, 2020
  34. f1chris

    f1chris

    Joined:
    Sep 21, 2013
    Posts:
    302
    Thanks again for your great support. I see now, a saveslot is like another file...or database i should say.

    For now I’m using for all my enemies where other than simple transform/position information I’m storing their health information. Eventually I’ll introduce pickups, players info and probably more.

    I had it working with one simple area for now and using autoSave/autoLoad in conjonction with your Poolkit/Spawner. First time I’m entering an area, the Spawner is spreading the enemies. After that, Datakit will do the job.

    It seems to be fast and smooth in the editor ( the datakit load and save) and I hope it will be the same in a build on a device. Other solutions I tried before were giving some hiccups on spawning.

    - Chris
     
  35. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    634
    Hi Chris,

    No worries!

    Save slots actually are a different collection of files behind the scenes so yes, you're entirely correct :)

    DataKit should work just as well in builds too!

    Have a great weekend! :)

    - Mel
     
    f1chris likes this.
  36. MoFaShi

    MoFaShi

    Joined:
    Oct 25, 2015
    Posts:
    35
    Hi,
    if (DataKit.IsReady())
    {
    DataKit.SetCurrentSaveSlot(1);
    DataKit.SetLocalKey("BaseData", role);
    }

    I am trying to change a slot and then saving the game data, but nothing happened. I don't know what am I doing wrong with this code?
     
  37. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    634
    Hi @MoFaShi,

    Ah, you're probably getting a console message telling you DataKit is in the middle of a file operation. This is because you changed the current Save Slot. Whenever you do that, DataKit has to load all of the save points and files associated to the Save Slot. As the console message explains, you can't set data while DataKit is in the middle of a file operation.

    Generally, you should avoid changing between Save Slots (unless it is a main menu where the player selects an account / character). In any case, here is one way you can refactor your code to achieve what you want to do:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using HellTap.DataKit;
    5.  
    6. public class AfterChangingSaveSlotExample : MonoBehaviour
    7. {
    8.  
    9.     // For consistency
    10.     string role = "role";
    11.  
    12.     // Start is called before the first frame update
    13.     void Start()
    14.     {
    15.  
    16.         // Run a set of actions After DataKit changes to a new Save Slot
    17.         StartCoroutine (
    18.             ChangeSaveSlotBeforeRunningAction(
    19.                 1, () => {
    20.  
    21.                     DataKit.SetLocalKey("BaseData", role);
    22.                     // ... more actions can go here!
    23.                 }
    24.             )
    25.         );
    26.      
    27.     }
    28.  
    29.     // This coroutine waits until DataKit changes to a specified Save Slot before running an action
    30.     IEnumerator ChangeSaveSlotBeforeRunningAction( int saveSlot, System.Action action ){
    31.  
    32.         // Make sure DataKit is ready to start with
    33.         if ( DataKit.IsReady() == true ){
    34.  
    35.             // Only change the save slot if it's different
    36.             if( DataKit.GetCurrentSaveSlot() != saveSlot ){ DataKit.SetCurrentSaveSlot( saveSlot ); }
    37.  
    38.             // Wait until the current save slot changes and DataKit is ready
    39.             while( DataKit.IsReady() == false ){ yield return null; }
    40.          
    41.             // Then, run any action we send to this coroutine
    42.             if( action != null ){ action(); }
    43.  
    44.  
    45.         // Otherwise show warning
    46.         } else {
    47.  
    48.             Debug.LogWarning("DATAKIT isn't ready yet!");
    49.         }
    50.  
    51.     }
    52.  
    53. }
    54.  

    This example calls a coroutine called ChangeSaveSlotBeforeRunningAction() that automatically changes the Save Slot to a specified int (and only if it is different), waits for all the file operations to finish ( and DataKit to become ready again ) before running some custom actions.

    When we call the coroutine ( the start method in this example), you can see that I've constructed an anonymous function "() => {}" to basically create any actions on demand so you can re-use this coroutine for pretty much any purpose.

    Hope this helps! :)

    - Mel
     
    Last edited: May 23, 2020 at 8:22 PM
  38. MoFaShi

    MoFaShi

    Joined:
    Oct 25, 2015
    Posts:
    35
    hi, this code is worked. but I encountered another problem.
    I just created ONE role in slot1, but I found that the slot2 and slot3 have the same role data as slot1.
    this is really weird, I can be sure I don't save any data to slot2 and slot3, any advice?
     
  39. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    634
    Hi @MoFaShi

    This is likely because you didn't save the data so you are still seeing the last key value you set in memory.

    I should have further explained that simply changing to a new Save Slot doesn't change the data in memory, it just tells DataKit that you now wish to work within a new Save Slot (this prepares the system and generates a new internal Save Point Map). It is important to understand that the local/global data tabs you see in the DataKit Debugger is the currently loaded data IN MEMORY and not what is saved on the disk. It also worth noting that each Save Slot has its own set of unique Save Points.

    In other words, updating DataKit's data in memory from a different slot requires you to load the new Save Slot and then load the newest Save Point from that Save Slot ( or if no Save Point exists there, you will likely want to revert the local data in memory to simulate a new default Save Point ).

    Here is a more complete example based on the previous one:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using HellTap.DataKit;
    5.  
    6. public class AfterChangingSaveSlotExample : MonoBehaviour
    7. {
    8.  
    9.     // Test Variables
    10.     string role1 = "role1";
    11.     string role2 = "role2";
    12.     string role3 = "role3";
    13.  
    14.     ////////////////////////////////////////////////////////////////////////////////////
    15.     //    START
    16.     //    Start is called before the first frame update
    17.     ///////////////////////////////////////////////////////////////////////////////////
    18.  
    19.     IEnumerator Start()
    20.     {
    21.  
    22.         Debug.Log("Setting up 1st Save Slot ...");
    23.  
    24.         // Run a set of actions After DataKit changes to a new Save Slot
    25.         yield return ChangeSaveSlotBeforeRunningAction(
    26.             1, () => {
    27.  
    28.                 DataKit.SetLocalKey("BaseData", role1 );
    29.                 // ... more actions can go here!
    30.             }
    31.         );
    32.  
    33.         // Save the data to a new save point and wait for it to complete
    34.         yield return CreateAndWaitForAutoSavePoint();
    35.  
    36.         Debug.Log("Setting up 2nd Save Slot ...");
    37.  
    38.         // Run a set of actions After DataKit changes to a new Save Slot
    39.         yield return ChangeSaveSlotBeforeRunningAction(
    40.             2, () => {
    41.  
    42.                 DataKit.SetLocalKey("BaseData", role2 );
    43.                 // ... more actions can go here!
    44.             }
    45.         );
    46.  
    47.         // Save the data to a new save point and wait for it to complete
    48.         yield return CreateAndWaitForAutoSavePoint();
    49.  
    50.         Debug.Log("Setting up 3rd Save Slot ...");
    51.  
    52.         // Run a set of actions After DataKit changes to a new Save Slot
    53.         yield return ChangeSaveSlotBeforeRunningAction(
    54.             3, () => {
    55.  
    56.                 DataKit.SetLocalKey("BaseData", role3 );
    57.                 // ... more actions can go here!
    58.             }
    59.         );
    60.  
    61.         // Save the data to a new save point and wait for it to complete
    62.         yield return CreateAndWaitForAutoSavePoint();
    63.  
    64.         Debug.Log("Example Finished -> Check the DataKit Debugger by clicking through Save Slots\n1 - 3 and loading the newest save points on each one.");
    65.  
    66.     }
    67.  
    68.  
    69.     ////////////////////////////////////////////////////////////////////////////////////
    70.     //    CREATE AND WAIT FOR AUTO SAVEPOINT
    71.     //    Calls AutoSave() and waits for it to complete
    72.     ///////////////////////////////////////////////////////////////////////////////////
    73.  
    74.     IEnumerator CreateAndWaitForAutoSavePoint(){
    75.  
    76.         // Create an automatic Save Point
    77.         DataKit.AutoSave();
    78.  
    79.         // Wait until the auto save is completed in the current slot
    80.         while( DataKit.IsReady() == false ){ yield return null; }
    81.     }
    82.  
    83.  
    84.     ////////////////////////////////////////////////////////////////////////////////////
    85.     //    CHANGE SAVE SLOT BEFORE RUNNING ACTION
    86.     //    We switch to a new save slot (using the 'newSaveSlot' integer).
    87.     //    If a Save Point exists in the new slot it is loaded. Otherwise, the current local
    88.     //    data is reverted to defaults. Finally, our own custom callback is run.
    89.     ///////////////////////////////////////////////////////////////////////////////////
    90.  
    91.     IEnumerator ChangeSaveSlotBeforeRunningAction( int newSaveSlot, System.Action callback ){
    92.  
    93.         // Make sure DataKit is ready to start with
    94.         if ( DataKit.IsReady() == true ){
    95.  
    96.             // --------------------------------------
    97.             // CHANGE TO THE NEW SAVE SLOT IF NEEDED
    98.             // --------------------------------------
    99.  
    100.             // Only change the save slot if it's different
    101.             if( DataKit.GetCurrentSaveSlot() != newSaveSlot ){
    102.  
    103.                 // Change to the new Save Slot
    104.                 DataKit.SetCurrentSaveSlot( newSaveSlot );
    105.  
    106.                 // Wait until the current save slot changes and DataKit is ready
    107.                 while( DataKit.IsReady() == false ){ yield return null; }
    108.  
    109.                 // ---------------------------------------------
    110.                 // HANDLE THE NEW SAVE SLOT BEFORE SETTING DATA
    111.                 // ---------------------------------------------
    112.  
    113.                 // If there are save points already in the new save slot, autoload the newest one
    114.                 if( DataKit.GetUsedSavePointCount() > 0 ){
    115.  
    116.                     // AutoLoad the latest save point from the new save slot
    117.                     DataKit.AutoLoad();
    118.  
    119.                 // Otherwise, revert local data to defaults
    120.                 } else {
    121.  
    122.                     // Reverts all the current local data in memory to the defaults (simulates a new save point with default data)
    123.                     DataKit.RevertAllLocalData();
    124.  
    125.                 }
    126.  
    127.                 // Wait until the new save slot auto loads / reverts data
    128.                 while( DataKit.IsReady() == false ){ yield return null; }
    129.             }
    130.  
    131.             // Then, run any callback action we send to this coroutine
    132.             if( callback != null ){ callback(); }
    133.  
    134.         // Otherwise show warning
    135.         } else {
    136.  
    137.             Debug.LogWarning("DATAKIT isn't ready yet!");
    138.         }
    139.  
    140.     }
    141.  
    142. }
    143.  

    Understanding The Code


    There are a few differences from the previous example:

    1) The main difference is in the 'ChangeSaveSlotBeforeRunningAction' method. I've now added extra code to handle the new save slot and check to see if it contains any save points. If it does, the newest save point is loaded first. If there are no save points, the local data in memory is reverted to the defaults that you've set up. This *should* make sure everything is managed properly.

    2) I've changed the Start method to a coroutine to show how you can chain this action together to modify several Save Slots, one after the other in a controlled way. It's also important to note that I'm saving the local data to Save Points before switching to a new save slot, otherwise those changes will be lost.

    3) I've made a helper method called 'CreateAndWaitForAutoSavePoint' which pretty much does what it says: It allows us to create a save point and wait for DataKit to finish in a single line to make things easier to understand.

    Reviewing the Results in the Debugger

    Once this example runs, it will have created 3 new Save Points, one in each of the first 3 Save Slots. You will actually understand how DataKit works a lot more by using the DataKit Debugger and observing how it works (more specifically, what actions trigger a file operation). You will also notice that if you simply change Save Slots, you will see that the Local and Global Data tabs don't change their data. This is because you must ALSO load the newest save point from those slots to load the Save Point data into memory.

    Just like the code we've setup above, the debugger works in the very same way :)

    Final Notes:

    In a real world project, I wouldn't recommend iterating through multiple Save Slots like I've done in this example. I've done it here primarily as a means to explain how DataKit works. In a real game, you'd normally want to have some kind of a menu screen at start where the player can select their 'account' or 'character' and you'd have something like the 'ChangeSaveSlotBeforeRunningAction' method running once for that purpose. After that point, you wouldn't need to worry about Save Slots again (unless you allow players to return to that menu of course).

    I hope this helps! :)

    - Mel
     
    Last edited: May 23, 2020 at 8:26 PM
unityunity