Liquids and Deadlines
While most of my previous posts have been about a specific topic, today I thought I would go more true "blog" style and just detail the happenings in EXO: Perl over the past week. The main task this week was to allow planets to generate a global "sea level" and fill those seas with a liquid: two options to start, water (of course) and lava.
(Top to bottom: looking at an underwater object at night ; an artifact encased in ice [yes, I know ice is not a liquid, but it used the same system]; lava on the surface)
This is a quite limited version of the ideal (or what I often call "moonshot") system for liquids. Obviously, lakes and rivers exist not at sea level. Multiple different liquids can form features on the same planet. It would be awesome if my planets generated in such a way to allow this, but in short, liquids are hard. When the environment is designed ahead of time and cannot be edited, it's not so bad, as you can hand-draw the way the rivers move and no one can attempt to drain your ponds. But in a procedural game like EXO, an algorithm to determine the flow of liquids is needed. And not only do they flow but we also have the idea of conservation of mass (well, volume is the way we actually notice it), at least for small bodies of liquid. In Minecraft, conservation of mass is ignored, and arbitrary sources of liquid can be created, with some limitations I won't detail here. Instead, it focuses on having an easy flow algorithm. For those not familiar, a Minecraft world is a set of cubes ("blocks") in a giant grid. Each block, then, has 6 neighboring blocks. Water is a type of block, so the flow problem is reduced from arbitrary direction to choosing one of 6 options. The algorithm is more or less like this:
If there is no block below you, create water in that block.
Otherwise, create water in each of your empty horizontal neighbors.
Repeat for each water block created.
Stop if you have not moved down after 7 steps.
If such a simple algorithm can be part of the world's most purchased game, ever (at least for PC, maybe for anything?), then why can't I do something similar? Perhaps I can, but the lack of conservation of mass is a little bothersome for the feel of EXO, and two other problems exist. One, Minecraft is flat, an infinite plane with some blocks stacked on top, whereas EXO's planets are spherical. Thus, I can't just lift Minecraft's algorithm, because of difficulty defining "horizontal" and "below". However, those difficulties can be resolved by generating terrain chunks using spherical coordinates ¹ . I have considered for a while using spherical coordinates, and this was the last straw for me to swap from my previous (Cartesian) system (not that spherical doesn't come with its own set of challenges).
The other difference from Minecraft is my terrain is generated per vertex, not per cube (I discussed this in detail in a previous post). That might not matter, since each vertex still has six neighbors, but it's not totally clear whether the resulting liquid flow will be satisfactory. All of these difficulties can likely be worked through, but as I said, the point is that liquids are hard. So, the liquid system stays simple for now, because I have an upcoming deadline.
"What do you mean, deadline? You are an independent developer!" Yes, and that does not mean deadlines are not still necessary. Like most deadlines, they can be bent if necessary, but in order to eventually release something, I need motivation to take care of some of the less fun tasks. This upcoming deadline is the "moratorium on new features", which is critical to putting out my first version. In a way, it's just a switch in mindset: previously, when creating features, I often referenced or connected to systems that did not exist in game yet. For example, when making the system for trade at space stations the first time, I made the payout for trade depend on the relation the player had with the owner of station, but I didn't have ways for the player to improve or decrease their diplomatic relations. The trade feature worked, and the game ran, but the gameplay experience would be wonky if you were making less money from trade and couldn't do anything about it.
A lot of systems and features are part-finished because of the habit to reference them this way. With the moratorium, all of these unfinished systems need to be tied up and connected to existing features while avoiding creating new loose ends.
With that in mind, the liquids can't just be pretty to look at! Interacting with liquid should affect the player. Lava should damage them, water should slow them down, and the ice I added (which will perhaps be moved away from using the liquid system, for obvious reasons) should be slippery. Ideally, different points of interest should be generated under/in the liquids than elsewhere. All of these made their way into the game over the course of the week. And, of course, the player should be able to jump in them! (With proper equipment, of course.) So, I leave you with the "underwater" and "under lava" pictures.
¹ for those who deal in math, using spherical means "horizontal" is changing either φ or θ , and "below" is just decreasing ρ . In a Cartesian system, yes, I could get "horizontal" with a tangent and bitangent vector to the surface, and "vertical" with the normal vector, but my grid of points is all integers, so moving in one of those directions would not necessarily come very close to a nearby point.