Balleg Devlog (December 2020 + Year in Review)

A very grey beta level.


I procrastinated away most of November, so this month, I made a push to create some playable beta levels. Most changes described here are a byproduct of this work.


Beta Level Push

Beta level 2.

I made three beta levels with a play time of about four minutes. There isn’t much to say about them right now, but it’s nice to have some semi-coherent gameplay instead of a jumble of disconnected test rooms. Each one is playable without noclip cheats, has checkpoints, and features a simple boss at the end. For the final game, I intend for levels to be split up into smaller rooms. For now though, it’s much easier to design levels as big single tilemaps.


Opponent Systems

Added audio and visual effects for when the player’s shot collides with a ‘protected’ opponent. An actor with this attribute will deflect or destroy player shots without taking any damage.



Added two ways for opponents to sense being damaged: a simple flag which gets set to true, with no other details about the attack, and an optional callback function with a reference to the source actor (if applicable), plus the amount of health deducted.



I wasn’t sure if I should include pits of instant death, or if I should only use sets of non-instant-kill hazard terrain instead. The latter I feel is more fair, but the player always needs to be capable of escaping the damage tiles, which limits the layouts I can come up with. I’ve decided to include off-screen pits because they’re more tense.

Since a scene can have multiple tilemaps, there is no longer a single horizontal line that I can point to and say “you die if you fall past this point.” To make this work, I added a special death-pit terrain tile, and each pit is terminated with those tiles. The camera system has to be set up to not follow the player down these pits.


An off-screen death pit.


Scroll System

I simplified scroll zones by adding some more attributes. Before, I had made ‘proxy zones’ which would activate the rules belonging to a different zone when the player overlapped them. I used this so that the screen wouldn’t follow the player down death pits, and I had some ideas for more complex scrolling layouts (for example, having different scrolling rules for the top and bottom parts of a screen.) Once I started putting together beta levels, I realized that proxy zones are just way too much config work and too fragile to be used regularly.

The new attributes are extend_left, extend_right, extend_top and extend_bottom, and they do pretty much what you’d expect. Assign 64 to extend_bottom and the camera won’t follow the player down 64-pixel-deep death-pits. Another case where this helps a lot is that the viewport is 480×270, but the closest match to that in 16×16 tiles is 480x272. So assigning extend_bottom to 2 in those cases gets rid of a two-pixel-tall gap between single-screen scroll regions that are stacked on top of one another.



There’s very little of interest to show in this month’s stats. (Truth be told, I lost a lot of momentum in the second half of the month.) I’ll be adding some more things to the stats beginning in January — more on that in a bit.

Codebase issue tickets:


Project lines of code:


2020 in Review

(Can’t write a ‘2020 in review’ post without mentioning the coronavirus pandemic. I’m okay, I don’t think I’ve caught it (if I have, I’m not experiencing symptoms), and I’ve been trying to minimize contact with other people.)

This year, I kind of ping-ponged between pushing myself too hard and (surprise) being burned out. I tested out several code ideas that I was interested in:

  • Texture packer + texture atlas
  • Use LOVE SpriteBatches for rendering tilemaps
  • GLSL shader stuff:
    • Apply indexed color palettes to pixel art
    • Dither-dissolve sprites and backgrounds
    • Apply mild wavy distortions to tilemap layers
  • 9-Slice sprite rendering
  • Fixed grid spatial partitioning (for collision detection)
  • Collision bitmask filters
  • Actor sub-shape support (rectangle, circle, diagonal lines, right triangles)
  • “Blocking” actors which behave like solid walls, floor, ceiling, etc.
  • Support for multiple maps (rooms) per scene
  • An event response system for specifying custom actions on a per-spawnpoint basis
  • A behavior macro system for actors


In November, I made large changes to how the player controls, and I also redesigned aspects of the game to simplify production. The biggest of these changes were:

  • The player can no longer be hurt by his own shot.
  • The player’s shot used to disappear after four impacts with the ground, walls and ceilings. It now disappears after a fixed amount of time. I made this change because various edge cases in counting impacts made it feel unpredictable.
  • The player can grab already-thrown shots and launch them again, which is faster than waiting for the existing shot to break.


Having already blown some provisional ETAs, I’ll refrain from announcing another one. On the bright side, I’m in a good position to keep going with more beta levels.

Biggest troubleshooting thing this year: in August, I found that rapid trace flushes were the cause of intermittent performance issues and crashes, so I disabled JIT. Performance without JIT has been fine so far (LuaJIT’s interpreter is pretty fast), and I’m OK at this point with just leaving it off after program initialization. Identifying this was a great relief.

For January, I’m planning to change the project structure to include a preprocessing pass. This would let me simulate constants, and it would be a good point in the build process to do things like source code minifying.

I started looking at wxWidgets / wxLua as a possible starting point for GUI tool work, and I got some basic C and C++ test projects to compile with LuaJIT included as a library. I don’t know if I’ll get anywhere with this stuff in 2021, but it was good to look into.

For the devlog stats, to reduce overhead, I’ll be switching from collecting info per-day to collecting it at the end of the month. Starting in January, I’m going to gather other kinds of info as well. This is what I’m considering so far:

  • Number of map files
  • A rough map size estimate, in total screens. (This is going to be wildly inaccurate for a while due to the current batch of playable maps containing a lot of empty space.)
  • Total number of actor (game object) definitions
  • Estimated game time (just me running through the existing content with a stopwatch.)


I guess that’s all I have for now. Next post will be around the end of January.

Leave a Comment