Search Unity

Easy Save - The Complete Save Data & Serialization Asset

Discussion in 'Assets and Asset Store' started by JoelAtMoodkie, May 28, 2011.

  1. JoelAtMoodkie

    JoelAtMoodkie

    Joined:
    Oct 18, 2009
    Posts:
    914
    ES2 doesn't natively support saving references, so to store references in ES2 you need to manage your own reference list.
     
  2. Wikzo-DK

    Wikzo-DK

    Joined:
    Sep 6, 2012
    Posts:
    83
    Hmm, forget what I said before: Unity still gets unresponsive. However, I think I have nailed it down to one of two prefabs. I am fairly confident it might have something to do with Full Inspector. Do you have any experience with that plugin?

    Apparently, it generates some files called fiBackupStorage.prefab and fiPersistentEditorStorage.prefab. It seems like these files themselves are dictionaries of other files. The two files are also referenced in the Easy Save 3 Manager. Not sure if a reference to a dictionary like this is a good idea?

    Sorry for keeping asking questions, but I really want it to work.
     
  3. JoelAtMoodkie

    JoelAtMoodkie

    Joined:
    Oct 18, 2009
    Posts:
    914
    Hi there,

    Easy Save only stores references to UnityEngine.Objects which are dependencies of the scene, which is something which Unity does itself under the hood anyway. It performs no processing on these objects.

    I'm afraid I have no experience of Full Inspector. Unfortunately it's difficult for me to pursue this further without a basic test project to test what is going on at my end.

    The only function the reference list performs outside of runtime is refreshing, so the only thing which could be happening is that the reference list is continually refreshing.

    We're changing the events used to automatically refresh the reference list in the next update, which might fix your problem. We're hoping to have this submitted for approval before the end of the week.

    All the best,
    Joel
     
  4. Wikzo-DK

    Wikzo-DK

    Joined:
    Sep 6, 2012
    Posts:
    83
    Ok, thanks. I am currently trying to isolate the problem as much as possible so that I can send you a dummy project.

    UPDATE: I've sent you a mail.
     
    Last edited: Jun 27, 2017
  5. ProdBySamson

    ProdBySamson

    Joined:
    Oct 22, 2015
    Posts:
    15



    Hi

    I was having a bit of trouble converting this to ES2/ ES3

    lockState + playerPrefsName + m_Name
    ---------------------------------------------------------------

    //Is the item locked or not? 0 = locked, 1 = unlocked
    public int lockState = 0;

    //The player prefs record for this item
    public string playerPrefsName = "";

    //The name
    public string m_Name;


    public void CheckLockState() {
    lockState = PlayerPrefs.GetInt(playerPrefsName);

    -------------------------------------------------------------------

    Would this be correct?

    if (ES3.KeyExists ("playerPrefsName"))
    lockState = ES3.Load (playerPrefsName,"");

    Thank you for your help :)
     
  6. JoelAtMoodkie

    JoelAtMoodkie

    Joined:
    Oct 18, 2009
    Posts:
    914
    Hi there,

    The API is documented here, which will give you the correct usage of the methods.

    To clarify, you need to explicitly state what type you are loading. Also the second parameter is meant to be a filename and is optional (it will use the default filename if you don't specify the parameter). If you set it to a blank string, it will throw an error because you can't have a file without a name.

    Also you appear to have quotation marks around the key in your KeyExists call, when they shouldn't be there.

    Your Load call should be:

    if (ES3.KeyExists (playerPrefsName))
    lockState = ES3.Load<bool>(playerPrefsName);


    All the best,
    Joel
     
    Last edited: Jul 3, 2017
    ProdBySamson likes this.
  7. ProdBySamson

    ProdBySamson

    Joined:
    Oct 22, 2015
    Posts:
    15
    Forgive me for what might be obvious... I am new to c# and easy save
    Thank you!!
     
  8. nathanjams

    nathanjams

    Joined:
    Jul 27, 2016
    Posts:
    304
    Hi @joeltebbett

    Just got your asset and I'm a little lost at the moment for getting it set up and was hoping you could point me in the right direction for getting started.

    I watched series "EasySave - Save System Tutorial #1 - Setup & Basic Saving / Loading - Unity 5 - C#" and have added all of the integration materials from Devdog (for Inventory Pro and Quest System Pro). I'm missing a LoadSave file for my GameManager but I can't figure out what this is supposed to be. I have an idea from teh video series but I'm still not sure what to do.

    The link on the first page of this thread for getting started with ES2 doesn't work and I can't find anything on the Mookie site for getting started. There is something for ES3, but I find even that a little vague.

    Please forgive my ignorance and if there is a link I missed please just give me that. I'm happy to figure it out on my own,. I'm just a little confused at the moment.

    Sincerely,
    Nathan
     
  9. JoelAtMoodkie

    JoelAtMoodkie

    Joined:
    Oct 18, 2009
    Posts:
    914
  10. Gatskop_Software

    Gatskop_Software

    Joined:
    Sep 21, 2014
    Posts:
    86
    How can I load a sprite from the database with playmaker ?
     
  11. Gatskop_Software

    Gatskop_Software

    Joined:
    Sep 21, 2014
    Posts:
    86
    Nevermind got it
     
    JoelAtMoodkie likes this.
  12. ProdBySamson

    ProdBySamson

    Joined:
    Oct 22, 2015
    Posts:
    15
    Hi
    I keep getting this error:

    FileNotFoundException: File "/Users/sam/Library/Application Support/DD/DD/SaveData.es3" could not be found.
    ES3.Load[Int32] (System.String key, .ES3Settings settings) (at /Users/Joel/Library/Mobile Documents/com~apple~CloudDocs/Projects/Easy Save 3/ES3 MonoDevelop/ES3/ES3.cs:243)
    ES3.Load[Int32] (System.String key) (at /Users/Joel/Library/Mobile Documents/com~apple~CloudDocs/Projects/Easy Save 3/ES3 MonoDevelop/ES3/ES3.cs:215)
    Coin.Update () (at Assets/_Scripts/Coin.cs:30)

    would be grateful for any help, Thank you
     
  13. JoelAtMoodkie

    JoelAtMoodkie

    Joined:
    Oct 18, 2009
    Posts:
    914
    Hi there,

    This error occurs because the file you're trying to load from doesn't exist. If you're unsure as to whether a file will exist, either use ES3.FileExists before loading, or provide the ES3.Load method with the defaultValue parameter.

    All the best,
    Joel
     
  14. ProdBySamson

    ProdBySamson

    Joined:
    Oct 22, 2015
    Posts:
    15
    Thank you for your quick response as alway Joel
     
    JoelAtMoodkie likes this.
  15. Thermos

    Thermos

    Joined:
    Feb 23, 2015
    Posts:
    148
    Hi,
    I have troubles while upgrading, seems all custom types are gone. Are there any files that I should not toggle on when importing?

    I also notice that ES2.CacheFile(string _identifier) functions is not documented. What does it do exactly? Are there any examples? Thanks.
     
    ProdBySamson likes this.
  16. JoelAtMoodkie

    JoelAtMoodkie

    Joined:
    Oct 18, 2009
    Posts:
    914
    Hi there,

    Sometimes when importing the type list is overwritten. However, you can regenerate this by going to Assets > Easy Save 2 > Manage Types > Refresh ES2Init.

    With regards to ES2.CacheFile, this is included for legacy reasons but is no longer supported and should not be used. Instead, an ES2Writer/Reader should be used to cache data. Easy Save 3 also allows caching of files using the ES3File class.

    All the best,
    Joel
     
  17. Thermos

    Thermos

    Joined:
    Feb 23, 2015
    Posts:
    148
    Wow, such a fast reply.
    Thanks, I can now modify my code for a better performance.
     
  18. ksam2

    ksam2

    Joined:
    Apr 28, 2012
    Posts:
    1,079
    Why Easy Save create too many folders and file? If I'm going to remove this asset from my project I can't track all them later.

    What is that link.xml file on the assets root folder? Isn't that possible to merge files and folders placed in the plugin folder into one folder?
     
  19. JoelAtMoodkie

    JoelAtMoodkie

    Joined:
    Oct 18, 2009
    Posts:
    914
    Hi there,

    Unfortunately the folder structure we currently have is required by Unity. For example, Unity requires that we keep our DLLs in Assets/Plugins folder (and sub-folders of). But we must also keep certain scripts out of the Assets/Plugins folder to ensure that they are not compiled in the first-pass.

    The link.xml file is required by Unity for builds targeting AOT platforms (such as iOS and IL2CPP platforms), and prevents Unity from stripping certain classes.

    All the best,
    Joel
     
  20. neshius108

    neshius108

    Joined:
    Nov 19, 2015
    Posts:
    110
    Hello joe,
    First of all, awesome job on the tool! It looks great and it is very simple.
    I haven't implemented the save function on my project yet and I would like to get your opinion: I noticed that you can either manually save using normal coding or use the auto-save function. This is because, I believe, it would make little sense to use auto-save AND manual save (if I got down to create a save/load routine for some components, I might as well finish it up for the rest).

    So, the question is: would you go ahead and use only the auto-save tool in one of your projects or is it not ready/stable yet for a full-use? I wouldn't want to use it and then, half-way through development, realize that I actually should have manually saved everything. I like the simplicity of it and the visual diagram makes it fun to do such a tedious job.

    Also, I find the auto-save function to be really interesting for being able to save the state of certain prefabs/game objects. The only problem that I currently saw is this:



    As you can see, I cannot Enable Auto Save for Prefab(s). How can I enable it? If I enabled that, would ES be able to save the game object of my player with all its attached prefab (the player starts without any attached prefab and, during the game, it gains new ones)? Currently it loses all the new children.

    And finally, I tried using Easy Save 3 on OSX but every few seconds Unity freezes for a moment making it impossible to use. How can I fix that?
     
  21. JoelAtMoodkie

    JoelAtMoodkie

    Joined:
    Oct 18, 2009
    Posts:
    914
    Hi there, and thanks for the praise!

    As it's still in beta, if you decided to use it in a release project I would ensure you test it well beforehand. However, I would also suggest that if you can code it, do code it. It's much more flexible, and easier to debug errors.

    Have you selected a prefab in the Project pane (not the Hierarchy pane)?

    It would indeed be able to do this. Easy Save 3 can also do this quite easily in code.

    This was a bug on a previous version which has since been fixed, so it looks like you need to update Easy Save 3, or the update wasn't applied properly.

    To do a clean update:
    • Delete the Assets/Easy Save 3/ folder, and the Assets/Plugins/Easy Save 3/ folder if it exists.
    • Update Easy Save from the Asset Store.
    • Go to Assets > Install or Update Easy Save 3 Beta
    All the best,
    Joel
     
  22. neshius108

    neshius108

    Joined:
    Nov 19, 2015
    Posts:
    110
    Sweet, thanks! Yeah, it was not updated.

    I shall proceed with coding then! :D
     
  23. neshius108

    neshius108

    Joined:
    Nov 19, 2015
    Posts:
    110
    Heya Joel,

    I tried again and indeed the new version works smoothly :)
    I went ahead and tried to save my prefab character with another prefab as child, here is what I got when I tried to load:

    Code (CSharp):
    1. FormatException: Invalid length.
    2. System.Convert.FromBase64String (System.String s) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Convert.cs:146)
    3. ES3Internal.ES3JSONReader.Read_byteArray () (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3JSONReader.cs:581)
    4. ES3Types.ES3Type_byteArray.Read[Byte[]] (.ES3Reader reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/Primitive Types/ES3Type_byteArray.cs:23)
    5. ES3Reader.Read[Byte[]] (ES3Types.ES3Type type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:239)
    6. ES3Types.ES3Type_Texture2D.ReadUnityObject[Texture2D] (.ES3Reader reader, System.Object obj) (at Assets/Plugins/Easy Save 3/Scripts/Types/Unity Types/ES3Type_Texture2D.cs:44)
    7. ES3Types.ES3UnityObjectType.ReadObject[Texture2D] (.ES3Reader reader, System.Object obj) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3UnityObjectType.cs:45)
    8. ES3Types.ES3Type_Texture2D.ReadUnityObject[Texture2D] (.ES3Reader reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/Unity Types/ES3Type_Texture2D.cs:56)
    9. ES3Types.ES3UnityObjectType.ReadObject[Texture2D] (.ES3Reader reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3UnityObjectType.cs:52)
    10. ES3Types.ES3ObjectType.Read[Texture2D] (.ES3Reader reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3ObjectType.cs:40)
    11. ES3Reader.ReadObject[Texture2D] (ES3Types.ES3Type type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:215)
    12. ES3Reader.Read[Texture2D] (ES3Types.ES3Type type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:245)
    13. ES3Types.ES3Type_Sprite.ReadUnityObject[Sprite] (.ES3Reader reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/Unity Types/ES3Type_Sprite.cs:43)
    14. ES3Types.ES3UnityObjectType.ReadObject[Sprite] (.ES3Reader reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3UnityObjectType.cs:52)
    15. ES3Types.ES3ObjectType.Read[Sprite] (.ES3Reader reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3ObjectType.cs:40)
    16. ES3Reader.ReadObject[Sprite] (ES3Types.ES3Type type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:215)
    17. ES3Reader.Read[Sprite] (ES3Types.ES3Type type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:245)
    18. ES3Types.ES3Type_SpriteRenderer.ReadComponent[Object] (.ES3Reader reader, System.Object obj) (at Assets/Plugins/Easy Save 3/Scripts/Types/Unity Types/ES3Type_SpriteRenderer.cs:49)
    19. ES3Types.ES3ComponentType.ReadObject[Object] (.ES3Reader reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3ComponentType.cs:86)
    20. ES3Types.ES3ObjectType.Read[Object] (.ES3Reader reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3ObjectType.cs:40)
    21. ES3Types.ES3ObjectType.Read[Object] (.ES3Reader reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3ObjectType.cs:34)
    22. ES3Reader.ReadObject[Object] (ES3Types.ES3Type type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:215)
    23. ES3Reader.Read[Object] (ES3Types.ES3Type type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:245)
    24. ES3Types.ES3ArrayType.Read (.ES3Reader reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/Collection Types/ES3ArrayType.cs:57)
    25. ES3Reader.Read[Component[]] (ES3Types.ES3Type type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:241)
    26. ES3Reader.Read[Component[]] () (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:98)
    27. ES3Types.ES3Type_GameObject.ReadInto[Object] (.ES3Reader reader, System.Object obj) (at Assets/Plugins/Easy Save 3/Scripts/Types/Unity Types/ES3Type_GameObject.cs:129)
    28. ES3Types.ES3Type_GameObject.Read[Object] (.ES3Reader reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/Unity Types/ES3Type_GameObject.cs:99)
    29. ES3Reader.ReadObject[Object] (ES3Types.ES3Type type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:215)
    30. ES3Reader.Read[Object] (ES3Types.ES3Type type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:245)
    31. ES3Types.ES3ArrayType.Read (.ES3Reader reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/Collection Types/ES3ArrayType.cs:57)
    32. ES3Reader.Read[GameObject[]] (ES3Types.ES3Type type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:241)
    33. ES3Reader.Read[GameObject[]] () (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:98)
    34. ES3Types.ES3Type_GameObject.ReadInto[GameObject] (.ES3Reader reader, System.Object obj) (at Assets/Plugins/Easy Save 3/Scripts/Types/Unity Types/ES3Type_GameObject.cs:126)
    35. ES3Reader.ReadObject[GameObject] (System.Object obj, ES3Types.ES3Type type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:205)
    36. ES3Reader.ReadInto[GameObject] (System.Object obj, ES3Types.ES3Type type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:259)
    37. ES3File.LoadInto[GameObject] (System.String key, UnityEngine.GameObject obj) (at Assets/Plugins/Easy Save 3/Scripts/ES3File.cs:190)
    38. SaveManager.Load () (at Assets/Scripts/System/Save/SaveManager.cs:33)
    39. SaveManagerEditor.OnInspectorGUI () (at Assets/Editor/SaveManagerEditor.cs:16)
    40. UnityEditor.InspectorWindow.DrawEditor (UnityEditor.Editor editor, Int32 editorIndex, Boolean rebuildOptimizedGUIBlock, System.Boolean& showImportedObjectBarNext, UnityEngine.Rect& importedObjectBarRect) (at /Users/builduser/buildslave/unity/build/Editor/Mono/Inspector/InspectorWindow.cs:1229)
    41. UnityEditor.DockArea:OnGUI()
    To give you more info:

    My character is a small prefab with several initially empty gameobjects. Whenever the player touches another prefab (say a sword), I add it as a child to the related gameobject and enable its scripts.
    The goal would be to be able to save and load a player and whatever he picked up. Is that currently possible?

    Here is what I am doing:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class SaveManager : MonoBehaviour
    6. {
    7.     public string SaveFileName = "save-01.kul";
    8.     public ES3File CurrentSaveFile;
    9.     public GameObject Player;
    10.  
    11.     public void Start()
    12.     {
    13.         // Create a new ES3File. This automatically loads
    14.         // the data from myFile.es3 into the ES3File.
    15.         CurrentSaveFile = new ES3File(SaveFileName);
    16.     }
    17.  
    18.     public void SaveToFile()
    19.     {
    20.         // Commit our ES3File to storage when the application quits.
    21.         CurrentSaveFile.Sync();
    22.     }
    23.  
    24.     // We can call this method whenever we want to save.
    25.     public void Save()
    26.     {
    27.         CurrentSaveFile.Save<GameObject> (Player.name, Player);
    28.     }
    29.  
    30.     // We can call this method whenever we want to load.
    31.     public void Load()
    32.     {
    33.         CurrentSaveFile.LoadInto<GameObject> (Player.name, Player);
    34.     }
    35. }
    36.  
    In addition:

    1. I tried with selecting only the character's prefab and adding the 'ES3 Prefab (Script)' (as you told me earlier):

    -> No error but only the character main prefab got loaded, the collected item did not move

    2. I tried with selecting the item prefab as well and I got:

    -> Huge error (see above) and nothing loaded

    Thanks in advance!

    P.S. Is the way I am doing (splitting Save and SaveToFile) the most efficient way for handling saves? I am still unsure on whether I want to split them (i.e. checkpoint = caching, save = save to file) or not. What do you suggest?

    /Nesh
     
    Last edited: Aug 7, 2017
  24. JoelAtMoodkie

    JoelAtMoodkie

    Joined:
    Oct 18, 2009
    Posts:
    914
    Hi Nesh,

    Would you be able to PM me a link to a basic test project which replicates this error, and some instructions to replicate it?

    What you've described should be possible, but I won't be able to track down your bug without being able to replicate it directly at my end.

    Also just incase there's corrupt save data, you might want to try deleting any existing save data by going to Window > Easy Save 3 > Tools > Clear Persistent Data Path.

    One other thing you might want to try is using ES3File.Load rather than ES3File.LoadInto. GameObjects are saved by reference, so it's not necessary to use LoadInto for them.

    All the best,
    Joel
     
  25. neshius108

    neshius108

    Joined:
    Nov 19, 2015
    Posts:
    110
    Ok, I will try cleaning up the save data and switch to Load. Let's see :)

    Update: Still not working, I will look into it a bit more and then make a test scene for you.

    Update2: I decided to just handle each part of the prefab manually, it would have been magic if the tool supported it out of the box but nevertheless I am very satisfied :)

    Btw, is it possible to use the File Editor from ES2 to visualize data saved with ES3? Also, does changing the buffer size make any major difference (performance, amount of data storable, etc.)?

    Also, I noticed that a lot of 'ES3 Temporary GameObject' are created, how can I clear them up?
     
    Last edited: Aug 8, 2017
  26. JoelAtMoodkie

    JoelAtMoodkie

    Joined:
    Oct 18, 2009
    Posts:
    914
    Apologies for the late reply, the Unity forums do not notify me when you've edited your post, so I had no idea you had added questions to your post.

    Easy Save 3 uses an entirely different format so this isn't possible. However, because Easy Save 3 uses JSON, you can edit it directly in a text editor if necessary. We hope to add a File Editor for Easy Save 3 in a future update.

    Reducing the buffer size will reduce RAM usage, but at the cost of performance. Generally it's advised to keep it at it's default value.

    ES3 Temporary GameObjects are created when loading a Component for which no reference exists, so we have to create a Component. Because a GameObject cannot exist without a Component, we also have to create a GameObject to store the Component.

    If you're loading Components directly, you can use ES3.LoadInto rather than ES3.Load, which allows you to choose a Component to load the data into (rather than creating a new Component).

    All the best,
    Joel
     
  27. neshius108

    neshius108

    Joined:
    Nov 19, 2015
    Posts:
    110
    Thanks for the reply Joel,

    Ok, cool!

    Here is what I am currently saving/loading:

    - Transform
    - Vector3
    - string

    So, why are those being created?
     
  28. JoelAtMoodkie

    JoelAtMoodkie

    Joined:
    Oct 18, 2009
    Posts:
    914
    Hi there,

    It will be the Transform component you're loading which is creating the objects.

    You will need to create your prefab, and then use ES3.LoadInto to load your saved Transform data directly into that prefab's Transform component. i.e.

    Code (CSharp):
    1. var instance.= (GameObject)Instantiate(prefab);
    2. ES3.LoadInto<Transform>("prefabTransform", instance.transform);
    All the best,
    Joel
     
  29. neshius108

    neshius108

    Joined:
    Nov 19, 2015
    Posts:
    110
    That fixed it! Thanks :)
     
  30. zephyr7

    zephyr7

    Joined:
    Oct 12, 2013
    Posts:
    16
    Hey,
    are there any plans to add a "sort entries by alphabet" option to the save file editor, and a filter to quickly find the entry you're looking for? That would be quite useful.
     
  31. JoelAtMoodkie

    JoelAtMoodkie

    Joined:
    Oct 18, 2009
    Posts:
    914
    Hi there,

    This is the first time this has been requested so I've added a feature request users can vote on here: http://moodkie.com/forum/posting.php?mode=post&f=14

    We're currently working on the File Editor for Easy Save 3, so even if there's minimal demand for it, it will likely be included with Easy Save 3's File Editor.

    All the best,
    Joel
     
  32. zephyr7

    zephyr7

    Joined:
    Oct 12, 2013
    Posts:
    16
    Cool, thank you. Looking forward to the updates V3 brings.
     
  33. Gladyon

    Gladyon

    Joined:
    Sep 10, 2015
    Posts:
    389
    I am trying the v3, and for some unknown reasons, the 'Easy Save 3 Manager' keeps creating itself despite that I unchecked the 'Auto add' feature in the 'Easy Save' settings window.

    I had to uncheck it in the 'ES3 Default Settings' prefab to remove it.
    I don't know if it's the standard behaviour or if I've missed something, but it's a bit confusing.
     
  34. JoelAtMoodkie

    JoelAtMoodkie

    Joined:
    Oct 18, 2009
    Posts:
    914
    Hi there,

    This is a bug and is fixed in the next update, which we hope to submit to Unity for approval by the end of the week.

    All the best,
    Joel
     
  35. Gladyon

    Gladyon

    Joined:
    Sep 10, 2015
    Posts:
    389
    OK, good.
    And good reactivity by the way, it's quite impressive!
     
  36. Gladyon

    Gladyon

    Joined:
    Sep 10, 2015
    Posts:
    389
    When I try to use 'ES3Reader.Create()' from another thread than the main thread, I get an error message relative to 'Application.dataPath'.
    As 'Application.dataPath' and 'Application.persistentDataPath' do not change at runtime, it is possible to save their value at the beginning, using the main thread, and then use the saved value from any other thread.

    Also, is there a way to read a configuration file while updating it at the same time?
    I mean, when I read the configuration file, I provide a default value, and if the key isn't there, then I'd like it to be created automatically using the default value I provided.
    That would make it very easy to keep a configuration file up-to-date.

    And to finish with, the JSON file create, while perfectly valid, is on one line only.
    It isn't very easy to read it, is it possible to add carriage returns and tabulations?
     
  37. JoelAtMoodkie

    JoelAtMoodkie

    Joined:
    Oct 18, 2009
    Posts:
    914
    Hi there,

    We don't officially support using Easy Save from a separate thread as most of Unity's API is not thread safe (though many users are using Easy Save concurrently without issue, just so long as Easy Save is only used in one thread at a time). Because Easy Save methods can accept an absolute path, you should be able to put Application.persistentDataPath/dataPath into a variable and use that as the beginning of the path supplied to the filePath parameter.

    You could make your own method to manage this. Something along the lines of:

    Code (CSharp):
    1. public static T LoadOrCreate<T>(string key, T value, T defaultValue)
    2. {
    3.     T loadedData = ES3.Load<T>(key, default(T));
    4.     if(EqualityComparer<T>.Default.Equals(loadedData, default(T)))
    5.     {
    6.         ES3.Save<T>(key, defaultValue);
    7.         return defaultValue;
    8.     }
    9.     return loadedData;
    10. }
    As we're only testing core functionality, non-essential functionality has not yet been added to the Easy Save 3 beta. However, you can vote that have support added for it earlier in the feature request I've created.

    All the best,
    Joel
     
  38. Gladyon

    Gladyon

    Joined:
    Sep 10, 2015
    Posts:
    389
    That's what I did, I just indicated it so that it can be included in ES3 in the future.
    And I confirm that using ES3 in another thread works perfectly fine, provided of course that it's the only one who access the file, and I have tried it only in one thread for now.


    Thanks for the tips, I'll do that.

    Just looking at that piece of code, I noticed that in ES3 you're using the type 'Object' instead of 'T' for the value, which generates some boxing/unboxing.
    Is it because of some technical problem or just because you do not have optimized yet?


    OK, that's normal to do things in good order.
    First core features, then small features, then some QOL and optimization, that makes sense.


    Thanks again for your fast and precise answers.
     
  39. JoelAtMoodkie

    JoelAtMoodkie

    Joined:
    Oct 18, 2009
    Posts:
    914
    Boxing is inevitable because it's not possible to cast T without first boxing it into an object, and this needs to happen for us to be able to access it's fields to serialise them. However, the actual cost of boxing and unboxing is negligible, especially in the context of a serialiser.

    We choose to get this out of the way early because providing an object provides us with some flexibility as early on as possible, and might allow us to do some really interesting things in the future. If we find that people are regularly providing the wrong generic type for the type of data they are saving, we might make the parameter generic so that an error is thrown at compile time rather than runtime. We'll cross this bridge when we come to it however :)

    All the best,
    Joel
     
  40. Gladyon

    Gladyon

    Joined:
    Sep 10, 2015
    Posts:
    389
    From a performance point of view, I presume it is better to use 'Reader = ES3Reader.Create()' and then several 'Reader.Read<T>()' in a row.
    I also presume that it's better to use 'ES3Reader.Create()' followed by calls to 'Read<T>(Name, Default)' than directly 'ES3.Load<T>(Name, Default)'.

    I have a few questions:
    - are my suppositions about performance are true (I know that ES3 is still un-optimized, I'm asking if it will be true when ES3 will be optimized)
    - it is indicated in the documentation of ES2 that after using a reader of a writer we must call 'Dispose()', is it still the case for ES3?
    - is it possible to have a 'default' value when calling 'Reader.Read<T>()', so that we can read sequentially with default value if necessary?
     
  41. JoelAtMoodkie

    JoelAtMoodkie

    Joined:
    Oct 18, 2009
    Posts:
    914
    Just to clarify, ES3Reader is only used internally so I can't provide support for it. However, ES3File essentially has the same performance benefits and is significantly more maintainable.

    ES3Reader is much more complex than ES2Reader, which is why we've not documented it and have opted to provide the ES3File class instead. ES3Reader may also be subject to change, so there's no guarantee your current code will work with later versions.

    All the best,
    Joel
     
  42. Gladyon

    Gladyon

    Joined:
    Sep 10, 2015
    Posts:
    389
    Thanks!
    You're right, ES3File is way better to use.
    It works very well and the code is a lot cleaner.
     
  43. JoelAtMoodkie

    JoelAtMoodkie

    Joined:
    Oct 18, 2009
    Posts:
    914
    Glad you like it. We will be adding more features to ES3File to make it even more flexible, so if you run into any limitations, let me know.
     
  44. Gladyon

    Gladyon

    Joined:
    Sep 10, 2015
    Posts:
    389
    You shouldn't say that ;)

    It would be good to have the possibility to automatically create the file if it doesn't exists, and even replace the existing one also (even if it would be less useful).

    Also, it would be great to add the 'LoadOrCreate' snippet you provided, it works well as an extension, but as you already have it, why not include it?


    These are quality of life improvements, I do not have looked into performances yet, but there's no use until it's well out of beta. And the initial tests indicates that it's OK for my current use (configuration file).
    I don't know if it's in the scope of ES3 or not, but it may be useful at some point to have the possibility to serialize fast, and with some compression.
    I say that because it could be used to send data over the network, which would allow people to have the same serializer to save data and to exchange data in multiplayer.
    But again, I don't know if it's in the scope of ES3, and it's quite a lot more work than the 2 previous small quality of life things.
     
  45. JoelAtMoodkie

    JoelAtMoodkie

    Joined:
    Oct 18, 2009
    Posts:
    914
    Thanks for the feedback.

    As you're the first person to suggest that feature in any version of Easy Save, for the time being it'll be better served as an unofficial extension (though I've added a feature request for it here). Adding infrequently used methods means we have more to document, test and maintain, and also bloats the API making it harder for people to find more commonly used methods, but if there's demand for it we'll add it :)

    We intend on eventually adding support for binary formatting which is much more compact than JSON, and should also allow us to add other optimisations (such as prefixing offsets to pieces of data, which isn't practical with the JSON format). We've had a few requests for actively compressing the data (see this feature request which I've moved to the Easy Save 3 forum), but we've not yet had enough interest to make it worth our while to implement it. Because Easy Save 3's flexibility means that it's format is less compact than Easy Save 2, there might be more requests for it.

    All the best,
    Joel
     
  46. Gladyon

    Gladyon

    Joined:
    Sep 10, 2015
    Posts:
    389
    Another little idea, now that the format is human-readable, it would be good to be able to add a comment (optional of course) to a variable.
    That way, the people modifying manually the file would know the meaning (and the possible values in case of an enum) of the different variables.
     
  47. JoelAtMoodkie

    JoelAtMoodkie

    Joined:
    Oct 18, 2009
    Posts:
    914
    Unfortunately the JSON format doesn't support comments. However, wherever it's necessary for users to modify files, I always suggest creating an Editor to do this, as in my experience it's fairly common for users to incorrectly modify the format (especially where JSON is concerned).

    All the best,
    Joel
     
  48. Gladyon

    Gladyon

    Joined:
    Sep 10, 2015
    Posts:
    389
    It is possible to automatically add a '__comment', as you did for the '__type':
    Code (CSharp):
    1. {
    2.     "FullLogs": {
    3.         "__type": "System.Boolean,mscorlib",
    4.         "__comment": "'true' to record all logs, 'false' to record only the important logs (faster)",
    5.         "value": false
    6.     },
    7.     "LoadAllMods": {
    8.         "__type": "System.Boolean,mscorlib",
    9.         "__comment": "'true' to load all mods (alphanumerical order), 'false' to use the user-specific list of mods (including its order)",
    10.         "value": true
    11.     }
    12. }
    Of course, it must be optional, but I think it may be useful for a lot of people.
     
  49. JoelAtMoodkie

    JoelAtMoodkie

    Joined:
    Oct 18, 2009
    Posts:
    914
    We could indeed do it that way. I've added a feature request for this, and if there's indeed demand for it we'll add it.

    All the best,
    Joel
     
  50. stevenatunity

    stevenatunity

    Joined:
    Apr 17, 2015
    Posts:
    114
    @joeltebbett Hi Joel, it's stupid question time :) Can you save arrays without tags? Thanks, Steven