1. Layer Sort Types
There are now two ways to configure the rendering algorithm for a given layer. The first method, 'batch mode', is what I've been using all along. If you're familiar with graphics programming, you've probably employed this technique many times: minimizing the number of render state switches (and texture switches) can drastically improve performance. So, quads that are similar are grouped together and drawn as batches.
2D games often don't use depth buffers (or if they do, it usually means a sacrifice with respect to partially transparent pixels)--instead, they use the 'painters algorithm', which just means drawing things front-to-back. But batching things together can lead to undesired results. Check it out:
The player is rendered incorrectly
In this case, as it happens, the blobs are all from the same texture, so they're batched together as a single call. Then the player is drawn. But that looks wrong, since the blobs right below the player should be rendered after the player.
In fact, what we really want to do here is sort every texture to be drawn by its lowest Y-coordinate (bottom) and then draw from the top down. So, the blobs 'above' the player (i.e. on the top half of the screen) are drawn, then the player, then the blobs 'below' the player.
Here's what that looks like:
The question is, how can optimal batching and this drawing algorithm be achieved? The first picture is done in 2 batches, the second picture in 3 batches. And the answer is that I don't know and I don't really care right now--the majority of the sprites in the game aren't going to need this slightly slower rendering process, just ones on the layer I've dubbed 'action layer' (where the player, enemies, and a few other things lie on). The majority of entities will still live on 'batched' layers--particles, floors, walls, weather effects, font characters, etc.
2. Advanced Model Configuration
I had some pre-defined model 'shapes' built into the engine, but that wasn't really the best design. This older blog post (namely, the video linked in it) shows how I would go about adding a new shape. But as soon as I realized I needed a special shape for the 'blob' enemy (and surely many, many more as I added more enemies), it was time to move model declarations out of the engine and into the implementation assembly. That is, every game using the engine can define their own collision shapes dynamically--and use them in the editor!
The white particles stop when they reach the blob's collision model edge
3. Screen Shake
Well, this one's simple enough. I added support for screen shaking (which is really just rapidly moving the camera). Here's a clip.
Big blobs landing shake the screen
For testing purposes I coded it so that when a blob lands it shakes the screen at a certain strength for a certain duration, but it's a one-liner in code now so I'll be able to quickly add it wherever appropriate.
4. Font Kerning
I fixed my font renderer so that it uses kerning data to properly display characters.
Proper letter spacing, yay