Dictionary of string and serialized objects are wiped at run

Issue #430 resolved
Andreas Podgurski created an issue

Using Unity 2017.4.9f1 and starting with Odin 2.0, my dictionaries of strings and SerializedScriptableObjects are wiped. If I fill them again and hit play, they are set back to null again. This is a real bummer, as it not only breaks my app, it flushed a significant amount of data.

I don't get any reports from the serializer, enabling error logging and exception throwing. All entries can be edited without any problems, but it seems, nothing is serialized in the end. The serialization debugger shows correct values, the dictionary should be serialized by Odin. Leaving Unity and reloading the project wipes the values as well.

If the dictionary is used unitialized, the dictionary itself is null after run, if there is an initializer, the dictionary is simply empty after run. Enabling/disabling the GameObject has no effect in this case.

Both, the ScriptableObject as well as the dictionary are scanned correctly by the AOT processor, although the false behaviour is in the editor already. No need to run it on the device.

My datatypes are:

public Dictionary<string, Dashboard> EngineDashboards = new Dictionary<String, Dashboard>();

[CreateAssetMenu(fileName = "Dashboard.asset", menuName = "Editor/Dashboard", order = 960)]
public class Dashboard : SerializedScriptableObject {
    public Dictionary<EUnitSystem, Sprite> RPMBackground;
    public Sprite EngineSprite;
    public int RPMGaugeMax;
}

