We’re a new team of developers called Fiddle Earth who all share a vision for science and education-based games that are first and foremost rooted in fun. If you don’t yet know about us, we’re basically a diverse group of designers, artists, programmers and other passionate developers from around the world, working as hard as we can to bring you our first game, which we’ve named Biota, meaning “animal or plant life from a particular habitat.”
The best way to describe Biota is that it won’t be quite like anything you’ve seen before. There will be bits and pieces that might seem familiar, but overall we’re piecing together a puzzle that will break the mold. Biota will feature a bit of a dichotomy in the two integral parts that make up our game, the world and the life inhabiting it. The player will have unparalleled control over the game world itself, changing such things as temperature, currents, wind, continental drift and other things even more exciting. What the player will not have, is much control over life on the planet.
Yet, the game’s central mechanic is not only evolving life and propagating it, but also ensuring its survival, so how is this possible without directly influencing it? Simply put, we consider the game world to be our game’s MVP (after the actual player, of course!) The way the player chooses to shape the planet, will in turn shape evolution. Ultimately, because only those creatures fit to survive in the ever changing battleground will live long enough to pass on their genes. Because the planet is such a vital component to our game, we had to ensure we’d be building our world right from the ground up.
One of the things I’ve valued most on Indie DB are all the tutorials and behind-the-scenes articles that talented developers are constantly sharing for the good of the community. That’s why we thought we’d share some of our earlier progress with the community to tie the ambition with something more tangible, and help show others wanting to do similar things how we started out this journey.
We started out with a basic platform consisting of a hex sphere where we planned to have the surface topography generated and overlaid on to a tile, so that each tile would represent a quantized region.
Each tile would then have an array of its immediate neighbors, with a mesh for any tile representing a continental area, with the oceans consisting of a sphere surrounding the entire planet. This seemed like a solid approach because we could then just rotate the continental meshes around the surface of the planet to simulate continental drift. As they’re naturally higher in elevation compared to the oceans, you could then just move them around through the water without having to adjust the oceans.
Unfortunately, this approach didn’t end up panning out as some obvious issues became apparent to us the further along we went. One problem ended up being that when you’d move a chunk of tile in one direction, the overall shape of the chunk would get warped. This is caused by the coordinate system of a tiled sphere not being Euclidean.
The warping effect is illustrated below:
Instead, we decided to go in a different direction, where the continents are the curved rectangular chunks of a sphere stretched out until the shape becomes round like a ball, in other words, a “cubesphere.” The heightmap would then define the terrain, which we originally thought we might sample from to make a Unity-terrain for closer views. An immediate concern to this approach would be that unlike our former hex tiling approach, the edges of the continents might look a bit jagged. One solution we quickly brainstormed is that sinking the edges beneath the ocean might hide this from view.
An initial “cubesphere” was created:
Here, the radius is variable and you can specify the resolution, aka “number of squares” within the 6 main faces of the sphere. The idea behind this is to create a gameobject with a nodescript for each individual square, assign its four immediate neighbors, and put a terrain on it. Continents would then consist of a group of nodes all interconnected.
The highest feasible number of squares per face ended up being 100 x 100 squares. Unity’s current limit is 6500 verts per mesh, so considering that each continent would be created as its own mesh, that would make the theoretical upper limit per continent about 1600 squares.
It’s using normalized coordinates, so (0,0) means bottom left corner, and (0,1) means top left corner and so forth. This type of image is just called a UV test grid, and it’s usual for finding any errors that might have snuck into your work, such as in the following image where warping was occurring near the bottom squares that weren’t getting the proper UV coordinates:
We then figured out that we could use a noise derivative to enable us to use 8 levels of detail from a continent to a region, thereby increasing the height as we’d approach a continent and thus giving it a more realistic effect. Using quad cell trees, we would then focus on a particular mesh area, which given our plans to feature tectonic movement, also meant that we could use simple Perlin noise to get results through the coordinate system:
With these basic things taken care of, we moved on to continents, which proved immensely satisfying as a fairly straightforward “walk” algorithm acting as a mask layer, was used to create pseudo-continents:
This eventually got more exciting as we were able to accomplish coast line identification:
And using basic colors to illustrate the landmass which in the following picture is green, coast line which is cyan and oceanic plates which are blue:
This made us think that we might be able to do the entire planet as a single mesh. Up until that point, our planet’s continent copied a set of quads and built their own meshes. But going in a different direction we thought about storing the continents as node data with attached height maps. This meant that tectonic plate movement could easily be simulated, but with the caveat that it would be simulated as discrete movement rather than continuous movement. Movement would also be restricted to up, down, left and right.
Building on this, we separated the coastline by making a list of cells that surround the perimeter of the “landmass” cell. Meaning that the cells for the coastlines would correspond to places in the height map lower than normal. Eventually, we wanted to take all the heights at the coastline cells and lower them by some amount, so that the continent’s coastline would sink nicely into the ocean.
Quickly we realized that we might need to try a different approach for the oceans. Instead of making them separate objects, we tried to make each continent encompass the entire face of the cube. This also means that the height maps will also handle the height-mapping of the ocean cells that surround the actual landmasses.
In the below screenshot you can see the same coastal elevation mapping being applied to the sea cells around the continent:
This progress is no longer current, but gives you a window into the struggles of building a spherical game world when you have to account for multiple, difficult mechanics that you need to keep in mind from the beginning of your design process. We hope it might be helpful to other developers aspiring to do ambitious things with their own game worlds, and thank you for showing interest in our project.
Thanks for reading!