Mapping Minecraft with Go (a.k.a OrienteerMap)
It has been, for a long while, on my bucket list to implement a program that renders from some sort of game/map data. And over the summer 2021, I had the time and opportunity to implement just that. Meet OrienteerMap, as I call it.
As a process of iteration, I made two different prototypes. First one, one on the top, renders large-scale PBM maps by having only single pixel per block. PBM was chosen as a format due to the ease of implementation of a renderer that doesn’t require the whole image file loaded in memory at once, without resorting to advanced lower-level methods like memory-mapping. Second one generates grids of SVG images - plan was to implement a beautifully scaling geographical map, with a combination of pixel tiles and contour curves (only former has been implemented so far).
Lessons learned from this venture
- Minecraft data format is complex. Very complex. There’s years of evolved storage methods, and depending on which exact revision of Minecraft you are playing, the same thing might be stored differently
- As such, a significant chunk of time was spent on data normalization - in other words, massaging and shaping data to a regular format that is easy to process by higher-level code
- This also proves a need for robust test cases - at least for the most important parts which are likely to be required often or are of most interest (e.g. chest inventories, tame entity characteristics). It should be noted that what documentation is available, isn’t completely up to date and is almost entirely unofficial
- With the amount of blocks being constantly increasing (and already large when this was developed), it will be a must to devise additional support for deriving color maps from resource packages. These prototypes were hand-rolled, but the approach quickly proved inviable for anything more but the most common blocks
- Golang reflection is very useful for deserialization purposes. I studied tnze’s NBT package thoroughly, and implemented a similar, perhaps somewhat more specialized method to pull data from NBT files into structures
- Parallelization is powerful. Even relatively large amounts of data could be processed in a reasonable time, particularly visible from the first prototype’s large map. Remember, one pixel is one block
I stopped developing this after I had an initial prototype - it was a hectic span of few weeks to implement these. That said, I wouldn’t foreclose the idea of me returning to this prototype eventually - the concept of using Go for parallelized data-based 2D rendering was proven very viable and usable with further refinement.
Source code for the second iteration can be seen on GitLab