Comments (36)

  1. Tor Esa Vestergaard
    • changed status to open

    I'll look into this right away. This does not happen on any other dictionary types, in your experience?

  2. Tor Esa Vestergaard

    As you might have noticed, Bjarke also replied on this issue, without seeing that I had already assigned it to myself. His message was relevant, though, so here's the important part of it :)

    When did the problem start? Did you update Odin, or did you downgrade or upgrade to 2017.49f1? Or was everything a fresh import? Can you confirm whether it's only dictionaries or everything Odin serialized which resets when entering playmode? What .Net backend and API compatibility is specified in player your settings? And what's your build-target? Does changing built-target changes things? Just tried it out in 2017.4.8f1 but will download 9f1 and see if that changes soon. If you have a project which reproduces the problem that would be extremely helpful. Or any more information about what's unique about your setup.

  3. Andreas Podgurski reporter

    I encountered the problem today, after I updated to 2.0 during the week when we both inspected the other issue, which was caused by disabled objects. I discovered this within the editor, as there is a default fallback, so I can't say, if it came with the update to 2.0.3.0 or with the 2.0.4.0 version with your last hot fix. The framework is still the old one, as I sadly can't use the 4.5 framework due to a closed source dependency. Build target at the moment is Android, content of the dictionary is gone on Windows as well on MacOS, where 2017.4.11f1 runs, changing the target doesn't fix it, the data is lost everytime I hit play.

    The problem is very specific to references of SerializedScriptableObjects only. All other dictionaries seem to work fine after your fix.

    The assets are stored within Resources in an own data directory, if that can be of any help (Resources/Data).

    Sadly, I can't send you the whole project, as it is for a customer and requires a non trivial setup to be able to run within the editor at all.

  4. Andreas Podgurski reporter

    Update: I just replicated the Dashboard class and an asset in a private prototype project, running under Unity 2018.3.0b1 and got the same result. I will try to create a standalone example now. Update2: Strange, got it reproduced in my private project only once, now there and in the sample it works. An update to 2.0.5.0 made no difference for the real project on the other hand.

    Any idea how we can examine this further? Any additional loggings to enable or such?

  5. Tor Esa Vestergaard

    It seems very mysterious if you can't make a reproduction project. Is it not possible to extract a subset of your project with everything about the object intact, perhaps?

    I can at least corroborate with Bjarke that this doesn't seem to reproduce for me either, which does make this a lot trickier - without reproduction steps, there's not much we can do. As for extra logging, it's a big difficult if it already logs no errors or anything of the sort when you enable full logging of warnings and errors. As soon as anything goes even slightly wrong or not as anticipated, a warning is logged, and if no warnings are logged at all, it seems more likely that the asset's data is so corrupted that the serialization system never even manages to trigger properly in the first place.

    If you add more Odin-serialized members to the asset with the non-working dictionary, do those members work fine?

    Also, if you could send me an example of a saved asset file that contains the non-working dictionary, I can have a look at the serialized data for it, and maybe that will shed some light on matters.

  6. Andreas Podgurski reporter

    I will see what I can do - sending the asset itself won't be a problem, I can send the cs of the corresponding class as well. Maybe I can strip the project down a bit, but the problem is, my successor in the project had, let's say, a favour for singletons.

    In fact, I discovered a similar behaviour now in my personal prototype as well, but it occurs very rare and randomly there. There it is a dictionary between UI buttons and GameObjects (Panels). I'll continue to look into it.

  7. Tor Esa Vestergaard

    I've still not replicated this - any progress on figuring out what's triggering the issue?

  8. Andreas Podgurski reporter

    Sorry for the long delay, we had to shift focus due to a award submission. To be not blocked by this issue, I hardcoded the dictionary in question, which is not a problem yet, as it contains only three members yet, but it is sure to grow.

    One thing I can say for sure now is, that this is a regression. Due to an expired certificate, I had to rebuild an older version of the app. This version used a version of odin, which was incompatible with Unity 2017.4.x, so I had to upgrade Odin for this build. After this upgrade, this well tested version (Internally used for testing setup variations) showed the very same issue described above, Before, this ran flawlessly. I'll try to send you the source of the class and the associated asset file, maybe that can help. If all fails, I need to check with our customer, if it is ok to send the whole project. You should be able to spot the issue without the need to run the app at all.

    Update: I have prepared a zip with the whole project for you, representing the old version with the updated Odin version, if you are interested in hunting this down. For me, I now went for a workaround, where I created an own asset with the collection in it, as I need it at another place anyway and now I access the collection there, without the issue occuring. Please let me know, if you would like to have a look (Simple to reproduce, no need to dig deep into the project as it is visible in a specific GameObject already in the editor) and how I should send it to you. Please discard the source afterwards, as it contains data, which is considered as confidential by our customer.

  9. Tor Esa Vestergaard

    Thank you for making sure we can take a look at it! That will really help :) You can send the zip to me at tor@sirenix.net, and provide an expiring download link if you want to make sure the file isn't cached anywhere on some email server. I'll make sure to delete the whole thing once I've diagnosed and resolved the issue in question.

  10. Tor Esa Vestergaard

    Any updates on this? I never got the zip file, and would very much like to try to get to the bottom of this issue.

  11. Andreas Podgurski reporter

    Sorry, we're hard on the release preparation, but I sent you a wetransfert last night with a simple reproduction description. Hope you can find the issue, because it is very easy to reproduce, although I didn't experienced that behaviour in any other context yet.

  12. Sebastian Janus

    I have the same problem as above, Debug Serialization shows that everything is fine.

    However, I managed to have Dictionaries serialized properly on scriptable object.

    This is how it’s not working (however it should probably):

    public class SomeScriptable : SerializedScriptableObject 
    {
        public Dictionary<string,List<Sprite>> someDictionary;
    }
    

    If you fill it with any data it will become empty even in editor after pressing Play button (or reloading whole project).

    If you make your definition like this, then it is fine:

    public class SomeScriptable : SerializedScriptableObject 
    {
        [NonSerialized, OdinSerialize, ShowInInspector]
        private Dictionary<string,List<Sprite>> someDictionary;
    }
    

    Unity 2019.1.10f1 and Odin 2.0.20.

  13. Tor Esa Vestergaard

    This has been reported solved as of Odin patch 2.1.6 - if anyone is still getting it, please contact me on Discord with repro steps/debug logs, and we'll look into it. Large parts of the binary serialization have been entirely rewritten and refactored to solve read/write issues with unaligned memory addresses on Android - as a bonus, the binary format's performance should now also be significantly better!

  14. Harry

    I’m on the latest odin with unity 2019.4.11 and eveytime I press play my dictionarys become empty. It's Incredably fustrating.

  15. Ivan Dudkin

    It happens in 2020.2.1f1 version too.

    Here are the steps to reproduce it:

    1. Create SerializedScriptableObject script, add public dictionary into it
    2. Create .asset file of the script
    3. Input data in created .asset
    4. Turn field into property in SerializedScriptableObject script
    5. Now any data written into existen .asset file will be removed from it on play
    6. To fix it, delete this file and create a new one

  16. z

    same here in 2021 ! frustrating …

    i am testing in last unity version for now 2020.2.4f1

    I would not like to be in Andreas position and I hope this kind of wiping errors should be so

  17. Tor Esa Vestergaard

    I’m afraid that I cannot reproduce this issue in 2020.1, 2020.2 or 2021.1 with any of the reproduction steps given here. In every single case, data is retained fine and nothing is lost.

    I’m afraid we cannot do anything to fix this issue people are experiencing without clear, repeatable, reproducible steps that actually cause the issue to occur when performed in a fresh project. Actual example projects included with these repro steps would help even more.

  18. Ivan Dudkin

    Maybe it happens if you create scriptable object without serializing dictionary and only then serialize it

  19. Tor Esa Vestergaard

    Looking at your linked project, it seems I might have misunderstood the behaviour you were describing. It is expected behaviour that if you take a field that is serialized by Unity, and then convert it to something that can only be serialized by Odin such as a property, without doing anything to transition it between those steps, then the data will be lost. That is not a bug, but simply how things work.

  20. Tor Esa Vestergaard

    I also see that you uploaded all of Odin along with the project in a public repo - I’ll have to ask you to delete that repo or make it private, as sharing Odin files in a public repo isn’t allowed.

  21. Ivan Dudkin

    But in linked project it’s not a property and problem is - it keeps losing data even after serialization on play button

  22. Krittayot Techasombooranakit

    Hi is there any update about this issue?

    Seems like happened to me in a couple of projects.a

  23. Krittayot Techasombooranakit

    The issue can be fixed by using Dictionary instead of SerializableDictionary in the inspector
    However, Not really sure if this is a bug or by design.

  24. Tor Esa Vestergaard

    Ah, perhaps that is what people reporting the issue have been doing. We’re aware of this gotcha and are working to fix it as soon as we figure out a good way of doing so - it is after all rather counter-intuitive that the option that says SerializableDictionary is not, in fact, set up to be properly serializable… we will have to write some special case handling for it to add support for that.

  25. Former user Account Deleted

    Hi, guys.
    For me, the issue still exists with Odin 3.0.12.0 and Unity 2020.3.25f1.
    Strangely for some SerializedScriptableObject it works, for some is not. Helped only to re-create scriptable object in editor and input all data once again.

    Any ideas where the fix will land or even exist?

  26. Log in to comment