This is Manuel from the development team of BitUp at Cosmogonia Games. One of the key features of the game is its map and I'd like to tell you a bit (heh, see what I did there?) about how we're bringing it to life.
In BitUp, we have a very unique level design. One of the biggest challenges that stems from this characteristic is the creation of the game map. The world is large and detailed so we need to give the players a tool that allows them to navigate through it effectively.
Before we started to write code, we had a long, way too long, discussion about the functionality and design of the map. What needs to be shown? How is it going to show it? How are the players going to use it? After answering these questions and analyzing some references and solutions from other games, we finally reached a definition of the map that we were all happy with.
Once we had this basic description of the map pinned down, my job as a programmer started. To achieve the features that we wanted, it was going to be necessary to take all the information of the map, which is divided in areas, sections and modules, and put it in a data structure that could be constantly updated and saved. The structure I settled into was an adjacency list where each entry is a node with connections. In this case, the node is a section, which in turn, contains its respective module data inside an array (a module is the smallest piece with which you can divide the map). The question was, how to construct this structure? The level was modeled freehand and the only rule to it was that it had to be divisible by a module’s lengths, so, beside that, anything was possible.
At first, I had the idea of creating an algorithm that could read the level’s mesh data and figure out its structure, logically dividing it into the “imaginary” modules that composed it, but I quickly discarded the thought. Then I realized that I could try to write the data structure myself. I wrote a small json file with a section and its modules, then I created a simple script that could read the file to deserialize the data structure and it worked! I had what I needed to create a map, the representation of the actual level. Job done? Not yet.
The problem was that it wasn’t a single section that had to be written, but dozens and dozens, each of them with their module data and connections to other sections. Doing it all by hand would be an interminable task, and good luck updating the file when the changes to the level would inevitably come. What’s more, the final file could not be in json format or any other format that is readable to the naked eye because of security concerns. What to do then? Here’s where I introduce you to the map editor!
This is a node based editor. Like I mentioned above, each node represents a section and its information. Sections can be interconnected. With the dimensions field of the node you define a grid of modules, and in the module inspector you can quickly “paint” the modules that compose the section.
I had prior experience with node editors in Unity but I always used the old IMGUI API. This editor was developed using Unity’s newest API for drawing and extending the editor, UIElements, publicly introduced in version 2019.1. This new API completely changes the paradigm of drawing in the editor. IMGUI uses an immediate draw mode, where the code you draw with is, basically, inside a loop that executes every frame. UIElements, on the other hand, is more similar to a web page since you can define a hierarchy of objects (a DOM) and then the engine draws them for you.
Once this editor was completed, creating the map file was a piece of cake. Adding nodes, filling them with the necessary information, a couple of clicks to export the file and done. We have a game map.
I hope you found this information interesting! Game development is surely a challenging process and we want to share some of it with you.