working with tiled for map editing

Tue Feb 04

Author’s note: writing this blog post made me realize that my brand new-ish site could use more sophisticated blog post styling… like a table of contents, and footnotes. Looking forward to implementing these things! Please bear with me for now though :)


I’ve dedicated many hours over these past 2 weeks to a program that I only recently came across, during batch at the Recurse Center (RC). The program is called TiledExternal link icon, an editor for tile-based 2D maps.

I need it to develop maps for my top-down, retro-style game world, which I plan to embed in this site’s homepage and hook up to this site’s navigation (fun aside: Pokémon GoldExternal link icon was a cornerstone game in my childhood and is my main inspiration). But I didn’t know anything about how these sorts of maps are constructed. It’s a whole thing (as most things are)!

I found that game tutorials would often skip over this bit and assume that you either have a map ready to go or will just use theirs. So, this is what I had to do to build my first map.

But wait, why build maps out of tiles in the first place?

While I am building a nostalgic RPG-style town, tile-based maps are fundamental to many types of games: from classic platformers to modern roguelikes, dungeon crawlers, and city-builders. The grid system that tiles provide makes designing levels more systematic and efficient, compared to placing individual objects. It’s kind of like digital LEGOs: one can quickly build complex worlds by combining and reusing basic pieces. It is also more memory- and bandwidth-efficient, since instead of storing one massive image with repeated elements, games can store a small set of unique tiles and just track where each one should be placed.

Let’s also take a moment to define some helpful terminology:

I had a lot of trouble grepping the difference between a texture atlas and a sprite sheet, with sprite sheet being the more common term that I was familiar with before this. The difference is fairly subtle, as both present as a single image file with multiple frames. I’ll return to this later.

Step 0-a. Before I could start designing maps, I needed artwork. I could create the art, if so talented. I am not so talented, in which case, art usually comes in the form of an asset pack from an artist, free or paid, which can be found in places like itch.ioExternal link icon, kenney.nlExternal link icon, and fab.comExternal link icon (which I have been told is more of an archive, now that Epic Games bought itExternal link icon). Anyway, finding assets is not a simple process! I had a pixelated, nostalgic 90s aesthetic in mind, with a host of buildings and landmarks and non-playable characters (NPCs) reflecting different elements of my (mostly professional) life around a small town. With such specific art style and game elements in mind, I had to do some spelunking for appropriate art. I did not settle on assets as Pokémon-like as I imagined, but this Pixel Quest asset packExternal link icon is still pretty charming.

Step 0-b. The Pixel Quest asset pack probably has over 100 elements inside, and I think I am being conservative there (all for a mere US$3.60)! I only needed a subset of these for my map, so I gathered the individual assets I needed and “packed” them, using a 7-day pro trial of TexturePackerExternal link icon, into 2 texture atlases: one for assets with dimensions of 16x16 pixels, another for 32x32 pixels.

Step 1. OK- now we can finally do some tiling! This involves quite literally placing your tiles on a grid.

Step 1-a. First, I chose a map size (by number of tiles) and a base tile size. But even just this step took me a couple tries to get right: to determine the sizes, I pulled up a reference map from the asset artist in MS Paint and counted 32x32 pixels per tile; so I thought, surely my tile size is… 32x32. It turns out that many tiles in my tileset are actually 16x16, meaning when rendered on a 32x32 map, I would see the target tile in one corner of the grid cell, plus 3 neighboring tiles. Between this and misunderstanding the purpose of layers, I had no idea what was going on for a while… until I was able to pair for 20 minutes with a more experience game developer in my RC batch (thanks, Alex!). And then voilà! I was finally able to place a single tile in a cell of my grid satisfactorily.

Step 1-b. Next up, I created Tiled tilesets (.tsx files) from tileset images (.png files, typically). This involved importing a source image, giving it a name (that becomes a key in my code later on!!), making sure I left the “Embed in map” option unchecked, and specifying tile dimensions in yet another place. One may or may not also have to tweak the “Margin” and “Spacing” settings, depending on your asset pack (fortunately, I did not have to do this)!

Step 1-c. Now I could finally “paint” by placing tiles from my new tilesets on my empty tilemap. If you have a large map, there are tricks to make this painting less granular, like texture brushes and some, frankly, heinous feature called automappingExternal link icon, which is like the most complicated find-and-replace engine you will ever come across. But I just stuck to the (1) stamp brush and (2) bucket fill tool, with some occasional rectangular select and eraser, for my tiny town.

Layers are essential for creating depth and organizing your game world. Tiled offers three fundamental layer types:

  1. A tile layer provides the core grid system for placing tiles. Elements must snap to the grid. Examples: ground tiles, walls, paths.
  2. An image layer holds a single large graphic, without tiles, which could be helpful for non-tiled backgrounds or overlays. Example: a distant mountain backdrop in a side-scrolling game.
  3. An object layer is best for elements in your game that will interact with your game engine (yes, we will code someday!). Elements do not need to snap to the grid. Examples: coins, power-ups, NPCs, spawn points.

How many layers I needed and for what kept evolving as I discovered new issues with my hierarchy 😵‍💫 Nothing is straightforward around here! From accidentally overwriting tiles when I really wanted them to overlap, to wanting to un-snap some elements off of the grid, to ensuring my character could walk behind tall things like trees or buildings. I guess this is kind of like coding, now that I think about it, with its layers (heh) of abstraction. But refactoring here is a lot more annoying, IMO… I finally settled on 5 layers, from bottom to top:

Anyway, you’ll want to decompose your map into layers before you start to paint. You may need to start painting anyway with an imperfect model and then iterate. Think about:

Step 2. Save your map as a .tmx file for any future map editing (note: Phaser does not use this file, or the .tsx files), then export your map as a .tmj file for use in Phaser. It is possible that some game frameworks do not require this export step: I would not know! Keeping these files together will make it easier for you to find them later.


So that’s my experience so far with Tiled!

I can also write briefly about integrating with the HTML5 game framework, Phaser 3External link icon, although this is a topic with much better coverage elsewhere.

Results

All that work, and what did it get me? Why did I do it?

Feel free to visit the map I built with ~approximately these steps here: https://iconix.github.io/rc-impossible-town/nadj-land/External link icon.

Well, I’m off to build a bigger map. Thanks for reading!

Resources

recurse

blogging

learning in public

gamedev