Killing hex bugs – and the importance of sprite sheets

hex mapping sprite sheet for fantasy mapping web app

I’ve been working more on my hex mapping project. One of the requests was to have random terrain placement. So, rather than picking a terrain element, placing it, and then changing to a new one – instead pick a terrain type, and place a load of terrain with the tool taking care of variation. That took a bit of coding, and threw up a nasty bug. Every 7 or 8 times you clicked the base of the tile would place, but not the terrain on top. I tried everything to figure out why – the data was there, when you refreshed the map, the terrain turned up, but it wouldn’t load on click.

It turns out it’s an image load problem. Basically, each image asset is it’s own image. So every time a tile is placed, two images are loaded – the base and the top. When you had to go back to the menu to change the tile, the timing was long enough that this was fine. But when you can click, and click, and click, with no time in between, sometimes the top image just wouldn’t load.

This introduced me to sprite sheets. Basically, rather than having every image as it’s own .png asset, instead place all the terrain on one large .png. That asset gets loaded once. Then, css picks the part of the image to show in each <div> element. Picking the region of the image is super fast, and solved the missing terrain problem. It has the excellent side effect of optimising everything else in the app too – and providing an easy workflow for the future. The image at the top of the post is the sprite sheet I’m now using for the terrain (transparent background replaced with mid-grey for ease of reading).

Downside? A bunch of re-coding, and a new data structure for the maps, that breaks backwards compatibility of maps. Well – that’s why this is an alpha test.

Here’s the result – a snappy tool for placing random terrain!

2 thoughts on “Killing hex bugs – and the importance of sprite sheets”

Leave a Reply

Your email address will not be published. Required fields are marked *