Sunday, June 30, 2013

Four Features

Four quick features added to the engine this week:

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:

Much better.

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!

Here is a picture that shows the blob model outline with a series of particles that stop when they 'leave' the blob:

The white particles stop when they reach the blob's collision model edge

This may seem minor, but I want to focus on having a really tight gameplay experience, and having complete control over collision models is necessary for that.

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

Compare this with this old screenshot, which has horribly messed up spacing:

So, that's all for this week. Sorry, no development video this week, just the little screen shake thing.

Sunday, June 23, 2013

Slabs and Ladders

Hello! If you recall my previous update, there's a section about how I needed to make some enhancements to the layering system to allow for layer-over-layer scenarios. I put forward my plan for it and am happy to report things went pretty much exactly as planned. Here's a screenshot of the result:

Layer-over-layer functionality: complete!

So now, I have the ability to create sections with multiple layer of gameplay. I haven't implemented leaping off edges yet, but it won't be difficult with how I've set up the infrastructure--it's pretty much just the reverse of climbing up a ladder.

This update isn't quite as flashy as the previous few, but it's pretty important from an engine standpoint because this feature is one of the last things I wanted to do before finalizing the Section Data structure. I've been holding off implementing real levels--that is, things that will go into the final game, not just demos--until this was complete, since anything I created before this would be invalidated (and force me to write data converters, which I don't feel like doing!)

That being said, check out the new level editor:

A better looking editor with slab-switching support

Single-slab mode with models off

I've put together a video of me showing off the results. Due to popular request, I've decided to use a mic instead of using annotations to describe what's going on, since it was hard to read annotations and pay attention to the screen at the same time. So make sure your sound is on!

Since the video does a pretty good job of showing what's going on, that's it for this week's blog update. Stay tuned! Allison (the artist) and I are going to be working on some serious character design (the current character is just temporary), so hopefully I'll be able to show off some of that next week.

Monday, June 10, 2013

Return from vacation!

I've been in Europe for the past 9 days or so, which is why there wasn't any update this week. Obviously, I didn't really get much done, but I was able to do some old-fashioned level design. And I mean really old-fashioned: by sketching out maps in a notepad.

So, with absolutely nothing else to offer for the last week, here's one of the sketches of one of the several immediately available to the player at the beginning of the game.

Next up for this week: I'll be solidifying and finalizing the structure for Layering. The steps for this are as follows:

  • The current system has a hard-coded Layers structure with a fixed number of Tile Layers and Entity Layers. These are hard-coded into the engine, which isn't good, because not every game is going to use the same layer structure. So, the engine will instead search for defined layers in the Implementation assembly and dynamically use those layers in the level editor and game engine.
  • The first bullet point is pretty easy, but this next one is going to be a major change. I want to allow for layer-over-layer scenarios: that is, not just a simple drawing order, but also entirely different sets of layers that overlap each other. So, let's say my game has 5 layers: ground layer 1, ground layer 2, entity layer 1, entity layer 2, and ceiling layer 1. But what if I want an entire section above another section? It would be very limiting to just create 10 hard-coded layers in the implementation assembly. Instead, I'm going to split the level structure into Slabs which each have a collection of Layers. Slabs will also serve as physical (that is, they affect game logic, not just drawing logic) separations of entities. A special entity behavior will transfer the player between slabs--this might occur, for example, at the top and bottom of a ladder. The end goal of slabs is to allow scenarios such as walkways that pass over other parts, and the ability to walk underneath those walkways.
  • Once slabs are complete, the lighting engine is going to have to be updated to support slabs correctly. A single layer of lights will no longer be sufficient. The bottom slab (closest to the ground) will receive light from all slabs, but upper slabs won't receive light from slabs underneath them.
  • Game logic needs to be updated such that the creation of entities is not done on a Section, but on a Slab. That is, the code 'section.CreateEntity(...)' is no longer valid, since the engine wouldn't know which slab to put it on. Instead, the command slab.CreateEntity(...) will be the way to spawn new entities dynamically.
  • Finally, I'll have to update the level editor so that the user can add and remove slabs, and switch which slab they're working on. It would also be nice to view just the current slab being worked on in isolation, or a full view of the level at once. This will probably be the most boring part of the update, but good tools are essential, so it's very important to do this correctly.
Will the update come this weekend? I don't know; this isn't a small feature, and it's definitely one I want to get right. I've been putting off real level design until this part was done, because it will change the structure of the file so much and I didn't want to waste time writing data migration utilities.

So, I'll see you when it's done! For more gradual updates, check my twitter,