Improving explosion performance

« back

April 18, 2018 | Originally published at https://blog.nyctef.com/post/173068665027/improving-explosion-performance

As you can probably tell from the last post, explosion performance wasn’t great- we get a noticeable hitch every time it happens.The main reason for this is we’re basically tearing down all of the generated meshes, updating the underlying map data and then recreating the level geometry from scratch. There’s obviously some improvements that can be done here.

The level geometry is currently split up into two parts: the display mesh, which just holds a forward-facing texture to show the level to the player, and the collision mesh, which faces at right-angles to the player and gives unity’s physics system something to work with. The simplest thing to look at first was to edit the display texture rather than recreating it:

Using GetPixels32/SetPixels32 feels like it should be fast and efficient (we generally like working on large blocks of data) but it actually turns out that allocating the large array is slow and calling SetPixel lots of times is much faster:

The next big area to work on is the collision mesh update. I tried a bunch of microoptimisations to improve the performance of the marching squares algorithm + the triangle/mesh creation process, but nothing ended up being significant. In the end the main benefit came from splitting the collision mesh into square chunks and then only updating mesh chunks which had been touched by the explosion circle.

I played around a bit with the format of the map data itself, going from byte arrays to C# BitArrays and eventually ending up on length 64 arrays of 64-bit long integers to describe a 64x64 map chunk. The big advantage of having each row represented by a single number is that if two consecutive rows are both 0 (or both 0xffffffff) then no edge geometry is going to be generated for those rows since they're either completely solid or completely space, and can be skipped:

After going through all these optimisations there's still a noticable bump in the frame duration for frames which have an explosion, but it's no longer anywhere near as large as it used to be (it's basically only visible in the profiler) so I'm pretty happy with it at the moment:

2026 edit: shout out to the Internet Archive for keeping a copy of the above video, which was originally stored on gfycat and then lost