Hello there and welcome back to another instalment of the Blightmare development blog! We’re still ironing out some of the newer features in the refactored editor, but things seem to be going well. Today’s post is going to be a look at one of the problems that came up several times in a few different forms.
The problem that I’m referring to is how to make sure state is synchronized between our “immediate mode” editor code and the supporting “retained mode” Unity objects. In order to explain a bit about why this is a problem, I will explain a bit about how the structure of the new editor solves a common problem. When we run a frame of the editor, we iterate through the entire state of what is being displayed and instruct Unity to draw a representation of it. This ensures that we are always displaying the most up to date values and completely sidesteps the tricky business of cache invalidation. That’s the theory anyway, but when it comes time to actually implement this we encounter some problems.
The general problem that we have is that we don’t own all the code that we’re using, so we can’t change the way that it is designed. As an example, we will walk through the implementation for displaying a visual indicator on the grid where every item is placed. These indicators are Unity prefab instances, and as a result are relatively expensive to create and destroy. The common paradigm of create/destroy is itself not well suited to our model of visiting everything all the time. This is because in the immediate mode paradigm, we don’t care about the lifecycle that something has. In particular, when we’re just drawing item indicators, we shouldn’t need to be aware of when or how objects are created or destroyed. All we need to know is how many objects there are and where they are located. When we’re forced into using objects with explicit lifetimes that are expensive to create and destroy, then we have to keep track of which object went with which piece of state and do a lot of extra book keeping to make sure we destroy the correct one when an item is removed, or create a new one when a new item is placed.
Or do we?
In the example of the visual indicator for item location, it turns out that every indicator is the same. In this case then, we don’t need to worry about matching up pairs of items and indicators that are the same each time. Instead, we just need any old indicator for the item that we’re processing, and we place it correctly for that item. This observation then allows us to maintain a pool of indicators that we reuse every frame, only creating new ones when we need them, and either disabling or destroying extra ones depending on what we want to do. This solution generalizes rather nicely to any situation where the change in state between visual representation of different items is very cheap to modify. The technique can be simplified into: always set the values of a pooled resource.
Pooled resources can only get us so far, however. One of the crucial requirements is that setting state on the resource is a cheap operation. The editor feature that I’m working on now does not have that nice property. This feature is the decoration system. The problem with decorations is that, while they are broadly divided into two categories: images and spine animations, setting a spine animation is a rather expensive process. In involves generating a mesh and setting up a significant amount of per-instance state to drive the animation. I haven’t yet figured out how I’m going to tackle this problem, but I’m leaning towards some kind of end-of-frame synchronization step with all the bookkeeping that I mentioned at the start. I’ll have to try out a simple method first and measure the performance to make sure it’s actually a problem, but we’ve seen performance problems before with creating spine animations frequently, so it’s a concern based on real experience.
I hope that next week I’ll be able to explain what the solution is! In the mean time, thank you for stopping by and as always, please head over to our Steam page and put Blightmare on your wishlist. Our Twitter remains the best way to catch all the latest updates about the game. Have a great week!