When I first started on building a world map for my game, I used a static image. Specifically, I made a quick map using Inkarnate, which I use anyway for making tabletop RPG maps.

This worked for a bit, but eventually I decided that my map needed a whole bunch of things that a static image couldn’t provide – I wanted to define regions of the map, I wanted some notion of how long it would take to move over different terrains displayed on the map, and I wanted to be able to designate some areas where quests won’t be able to spawn.
Designing a new World Map

Taking inspiration from a type of gameplay called “hexploration” in tabletop RPGs, and from games like Civ 5/Civ 6 (and now Civ 7), I decided that a hex grid would work really well for this.
So I went ahead and made a hex grid map.
It’s quite a primitive map by today’s standards – I made some coloured hexagons and simple terrain features using Krita, then I set up a component with three TileMapLayers in it – one for the base terrain, one for tile borders, and one for features. I feel like it looks quite charming despite being very bare bones and I was very pleased with it.
Then I remembered all the other things I wanted.
I decided that some kind of array containing all my tile information would be pretty efficient. I’d have to find some way to tell the code where all the regions were and which tiles couldn’t have quests spawn in them. I knew that if I added some invisible layers, I could use code to get all the information out of the map at runtime. That, however, did not feel like a clever solution. Why should I leave components in my scene that would never be used to do something in-game?
And so I built myself a world map editor. Using the Godot editor for the UI, and VS Code for the code. I really enjoy that I built a tool for my Godot game using Godot.
Editing the World
I started off moving my existing map component and code into a new scene and set it up to output that information to a json file. I added in an extra layer with numbers as the tile set to define my regions because that seemed like a nice easy way to do it. I’m cheating a little bit because I still do a lot of the tile placement in the Godot editor, but I don’t really need to have the full map editor as a standalone program.

In Godot, the different tiles are represented as vectors in a tileset. My editor has a lot of repetitive code that takes advantage of this to convert tileset information into terrain data using dictionaries, e.g.
private Dictionary<Vector2I, TerrainType> _terrainTypes =
new Dictionary<Vector2I, TerrainType>
{
{ new Vector2I(0,0), TerrainType.Ice },
{ new Vector2I(1,0), TerrainType.Snow },
{ new Vector2I(2,0), TerrainType.Dirt },
{ new Vector2I(3,0),TerrainType.Grass },
{ new Vector2I(4,0), TerrainType.Water}
};
private void GetTerrain(Vector2I tile)
{
return _terrainTypes[_baseLayer.GetCellAtlasCoords(tile)]
}
Absolutely riveting stuff, I know. There’s a reason I’m not putting in every single dictionary and example in here.
Region Borders and Labels
In order to calculate where the region borders should be drawn, I needed to get polygon data for each tile. To do that, I had to open the Physics Layers section in the node inspector on one of the tilesets and enable a collision layer (I chose the base layer, but really it could have been any).
Enabling collision layer causes Godot to create a collision polygon for each tile, which I can then read in and combine with its neighbours in the same region to make a super polygon. The coordinates that describe that super polygon can be used to draw a line around it.
I’ve not found another way to do this despite quite a bit of searching. I could probably have manually worked out the offset for each point of the hexagon from the centre and just input that, but the whole point of building a world map editor tool is so that I have to do as little manual work as possible if I make changes.


With the collision layer added, I could then open the TileSet editor and “Paint” on a collision polygon.
After this, I wrote code to grab every hexagon in the region and merge their collision polygons into the super polygon. Code uploaded as a PDF for those who are interested.
I also added code to calculate the centre of each region using this formula so I could put the label there.

Region Details
The last details I need to edit for regions at this point are:
- Region name
- Is it visible at the start of the game?
- Quest level range
- Allowed quest types
I also need to be able to save and load map data, set places where quests can’t spawn, and also set a tile as a “home base” which will be used to plan quest routes.
In the previous screenshot, you may have noticed that there’s a Save button and a Load button – these just save the data where my world map scene expects to find it and can load data from the same file.
To facilitate the region editing, I created a popup that appears when you click on a region.

The Set Route Start button you can see there allows the user to click a tile, which gets stored as the quest route start hex.
And to choose places where quests can’t spawn, the Set No Spawn Hexes button (amazing name, right?) is a toggle button which, when active, allows the user to click and drag areas where quests are not allowed to spawn. Right click removes a hex from this designation. You’ll see that I’ve blocked out a large chunk of hexes under each region name label, and also the ones around the edges of the map so that there’s no chance of a quest spawning somewhere the camera can’t go.

So… how much time has this actually saved?
Realistically, it’s probably only saved me an hour or so at the moment, when I factor in the time spent building it in the first place.
What it has given me is some peace of mind.

My map data json file is now nearly 13,000 lines long. And I’d have to go through a lot of that any time I wanted to make changes.
Some of those changes might be easy, e.g. changing some terrain.
Some might be difficult, e.g. recalculating region polygon data if I change some hexes.
Either way, I’d be terrified of how many mistakes could go unnoticed in a 13,000 line json file.
And if I decide to add some more features to the world map, it’s far, far easier to make a small change to the map editor tool than it is to work out exactly what json I need to change in the map data file.
Plus, this was kind of fun and it taught me a lot about TileMapLayers and polygons, which will be quite useful when I get around to building the turn-based combat scenes.
Future Tools
I have every intention to build more tools to help me edit data for my game as I go along. I’m sure there are people who can visualise swathes of json data with ease. I wouldn’t consider myself bad at such a thing – I’ve had to do a lot of editing json in my time as a Software Engineer. But it’s significantly easier to just do it through a quick and dirty graphical interface. It’s much easier to spot mistakes, and to avoid making the mistakes in the first place. And avoiding making mistakes saves you a lot of time in the long run.
So, if you’re going to be repeating a task many times over, or just want to make sure you get something complex right, build a tool to help with it. You won’t regret it.