I went on yet another cartographic adventure recently to make myself some maps of the 2018 indie hit Subnautica, and here they be.
This post may contain game spoilers. Proceed at
your own risk if you have not finished the game.
Goals
There are many existing maps of Subnautica out there. Interactive ones such as subnauticamap.io and mapgenie.io. And numerous static ones you can find in image searches. They’ve been helpful in my playthroughs and in this project, but none of them do everything I want. And many of the static image maps were made from earlier versions of the game that aren’t accurate anymore.
|
|
I have a number of questions that come up during my playthroughs that a good static map image or set of images should be able to answer for me.
- Terrain details — Many maps show no geographic features at all. In a game that’s just open ocean with no in-game map or visible coordinates (without using the development console), it’s essential to be able to identify distinctive geography to figure out where you are and where your goal is. This can be depicted both with hillshading to give an intuitive sense of the landscape and with contour lines like a topographic map.
- Depth — Your primary character leveling mechanism is how far you can dive. You start out with a short oxygen duration, slow swimming speed, and a penalty if you dive below 100m. As you progress, you get better equipment and vehicles to dive to deeper areas. It’s helpful to see what areas you can reach with your current abilities and what is still out of reach. Upgrades happen in 100m increments, so showing depth in color coded bands will help.
- Cave entrances — There are some major cave systems of importance to the main story, and they have multiple entrances that can be difficult to find. Marking where these are will be helpful.
- Coordinates — While the game does not reveal x,y,z coordinates to the player during normal play, it’s still useful to have a precise way to locate places on the map. A simple grid will let us refer to locations or cross-reference with other resources like wikis and game guides as well as reckon distances.
- Lifepods — You’ll be sent to explore other lifepods around the map during the story line. Seeing them on a map will help locate other nearby points of interest by using these signals as a constellation.
- Wrecks, large and small — Pieces of the main ship are scattered around the map. Large pieces will have explorable interiors while small ones are mostly just scattered chunks of metal. These contain important scannable items that provide blueprints and story data. A thorough list of what can be found at each wreck site and what tools will be necessary to fully explore them is probably beyond what a map can clearly depict without getting extremely cluttered, but simply numbering the wrecks and having a separate text list to cross-reference should be sufficient.
- Degassi bases — There are five in total. Includes scannable items and story data.
- Alien bases — Major story locations as well as minor caches.
- Leviathans — Knowing what megafauna awaits in a particular biome lets you plan to be more cautious when approaching.
- The Aurora — It’s an extremely large detail and one of your only points of reference and somehow I keep forgetting it. It’s really important! Simply representing its location and orientation is sufficient. Having a map of its interior is helpful but is not really the goal of this particular project, and there are existing ones out there that do the job.
First Attempts
I wasn’t setting out to do a lot of engineering with this project. I was just going to borrow the best blank map I could find and mark it up with noteworthy stuff. There was no intention of sharing it, just making some static maps for myself. I liked the MapGenie map I found, but it had some shortcomings. First, it doesn’t expose coordinates. Clicking specific markers sometimes shows their coordinates, but you can’t mouseover to get coordinates of arbitrary locations. It also lays out the cave systems beside the main map instead of overlaying them. It’s a fine choice, but I would prefer they be shown in situ to help find entrances and relate locations in the overworld and underworld better.
I extracted the background imagery from this map as a basis for my own and set out to try to figure out a coordinate system, translating between pixel coordinates and world coordinates, but I was having a heck of a time. I visited many of the locations in-game, taking note of my coordinates in the dev console and studying the topography to figure out where on the map I was as accurately as possible. But the math wasn’t mathing. I’d decide on a scale factor and origin, but I’d wind up with some coordinates that were way off. I finally realized the imagery was distorted, likely due to it being rendered with perspective, so shallows being closer to the camera were larger and deeper areas were smaller, introducing a subtle but significant fisheye effect to the geometry. Well that’s no good!
![Screenshot of insane spreadsheet](https://blog.rocketsoup.net/wp-content/uploads/2024/07/spreadsheet-1024x611.png)
Digging around for other maps, I saw a post by someone who was able to extract height information directly from the game data. It’s an old post and talks about a file that is no longer in the game, but it was a lead. Some more searching led me to a post by a Subnautica developer going into the details of how the terrain is stored, and it matched what I was seeing in my game data. Without going into detail, it’s a voxel-based system stored in octrees at 1m resolution. The post was intended to help mod creators in lieu of publishing official tools. This was perfect! After only a few hours of hacking together some awful Python I was getting my first depth maps that looked familiar.
![Grayscale heightmap of the game map](https://blog.rocketsoup.net/wp-content/uploads/2024/07/depth-final-1024x1024.jpg)
Additional Imagery
This was basically all I needed. I did some brief searching to see if there was info on how objects are stored (e.g. wrecks, plants, creature spawners, etc.), as it would be nice to go straight to the source and automate locating these things, but I didn’t find anything, and it would be too much work for too little benefit for my purposes.
I spent another day or two perfecting my heightmap extractor. I reworked it to render from the deepest parts of the map to the shallowest, saving off slices as it went. This would hopefully give me views into the Lost River and Jellyshroom Cave. Heightmaps were rendered as grayscale, with higher parts being rendered in lighter shades, and an alpha channel to render areas without geometry as transparent. The map is 3200m deep, and I wanted to preserve those values rather than reduce them to 256 values, so I used OpenCV for Python to create 16bit PNGs. Rendering was very slow because my code wasn’t amazing. My most optimized version took around an hour to render all the slices at 160m increments.
|
|
Then I wrote Python programs to ingest those heightmap images and generate other visualizations, including topographic contour lines, shaded depth zones, and hillshading. The voxel data also includes materials, such as sand, rock, coral, etc. and I rendered images that gave a unique arbitrary color to each one. Those were interesting images, but figuring out which textures go to which material, decoding those textures, and rendering more accurate colors was just a bit too much work and may have resulted in too cluttered an image, so I abandoned that.
One other bit of information was biomes. Fortunately while digging through the game files I found files named biomeMap.bin and biomes.csv. The former was exactly 1MB, and the latter was just plain text, so it was completely trivial to deduce that the bin file was just 1024 x 1024 one-byte biome codes (each byte representing a 4x4m area), and the csv file mapped these byte values to names. It literally took minutes to figure this out and get a usable image.
![Biomes](https://blog.rocketsoup.net/wp-content/uploads/2024/07/biomes-1024x1024.png)
Compositing
The longest step was taking these disparate images and cobbling together a useful, clear, and aesthetically pleasing map. I simply went about putting as much stuff into a big Photoshop document as possible with dozens and dozens of layers, seeing what looked good, what could be shown clearly without getting overly cluttered. Could I fit all the details in one image or would I need several that focus on different visualizations?
I also spent time manually placing points of interest on the map: wrecks, lifepods, Degassi bases, biome labels, and more.
All of this was more art than science. Map making is a skill that fascinates me and I don’t feel particularly skilled at. There are countless details in a good map. Where you place each label so that it is legible, uncrowded, and isn’t covering up something important. Scaling so that large elements can be seen at a distance while tiny details can be seen close up and they all fit together harmoniously. Picking typography that’s clear and legible and which helps you identify priority and classification. I could futz with a map for a thousand hours and never be fully confident I’ve done a good job.
Images
Here are the maps I have created so far. I played a new game using these, and that helped inform the process. I think I’ve included all significant information I can fit on a map, but if I think of more that I can reasonably include I will update these.
Last updated 2024-07-20.
Detail Map
![Subnautica map](https://blog.rocketsoup.net/wp-content/uploads/2024/07/map-details-2-scaled.jpg)
Supplemental info:
- scannables.txt — A list of every numbered wreck, lifpod, Degasi base, and more and what noteworthy items you can find in each location. Useful for finding that important fragment that you just need one more scan of. (I am constantly starving for a battery charger early in my playthroughs, for example.) This info is just borrowed from the Subnautica wiki and compiled in one searchable document.
Cave Systems
Maps of the major cave systems. Green arrows show paths to shallower areas, blue arrows show paths to deeper areas.
![Subnautica map](https://blog.rocketsoup.net/wp-content/uploads/2024/07/map-jellyshroom-cave-1-scaled.jpg)
![Subnautica map](https://blog.rocketsoup.net/wp-content/uploads/2024/07/map-1-lost-river-2-scaled.jpg)
![Subnautica map](https://blog.rocketsoup.net/wp-content/uploads/2024/07/map-2-inactive-lava-zone-2-scaled.jpg)
![Subnautica map](https://blog.rocketsoup.net/wp-content/uploads/2024/07/map-3-lava-lakes-2-scaled.jpg)
Simplified Maps
Here are some simpler, single-purpose maps that may be easier to read.
![Subnautica map](https://blog.rocketsoup.net/wp-content/uploads/2024/07/map-blank-scaled.jpg)
![Subnautica map](https://blog.rocketsoup.net/wp-content/uploads/2024/07/map-biomes-scaled.jpg)
![Subnautica map](https://blog.rocketsoup.net/wp-content/uploads/2024/07/map-wrecks-scaled.jpg)
![Subnautica map](https://blog.rocketsoup.net/wp-content/uploads/2024/07/map-lifepods-scaled.jpg)
![Subnautica map](https://blog.rocketsoup.net/wp-content/uploads/2024/07/map-degasi-scaled.jpg)
![Subnautica map](https://blog.rocketsoup.net/wp-content/uploads/2024/07/map-leviathans-scaled.jpg)
![Subnautica map](https://blog.rocketsoup.net/wp-content/uploads/2024/07/map-architect-scaled.jpg)
Rights, Permissions, and Miscellany
You can do whatever you want with these images, private or commercial, modified or unmodified, with or without credit (though credit’s always nice). It’s based on copyrighted game content by Unknown Worlds Entertainment, so to the extent that copyright affects this derivative content, it affects your reuse of it. I dunno law stuff. Just a fan unaffiliated with the developer.
These images were generated directly from the game data as of July 2024. The game has not received an update in over a year, and there’s already been one sequel with another supposedly in the works, so it’s a reasonable assumption that there will be no major updates to the game that would affect the accuracy of these maps.