I was super excited to get a road tileset working in my demo two days ago! Ned can walk around on top of the world with arrow keys. I’m going to have left-to-right and diagonal roads, a similar aesthtetic to the Mother series.

Screenshot of Ned on a corner road

At first I thought the right look and feel for the roads required the sidewalks to take up half a tile: Screenshot of road tiles in aseprite with the grid turned on

This was also done in Earthbound tilesets. When a building was directly adjacent to a sidewalk, it had its own special tile. Since this is the future, I decided to use transparency in my tilesets and just make sure any building that is against a road starts mid-tile. In Godot, I have a map scene with a 2DNode as the root and two child Tilemap nodes to allow for overlaps: one for grass and roads and one for buildings.

Autotiling 😳

I spent at least 12 hours over the past two days trying to understand and build an autotiler for my road tile sets. Adding tiles manually requires you to choose each tile from a pallete each time you want to add a specific tile (there are a lot of tiles!). The autotiler allows you to simply add tiles and have them turn into the right one depending on the context of neighboring tiles. It seemed like it would make the whole process of building a map easier if I figured it out now.

This entry probably won’t make sense unless you go learn about tilesets before reading on. https://docs.godotengine.org/en/stable/tutorials/2d/using_tilemaps.html

After I finally figured out how it worked, I kept doing trial and error on my road tileset to try and get it to work… As soon as I made a tile that had the same bitmask as another, I knew it wouldn’t do. Whenever I knew the tileset wouldn’t work, I tried making various changes to the tilemap, like using a different tile size, adjusting the road placement within each tile, etc. and then I would try to make the bitmasks again.

I also noticed that sometimes even if I had the bitmasks correct, it still would not tile as expected (but then if I reimported the file and redrew everything, it would work as expected. Bug in Godot editor I guess).

When I got smart about it, I stopped trying to organize the roads exactly and just started using lines as placeholders, so I could try different positions and bitmasks more quickly.

If anyone knows of a way to think about making tilemaps systematically instead of by trial and error, please lmk! Attempting to make an autotiler [Line placements used for attempting a full road autotiler]

A nice thing about Godot is that any change to the underlying png file used for the tileset immediately updates in the Godot editor– all of the tiles already placed in the world and the bitmask editor. So once I figured out the correct bitmasks for these lines, I could simply paint over them in the original file with the fully detailed road tiles and everything would automatically update.

In the end, autotiling just does not work with diagonal roads. I realized that the diagonals will always require three unique tiles, no matter what the tilesize was– and this caused duplicate bit masks.

I really wanted the diagonals instead of just a top-down asthetic like old pokemon games. So, in the end (after many many hours), I settled for tiles of 64x64 pixels, and an autotiler that only works for straight horizontal and straight diagonal roads. Any intersections and corners I would just tile on manually from a tile atlas. I changed the straight roads so that they would only take up one 64x64 tile, which made it much easier. Road autotiler [Straight and diagonal autotile bitmask]

By using multiple tilemaps as children of a Node2D for the map scene, my other tilesets can still be 32x32 pixels, or any other multiple of 2! Having a demo game with the animated Ned sprite to walk around in helped me ensure the roads are a good size.

Thought Perhaps there is a way to build a nearly perfect autotiler for these roads that only has a few duplicate bitmasks. When there are duplicate bitmasks, Godot will choose one of those tiles at random to fill the space. It could be more efficient to use an imperfect autotiler and then fix the small mistakes when they occur. Given how much time I’ve already sunk into this, I will just stick with my solution for now.

Camera Movement

In contrast to autotiling, setting up the camera to pan with my player only took about a minute! Just had to add Camera2D as a child to my Player scene and check the current box. https://stackoverflow.com/questions/61108940/how-to-make-camera-follow-player-in-godot

Gives me some hope that I’ll be able to finish this game some day.