TaleSpire Dev Log 504
Evening folks!
A week and a half back, I started splitting my time between VFX and the performance of the new live search system.
The search itself is decently quick, comfortably fuzzy-matching thousands of assets a millisecond[0]. What sucked was that once it was wired up to the UI, the search felt bad. You might have even seen the stuttering in the last bi-monthly banter.
This was a release-blocker. Live search is no good if it's not live. I broke out the profiler and got to work.
It took but a moment to see the issue. Unity's UI system (UGUI) is slow [1].
We were seeing enabling/disabling UI elements taking multiple milliseconds PER ELEMENT. It wouldnt be so bad if our code was being unreasonable, but it wasn't. We already employed many of the standard pooling tricks you use in Unity to avoid creating new objects, and we steered clear of the auto-layout components as they are well known to be slow[2]. But still, it was slow.
The fact that pooling was slow was counterintuitive, but the measurements clearly showed just how slow UI reparenting was (or rather, the side effects reparenting caused[3]). There was nothing left to do but ugly tricks. For example, believe it or not, it was better to just move the objects waaay off-screen rather than disable them. I whipped up a simple factory to handle that without reparenting.
Then it was on to refactoring to get rid of defensive code. Unless you are careful, code can accrue execution paths that do things just to ensure the system is in the desired state before doing the desired task. This can result in unnecessary work, as was the case here. I slowly massaged the code until no path did more than it needed to.
Next up, allocations. I tracked down a large number of memory allocations to places where we were passing methods as callbacks to the ui elements. Reasonable at first glance, but each pass of an instance method allocates memory. Those added up fast, and even if allocating memory was free, garbage collection is not. Switching to using interfaces on existing objects helped a lot.
UI Text is stupifyingly slow. All the little tags that show tile dimensions caused dozens of milliseconds of work. To solve this, I made a grid of all 64 possible dimension-tags, rendered the result to a texture, and used the texture as a spritesheet. This too worked well.
As work progressed, more opportunities presented themselves. Newly redundant code could be trimmed, which in turn opened up more optimization opportunities. We didn't have time for all of them, so there are plenty more wins for another day.
I also fixed the horrible lag that happens when you first go to the "community" section of the asset library. The fix makes that transition instant and saves a bunch of memory to boot!
With these changes, and many more, I cut the stalls from 40-70 milliseconds to around 4. Still not good, but at least it felt nice when typing.
The problem is that we are running into limits of what we can get out of UGUI without basically writing our own system. And so that is what we will do! But not yet.
We are going to ship search first. And soon. It will be released in a few stages:
1. First, we will release the search system in TaleSpire. It will give you fast tag search, which you had before, and also name search, which you did not. The search is live, so you see results as you type. The release also brings improved UX around search (like multiple suggestions), not just in the asset browser but also in the community browser.
2. Then we shall do a final pass on tags and make a release where all creatures in-game have the new tags.
3. And at last, we will ship the new build of TaleWeaverLite, which will allow all modders to add tags to their own creations.
And with that, it will be out! Keep an eye out for a tagging related dev-log after the main releases. We hope to help tag as much of the asset ecosystem as we can.
Tomorrow I'll be merging code to prepare for step 1. It's very exciting. With that merged, I expect a day or two of bug fixing and play-testing. We'll keep ya posted.
Until next time,
Peace.
[0] There is still plenty of room for improvement here. I wrote more or less the first thing I felt would perform well. With a bit more digging, I know we'll find more exploitable parts of the problem.
[1] We are aware of Unity's other ui system (uielements/uitookit). It has its own issues and, like Ugui, it doesn't have a great story for animations. (Also, I loathe the XML/CSS approach. It's purely a personal preference. But ew)
[2] For more details, see here: https://unity.com/how-to/unity-ui-optimization-tips
[3] Reparenting isn't the fastest thing at the best of times, but still, this was bizarre.

Guest
UserGuest
User