The svson.xyz blog

Mythos Engine Update 19-06, and on writing tools

Published:
Tags: gamedev qt python
1120 words
6 min read

Tilemaps

Mythos Engine is almost untouched since the last post. I did implement tilemap rendering on 14th of June, so there’s at least something ;).

The tilemap geometry is generated in the geometry shader, since it seemed nicer that way. Basically, I dump a bunch of unsigned integers onto the GPU that denote the tile ID (starting from top-left corner) which the GPU turns into properly placed and textured quads.

Shaders get a couple of uniforms for the calculations:

  • Map dimensions in tile units,
  • Tile dimensions in pixels,
  • Map tile count per side,
  • Z coordinate for the whole layer.

The vertex shader stage calculates the destination coordinates (gl_VertexID div/mod tile_count mul tile_px) and texture position (tile_id div/mod tiles_per_side), which then get passed into the geometry shader. Note that the tilemap is drawn in pixel coordinates.

The geometry shader is where things get a bit more interesting. For each point that comes in from the vertex shader, the geometry shader draws two triangles to form the tile quad. Might not sound interesting, but I spent a couple of hours beating my head against the wall of jaggly vertices displayed on my monitor trying to get it to work properly.

float tw = gs_in[0].tex_width;
float th = gs_in[0].tex_height;
float tx = gs_in[0].tex_x * tw;
float ty = gs_in[0].tex_y * th;

// Bottom left
gl_Position = top_left + vec4(0, -height, 0.0, 0.0);
gl_Position = projection * gl_Position;
uv = vec2(tx, ty);
EmitVertex();
[...]

In the end, the reason for my multi-hour struggle was that I mixed up my units (pixel or normalized). I think I’m starting to get the hang of it, or at least I can almost understand what I’m doing and what all those fancy OpenGL buffers are storing.

I tried putting as much math into the vertex shader as I could, because I read from a trusted source (somewhere on the internet that I can’t remember) that geometry shaders are horrible and slow :^). Not sure if that’ll be an actual issue in my use case, but I’ll leave it to future-me. No point in trying to achieve peak performance when I’m still learning.

Re-styling RmlUi

I did start work on my GUI and took a look at re-styling the GUI components, as the space invaders style wouldn’t go well with the game I’m envisioning 1.

The problem I was faced with was the spritesheet format, for which I didn’t find any editors.

@spritesheet theme 
{
    src: invader.png;
    resolution: 1x;

    title-bar-l: 147px 0px 82px 85px;
    title-bar-c: 229px 0px  1px 85px;
    title-bar-r: 231px 0px 15px 85px;
    [...]
}

Since I like to dream big, then I only had bad dreams about doing a large GUI skin by method of manual entry, because like any other tedious manual task — it’ll be darn tedious.

So I decided to write an editor for the spritesheet files. The format is fairly simple and all I’d have to do is display boxes and move boxes on an image. Picked Python and Qt for the job and cranked out a WIP prototype of the tool. Could also learn Qt for future tooling in the process as well, win-win.

View of the editor window
The main window

I originally wanted to publish it on the 18th of June, but I kept finding little things to add to it, as I didn’t want to release crap. It was mostly functional by then but, then I realized that “hey, I don’t have undo/image reloading/highlighting sprites on hover/some other QoL feature!” and went off to implement that. Overall I did learn a lot, though mostly about using Qt, as it is the biggest program I’ve used Qt for.

I did mess up the architecture a bit, as I concentrated too much logic into the main window class. Now that I’m looking at adding support for multiple spritesheets I’m at a bit of a pickle, as the main window class contains an array of all the sprites, each of which is intertwined with QListElements, as I needed a way to reference them from both elements. So that functionality will mean decoupling the components, which, while good for the quality of the codebase, isn’t that fun to do.

I guess that problem would’ve been averted by the same method as with the libpng problem, reading the docs before doing the thing. But who has time for that, better to rush in and then refactor ;).

As the modern techies say: Move fast, break things, own nothing and you will be happy :^)2.

After I released it I posted the link onto the RmlUi Gitter and the (lead?) RmlUi developer suggested adding support for packing sprites from loose files…

Damn, I would’ve saved so much trouble doing this fancy-pants UI if I had come up with the sprite packing idea before starting work on this tool, as that would’ve solved my problem with even less work in the spritesheet creation process. Oops, but at least I’ve now got a tool to visually verify the spritesheets the packer creates and gained experience in Qt. Plus I’m pretty happy with how it turned out, though I’m a bit biased since I’m a power user of the Smart RCSS Spritesheet Editor Pro Unleashed Edition™ 8-), and, seeing as it’s released and, to my knowledge, usable for what’s written on the tin, then maybe it’ll be of use to someone else.

Next steps are to implement some of the missing functionality, the highest priority of which are:

  • Support for multiple spritesheets,
  • Sprite packing from loose files,
  • Loading spritesheets from inside of non-RCSS files.

The last one is on the list purely because I feel like writing a parser. For the currently released version I decided to use the tinycss library for the CSS loading with custom extensions to support @stylesheet blocks. Too bad that I didn’t check if tinycss is still maintained :)). Since the tool would have to parse a rather simple subset of CSS then I’ll most likely go the custom parser route.

The next post might be about parsers.


As a sidenote, I guess I should rewrite my “About” page, as I did a short spurt of posting about hardware and then pivoted into blabbing about software :).

Off-topic rant: I wish GitHub would stop stealing my slash key in the web browser :@@@. I want to use the slash key to use the search functionality as it works on every other page, to search the current page, not their special key-jacked “search GitHub” search.


  1. I don’t actually have a clear game idea, but I’ll just wing it until I do ;) ↩︎

  2. I forgot the phrase and had to search it on the WWW and apparently the best result for “programming break fast” is “School Breakfast Program - Wikipedia”. ↩︎

Next part: None, yet!

Previous part: Mythos Engine Update 12-06

Series outline