Yonuo 2 years ago updated 2 years ago 6

Well, after suffering it once again and wasting enough hours, I decided to hunt this bastard, and I think I have succeeded.

I can pass the project if necessary, but it is empty and is extremely easy to provoke it.
unity version 2019.2.3f1 bolt
bolt version 1.4.8f2

It can be caused in several ways and all are because of the creation of superunits macros.
I started doing very convoluted tests trying to recreate my last time, to finally realize that the content is not important.
The bug occurs in stategraphs and flowgrahs, embed or macro.

In an empty project and after installing bolt:
-create a state macro, create a start node (if it isn't already) and add a superunit.
-convert the superunit to macro
-make a copy of the STATE MACRO and you will see how the node where the superunit macro was will appear empty.
* Alternatively you can copy and paste this superunit macro into another state of the state graph and press undo. then what will happen is that the two states will be erased (and if the macro was in 20 then the 20 ...).

- Basically this can be repeated with flow macros and also with embed, but in the case of embed, instead of making a copy of the macro, it is to make a copy of the object that contains the flow or the state macro.

From here I draw the conclusion that the undo or the copy of the state macros or flow macros or the objects that contain it are the trigger, but the cause is related to the creation or manipulation of superunit macros.

I think I have read that they are dedicated to bugs one day a week, but also that this is their priority, if someone has a way to get it to them I think it would be interesting for everyone.

maybe in discord?

I hope this helps.


Bolt Version:
Unity Version:
PC, Android
Scripting Backend:
.NET Version (API Compatibility Level):
.NET Standard 2.0
Satisfaction mark by Yonuo 2 years ago
Working on Fix

Hi Yonuo,

Thank you so much for investigating this issue.

I'm trying your reproduction steps right now and I do see that the duplicated state macro becomes empty after converting. Very odd! I'm not sure if/how this is related to undo at all (because I didn't have to even press undo to get it to occur), but it's definitely a bug and I'll look into it.

My English does not help to make it clear. And maybe it has been a bit confusing to mix the issue of copying the state or flow macro, but it is something I discovered while trying to provoke the undo bug, and I came to the conclusion that at the same point that the undo bug is caused, the copy bug can be caused too, so it seemed to me that they are caused by the same reason.

This is why I say in the first comment, that I think it is not a undo bug. I think is a failure of the management of the superunit macros, the undo or the copy are the triggers.

*Quick note: if you save and restart unity before use undo, you can continue without any problems.

reproducing UNDO BUG:

If after creating the superunit and converting it to macro, you use undo, the graph will be deleted.

Also, if you have copied that macro in other states of a state graph before use undo, all of them will also be deleted.

Thanks for the additional details! I still can't get the graph to disappear on my end, but I've found at least 3 core bugs related to that set of operations. I don't want to confirm anything yet but it could very well be related to the symptoms of the undo bug.

Fixed (Unreleased)

Hi Yonuo,

Thank you so much for the report. I believe I finally fixed the issue thanks to your reproduction steps!

Here's what was happening:

Bolt uses a "serialization dependency" system in the background to make sure that macros and nester elements (nester elements = super unit, super state, flow state, state unit) get loaded in the right order. For example, we need to make sure that a macro gets loaded before the super units that reference it get loaded.

In order for this to work, macros have to let the system know when they become "available", that is, deserialized/loaded. They do this in Unity's ISerializationCallbackReceiver.OnAfterDeserialize.

The super units and the graphs that include them then only get loaded when their macro dependencies are available. If they're not, they just wait silently -- nothing happens, no error, no warning, no log entry. Hence why no one ever had an error to report with this bug! Because normally, this all gets sorted out before even the first frame.

But when creating new macros, OnAfterDeserialize doesn't get called immediately, because the macro didn't have to save/load from disk. Therefore, the serialization system doesn't get notified that this macro dependency is available. And if you create any other graph that depends on that freshly created macro, then those will eternally wait for the macro before loading (which happens on undo), even though it's actually perfectly ready.

This is why entering/exiting play mode or restarting Unity before doing the undo operation fixed it: because it forced the macro to save/load from disk, therefore triggering OnAfterDeserialize.

The fix is extremely simple: in Macro.OnEnable, I also make it notify the serialization system that it's available. Therefore, new macros don't create stuck graphs, even if they don't get reloaded.

It's literally a 3 line fix:

protected virtual void OnEnable()

I'll be uploading Bolt 1.4.9 in the next few hours to make this fix available to all.

I'd also like to offer you a complementary copy of Peek as a thank you for helping us fix this bug that's been plaguing everyone for months. Please let me know if I can send it to your account's e-mail address.

I'm really glad you finally managed to fix it. It was quite stressful.

I know it's not necessary, but I confirm that it doesn't happen anymore.

As for Peek. It is a very interesting tool. Glad to receive it! you can send it to my email whenever you want.