Search Unity

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:
    772
    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,215
    @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:
    772
    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,215
  5. melgeorgiou

    melgeorgiou

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

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    772
    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:
    9
    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:
    772
    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:
    772
    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:
    772
    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:
    772
    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:
    772
    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:
    772
    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:
    43
    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:
    772
    Hi @MoFaShi,

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

    Thanks! :)

    - Mel
     
  17. indie_dev85

    indie_dev85

    Joined:
    Mar 7, 2014
    Posts:
    52
    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:
    772
    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,462
    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:
    772
    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:
    772
    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:
    772
    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:
    43
    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:
    772
    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:
    335
    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:
    772
    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:
    335
    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:
    772
    Hi Chris,

    Sounds good! :)

    - Mel
     
  30. f1chris

    f1chris

    Joined:
    Sep 21, 2013
    Posts:
    335
    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:
    772
    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:
    335
    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:
    772
    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:
    335
    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:
    772
    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:
    43
    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:
    772
    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
  38. MoFaShi

    MoFaShi

    Joined:
    Oct 25, 2015
    Posts:
    43
    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:
    772
    Hi @MoFaShi

    This is likely because you didn't save and reload the data from a Save Point 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 represent 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 2 steps. First, you would change to the new Save Slot and then you would 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 Save Slot 1
    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 Save Slot 2
    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 Save Slot 3
    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 (more specifically, what actions trigger a file operation). You will also notice that if you simply change Save Slots, the data in Local and Global Data tabs won't change. This is because you must ALSO load a Save Point from the new slot in order to load the Save Point's 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 27, 2020
  40. IceTrooper

    IceTrooper

    Joined:
    Jul 19, 2015
    Posts:
    36
    Hi, first of all, thank you for your asset. I'm trying to integrate it into my game. Looks really good so far.
    I thought that it'd be nice to have a constants (static class with const strings .cs file) generator for Local/Global keys/groups names based on DataKit Setup ScriptableObject. Is it possible to add this feature/button to generate in DataKit Setup -> Options? If not, can you help me to add this on my own? I've never autogenerated any code before.
    It will certainly help in a code to not mistype some key/group name. It's nice that DataKit supports auto-creating not founded keys, but when you want guaranteed safety those constants could help.
    Code simple like that:
    Code (CSharp):
    1. namespace HellTap.DataKit
    2. {
    3.     public static class DataConstants
    4.     {
    5.         // Groups
    6.         public const string GlobalGroupDefault = "Data";
    7.         public const string LocalGroupDefault = "Data";
    8.         public const string LocalGroup_IAP = "IAP";
    9.  
    10.         // Keys
    11.         public const string GlobalKey_MusicMuted = "MusicMuted";
    12.         public const string GlobalKey_SoundMuted = "SoundMuted";
    13.         public const string LocalKey_BestScore = "BestScore";
    14.         // ...
    15.     }
    16. }

    Waiting for your response :)
     
  41. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    772
    Hi @IceTrooper,

    Firstly, thanks for your interest in DataKit! :)

    If you could send me a PM with your invoice ID ( so I can verify your purchase ) I'll try to add this feature for you as soon as I can. It *should* be possible!

    Hope this helps! :)

    - Mel
     
  42. CashDevs

    CashDevs

    Joined:
    Oct 16, 2019
    Posts:
    1
    Hey! Just picked up DataKit. I'm really excited to dive into it. It's surprising to see DataKit not get the attention it deserves... I've only glanced at the other 'popular' options, but this one appears to be the most powerful and intuitive solution for handling data in unity. Hopefully you catch on!

    I have a quick question before I fully implement DataKit into my current project. I noticed that upon importing, the asset folder 'Hell Tap Entertainment' isn't placed in the 'Plugins' folder like is standard for so many asset store plugins. Could I manually move it in there, or will this break functionality? If I can't, is it possible to rename the Hell Tap folder or to take the DataKit folder out of the Hell Tap folder? Honestly the name 'Hell Tap Entertainment' isn't a very appealing name to me and I'd rather not have to glance at it every time I work on this project for the next 5 years :D
     
  43. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    772
    Hi @CashDevs,

    Firstly, thanks for purchasing DataKit and for the positive feedback! :)

    Unfortunately there is a very specific purpose that folder isn't in Plugins ( it actually was in DataKit v1 but I changed it in V2 ).Usually, plugins would compile first which is why they are placed in the Plugins folder. DataKit is actually a special use case because it is possible to write custom surrogates for your own classes ( if you choose to ) as well as potentially support more complex stuff in the future (without breaking your existing games). Because of this, DataKit needs to be compiled at the same time as your other standard scripts so it cannot be in Plugins. There are more technical reasons explained in the docs, too.

    Changing the name will likely break stuff so you will need to modify the file paths located in several scripts because the DataKit Setup asset as well as the Resource Database asset have hardcoded paths, as well as the menu shortcuts script. You will also have to do this again after every DataKit update ( or choose not to update which is fine, too ). It's not a crazy hard thing to change on your end, but does require some effort.

    TLDR: I wouldn't recommend doing this as it'll likely cause more headaches than it solves. However, If you really want to change the name of that folder it's unfortunately going to take a little bit of work on your part. If you want more information about how you can do this, please send me a PM with your invoice ID and I'll give you some pointers :)

    Hope this helps! :)

    - Mel
     
    CashDevs likes this.
  44. IceTrooper

    IceTrooper

    Joined:
    Jul 19, 2015
    Posts:
    36
    Hey once again ;)
    I got few questions:
    1. DataKit preloading performs only Initalization operation, right? It doesn't load any data? I'm asking because I couldn't respond to "OnLoadGlobalDataSuccessful" event and set my custom variables according to loaded data.
    2. How to turn off DataKit preloading? If I got 2 scenes currently opened it removes them and loads only Active (one scene). EDIT: Ok I found this option.
     
    Last edited: Sep 9, 2020
  45. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    772
    Hi @IceTrooper :)

    1) DataKit preloading is a helper feature in the Editor to load and setup DataKit before the scene in the Editor begins. It calculates the Save Point Map, loads your latest save point (or default data) as instructed in DataKitSetup options, and then loads your scene. It's supposed to mimic the fact that DataKit is usually ready before loading your first game level while your splash screens are showing, etc.

    2) You can turn it off in the DataKitSetup options. However, after you disable it DataKit will need to initialise when you press play in the Editor and may take a good few frames to complete its setup ( which usually happens during game splash-screens, etc). It usually takes about the same amount of time as the preloading splash screen you see when preloading is enabled.

    Hope this helps! :)

    - Mel
     
  46. IceTrooper

    IceTrooper

    Joined:
    Jul 19, 2015
    Posts:
    36
    You're too fast with replies, haha. Thank you.
    3. Is it possible to load only local data? I see that when Initialization is done it loads global data automatically. When I want to load also a local data (I got only one SavePoint and Slot) with Load or with AutoLoad it loads local+global(again). Is it good to load global data two times in short span?
     
  47. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    772
    Hi @IceTrooper,

    No worries! :)

    At the moment, Global Data is always loaded by default because it's supposed to always be 'in-sync' with local data. I may look into adding a way to do local-only in a future version of DataKit.

    For the moment however, DataKit is super fast ( and uses its own threads when needed ) so it's highly unlikely you'll notice any lag (unless you're doing something crazy like saving huge amounts of raw data from images and audio into the global data file as opposed to using the External Assets feature). So yeah, don't do that and you'll be fine :)

    Hope that helps! :)

    - Mel
     
    IceTrooper likes this.
  48. IceTrooper

    IceTrooper

    Joined:
    Jul 19, 2015
    Posts:
    36
    Hi again :)
    I've just integrated DataKit with cloud saving (EasyMobile package). Mostly, I'm using DataKit events to react on LoadEnded, SaveEnded, etc. After some testings, it looks good. Anyway, I didn't found that in the documentation:

    1. How to check if I can call DataKit.GetSerializedGlobalData()? Is it ok if I got no data saved and call this method? It should return empty string which is desired.

    2. Is it ok to call DataKit.SetSerializedGlobalData("") <- with empty string? I think I got a warning. Simply I want to wipe out entire GlobalData (in precise: I want to revert to initial data, but sometimes I got empty string as inital data).

    3. Should I call DataKit.AutoLoad after DataKit.SetSerializedGlobalData? As I mentioned before, I'm working with DataKit events like OnLoadGlobalDataSuccessful/OnLoadGlobalDataFailed. Those events aren't raised when I used SetSerializedGlobalData. Is there any event to know that I set GlobalData by SetSerialized? Should I just call method on my demand instead of event when working with SetSerialized?

    4. I'm struggling with Global data loading right after the initialization. I don't have control about it. For me, it's annoying because I want to load Global data and Local data in one call. Now I got something like this:
    a) I call DataKit.Init
    b) Automatically DataKit loads Global data
    c) My cloud saving system react to OnLoadGlobalSuccessful/OnLoadGlobalFailed and loads saved games from cloud (performs some operations)
    d) If I want to load local save (in my game I got only one hardcoded in scripts), I have to call AutoLoad which causes c) to work again unnecessary.

    In this problem, I see that I need to have LoadGlobal and LocalLocal separated methods OR get rid of automatically global data loaded right after the initialization. In the second case, I would manually call AutoLoad once and it would load local and global data after Init. But I think it would be easier to work with first fix (separated Save/Load Local/Global).

    PS I can show you two scripts in DM (one for DataKit and one for cloud saving) if you want to see how I did that.
     
    Last edited: Sep 21, 2020
  49. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    772
    Hi @IceTrooper ,

    As this is a very specific question to your own project, I'll send over a PM in a few! :)

    - Mel
     
    Last edited: Sep 21, 2020
  50. jeromeWork

    jeromeWork

    Joined:
    Sep 1, 2015
    Posts:
    429
    Hi @melgeorgiou I'm a bit fan of MeshKit and PoolKit which is why I'm looking at this asset. My current data saving and serialization solution seems to no longer be supported so it may be time for a change :)

    I've been looking at the videos and I'm a bit confused and overwhelmed by the options and functionality.

    What I'm finding a little confusing is that so much of the functionality seems to be focused on in Editor management, so for example handling multiple 'player' profiles or preloading "existing data" (template data?), I can't get my head around how it would work in practice in the kinds of applications I make.

    I don't make games in the traditional sense (with save points) instead I create apps for research purposes.
    My set-up usually involve one or more therapists (doctors) logging into the app on the same PC.
    They then run multiple sessions with different patients. (Each session is the equivalent of a scene in a game, with the patient acting as a player character)
    The data for each of these sessions needs to be saved.
    The kind of data that is saved is both finite values (e.g. the patient's ID, how long the session lasted, or what choice the patient picked for various in-game questions) but also continuous values (e.g the position of the user's avatar (Vector3) sampled every 30 seconds, for example)

    Is there any chance you could explain how this would be set-up using DataKit?

    Would Save Slots be each of the different therapists? (Can they be added at runtime through code?)
    Would adding a new patient in the app UI need to dynamically add a new group, containing the different keys that are being saved.
    And would each of the sessions for each patient be a different SavePoint in each of these different groups?
    How would the saving of continuous values be handled?

    Another big requirement for me is being able to get the data out. One of the videos mentions that saves are fairly obfuscated by default. Is there a way to get the out in a format that can be parsed. i.e. XML or JSson, so that it can be loaded in Excel or Access for analysis? Or, in the case of the same application running on multiple PCs, to enable the data from both to be collected into one data store.

    Sorry for the wall of text! Hopefully that all makes sense. Please do feel free to PM me if it's better to discuss out of the forum. I just want to make sure the asset will do what I need before making a jump to this new system.