Page 1 of 2

Optimizing LuaWatchers.NotifyObserver() taking 450+ ms

Posted: Sat Aug 03, 2024 7:25 am
by LostTrainDude
[Unity 2021.3.38f1 - DS v2.2.46.1 - AC v1.81.4 - Articy v2]

Hi Tony,

I've been experiencing some hiccups (1-2s on my machine) while saving during our game and, looking into the Profiler with Deep Profile activated, I noticed that there are a lot of LuaWatchItem.Check() under LuaWatchers.NotifyObserver() as per the following screenshots:

Image

Image

Now:
  • I understand this is not strictly related to saves, since I do rely a lot on observing Lua variables (the majority of the logic is intertwined with our use of Articy)
  • I know that string checking is an expensive operation, especially on a scale this large.
Still, I was wondering whether there was something I could do to reduce this, without having to revolutionize the way we do things.

It currently seems not too much of a big deal when manually saving, but it is an issue during autosaves, that we would like to happen in a more "silent" way.

My guess (and I could be wrong), by looking at the profiler in Deep Profile mode, is that that anytime a Lua variable is updated, all of them are being checked via observation, and that of course, happens during saves.

For the sake of completion, I have asked a similar question on the AC's forums, as 50% of the hiccups are currently also generated by having enabled screenshots to save games.

When I write that I'm worried about opening "a can of worms" when I realized roughly the same time was taken by DS, know that I'm referring to having to radically change something in how we deal with game logic and variables, so it's not a commentary on DS itself! :)

Thanks a lot, as always!

Re: Optimizing LuaWatchers.NotifyObserver() taking 450+ ms

Posted: Sat Aug 03, 2024 1:31 pm
by Tony Li
Hi,

If you're monitoring variables, use Language.Lua.Assignment.MonitoredVariables instead of Lua watchers. They are much more efficient and should eliminate all of that lag.

Re: Optimizing LuaWatchers.NotifyObserver() taking 450+ ms

Posted: Sat Aug 03, 2024 1:47 pm
by LostTrainDude
Hi Tony, thanks for the answer!

Just to be sure I understood: I could use Language.Lua.Assignment.MonitoredVariables.Add() instead of DialogueManager.AddLuaObserver()?

I have to double check whether I can do it everywhere I currently do use AddLuaObserver() because I think in some cases I do actually need the Lua.WatchItem \ Lua.Result data. Is that covered by the object returned in the callback for MonitoredVariables.Add()?

Re: Optimizing LuaWatchers.NotifyObserver() taking 450+ ms

Posted: Sat Aug 03, 2024 8:05 pm
by Tony Li
Hi,

> Just to be sure I understood: I could use Language.Lua.Assignment.MonitoredVariables.Add() instead of DialogueManager.AddLuaObserver()?

Yes. It's much more efficient. See the code example in the link above for sample code that shows how to use it.


> I have to double check whether I can do it everywhere I currently do use AddLuaObserver() because I think in some cases I do actually need the Lua.WatchItem \ Lua.Result data. Is that covered by the object returned in the callback for MonitoredVariables.Add()?

No. In those cases, you'll need to use Lua observers. However, when you're loading or restarting a game, you could remove the Lua observers first and then add them again after loading.

Re: Optimizing LuaWatchers.NotifyObserver() taking 450+ ms

Posted: Sat Aug 03, 2024 8:26 pm
by LostTrainDude
Assuming I converted everything correctly, the difference is like night and day!

I can't believe I overlooked this*. Thanks a lot!

*EDIT: checking the Release Notes, I realized this is a relatively new feature! Phew :D

Re: Optimizing LuaWatchers.NotifyObserver() taking 450+ ms

Posted: Sat Aug 03, 2024 10:19 pm
by Tony Li
Awesome! Glad to help.

Re: Optimizing LuaWatchers.NotifyObserver() taking 450+ ms

Posted: Sun Aug 04, 2024 10:42 am
by EpicMcDude
Oh this is very interesting, I've been experiencing hangups as well when saving the game which is understandable, but is this possible with PlayMaker?

Re: Optimizing LuaWatchers.NotifyObserver() taking 450+ ms

Posted: Sun Aug 04, 2024 10:46 am
by Tony Li
Can you use the profiler to determine what's causing hangups? If you're using mostly Playmaker, then it's probably something other than Lua watchers.

Re: Optimizing LuaWatchers.NotifyObserver() taking 450+ ms

Posted: Tue Aug 13, 2024 10:01 am
by LostTrainDude
Hi Tony,

I'm updating this because it's related to my implementation of this solution.

This is unrelated to performance, and I also assume this was intended (as it would make sense), but a difference I noticed, compared to the previous implementation, is that the Language.Lua.Assignment.VariableChanged event is triggered every time the game executes a variable change, even if the value of such variable is already set to that value.

E.g.: "myBool" is currently set to true, if something in the game sets it to true again, it still triggers the event.

I'm still figuring out whether it's a big deal or not for me currently, because I should already be using checks in places to make sure some things don't get triggered multiple times, but It's more tricky in my variable changes logger (I do this for debugging purposes). There I'm not sure how to "intercept" a variable before it's updated, so that I can prevent the logger to register it multiple times, other than, maybe, checking the collection of recorded events and prevent the duplicate (but that would require me to make sure things can endure a game reset without having to lose the current testing session progress).

Was it meant to work like this? I may be wrong, but when I was using the NotifyObserver() method I don't recall this ever happening.

Thanks a lot as always!

Re: Optimizing LuaWatchers.NotifyObserver() taking 450+ ms

Posted: Tue Aug 13, 2024 11:13 am
by Tony Li
Hi,

That's a good point. Currently the event is raised every time the variable is assigned a value, even if it's the same value that it currently has. I don't think it will hurt anything to change it so it only raises the event if the value is different. I'll plan to add that to 2.2.48.