DwarfCorp is a RTS game about ruthless capitalism in a fantasy world. You've been hired as Regional Manager for Greybeard and Sons Company to explore and exploit new territories. As Regional Manager, you'll need to prospect the best location, and send a scouting party of dwarves in a balloon. From there, it's up to you to make sure your dwarves survive long enough to mine precious gold and mana rock. Use your profits to hire new employees and buy equipment! Only the most ruthless capitalist will prosper!

Report article RSS Feed How Water works in DwarfCorp (New Video!)

A blog post describing how the water system works in DwarfCorp, the indie fantasy RTS about ruthless capitalist Dwarves, and a new video.

Posted by CompletelyFairGames on Jun 18th, 2013

I've gotten a lot of questions about how the water system works in DwarfCorp recently, so I thought I'd write a post about it.

A dwarf reflected in water.

Simulating the Water

Water in the real world is made up of millions of tiny particles that flow past each other and form temporary atomic bonds. These little interactions between particles follow simple rules based on electrostatic repulsion and attraction. The net result of all these millions of interactions causes interesting effects from water pouring out of a cup to flowing rivers and waves in oceans. Unfortunately, modeling water at this level is still beyond reach of modern computers running in real-time. So we have to make serious simplifications to make something that looks "okay".

Like in Minecraft or Dwarf Fortress, the water in DwarfCorp is a "cellular automata" (CA) based system. A "cellular automaton" is a kind of program where cells (or in my case, voxels on the scale of about a meter) have values which are modified by simple rules. These simple rules can lead to some cool behaviors, but doesn't even come close to simulating real-world water.

CA-based water ranges from extraordinarily complex to fairly simple. In DwarfCorp, the rules are very, very simple. By just having a few of these easy rules, the engine is able to simulate lots and lots of water extremely quickly.

We store a grid of "Water Cells" for each voxel in a small "chunk" of the world. Each cell has a few bits of information: the water level (a byte from 0-255), a "flow" vector,  and the fluid type (currently just water and lava).

Each iteration, we loop through all of the water cells which have any water in them and perform the following rules:

  1. Is the water level below an "evaporation threshold" for its type? If so, subtract water from it.
  2. Check the cell below the water. If it's occupied, don't do anything else. Otherwise, if it is below maximum capacity? If so, move as much water to the cell below as possible.
  3. If any water remains from steps 1 and 2, check all adjacent cells (4-connected) in order according to direction of this cell's "flow" vector. Move a random amount of water to each of the cells until we can't move any more. The "flow" vector of each neighbor becomes the vector from the current cell to the neighbor.
  4. Set the flow vector to zero.
A waterfall.

That's it! For lava, we just move a slightly smaller amount to each adjacent cell in step 3. This leads to some pretty cool effects, like flowing rivers, waterfalls, basins which fill and empty, and underground channels. Unfortunately, the water in DwarfCorp does not currently support a pressure model (as in Dwarf Fortress), so water never moves *upward*. We're planning on adding this soon, however.

A lot of people have asked how I render the water, as opposed to simulating it. Water in DwarfCorp features reflections and refraction, waves,  subtle texturing, and shorelines. All of this is eye-candy implemented in shaders.

Rendering The Water

DwarfCorp features a realistic water simulation.

The water in DwarfCorp is rendered as a surface mesh that's generated by averaging the heights together between adjacent cells, and culling away faces that are covered by water or obstacles. If we just rendered this mesh as a textured surface, it would look okay, but we wouldn't be able to get the kind of effects you see in DwarfCorp screenshots. To do this, we use pixel and vertex shaders.

There are a few effects that are layered on top of each other in DwarfCorp:

  • Reflections - To do this, I first estimate the plane that represents the surface of the water. This is done via raycasting and averaging. (That step can lead to ugly artifacts if water is rapidly changing heights...). Then, we simulate a camera perspective below the plane. We then render the entire scene from this perspective, culling out anything below the water plane, and store this rendering in a texture. The pixel shader figures out what color to draw for the reflection by indexing into the reflection texture, and using Fresnel's Law.
  • Refraction - This is identical to reflection, except we don't put the camera below the water plane, and we render everything *below* (rather than above) the water plane.
  • Texturing - Because water with just reflections and refractions looks too perfect, we multiply in a cartoony pixel art texture to the scene.
  • Shorelines - Vertices of the water that are adjacent to empty cells get a "shore counter" incremented. The higher the "shore counter", the more of the "shore shader" is mixed into the final pixel output. The "shore shader" works by thresholding on the function "sin(t + s)" where t is the time in seconds, and s is the "shore counter", and adding an arbitrary color to the pixel when its above the threshold. The effect is a set of bands which appear and disappear over time.
  • Waves - The reflections and refractions are distorted by a normal map representing ripples in the water. Each vertex is also pushed around in the vertex shader by a sinusoidal function over time and position. The effect is water which moves widely up and down, and also has visual distortions.
  • Splashes- Particle effects and sounds are created whenever liquid of a certain type moves more than an arbitrary amount.

That's it! Here's a video of the liquid simulation system in action!

or here:
Dwarfcorp.com

You can play with a prototype of the water simulation in 2D here:
Dwarfcorp.com

Post comment Comments
ZombieJ
ZombieJ Jun 19 2013, 10:37am says:

Looks amazing, keep it up!

Glad to see water is finite, even if it is unpressurised. Having an ocean endlessly draining into a tiny pool has always looked lame in MC.

+1 vote     reply to comment
Templarfreak
Templarfreak Jun 19 2013, 12:33pm says:

Wow, cool. =)

+1 vote     reply to comment
limofs
limofs Jun 19 2013, 1:43pm says:

Would be nice if you reduce speed of lava, then game might have additional functionality, like traps

+1 vote     reply to comment
*Flame*
*Flame* Jun 19 2013, 5:55pm says:

<3 Epic , Tracking

+1 vote     reply to comment
Tajin
Tajin Jun 20 2013, 5:10am says:

Very nice, but that "splash"-effect looks weird. Maybe use a fine dust for it and more transparency. The current one looks like snow or feathers.

+1 vote     reply to comment
Post a Comment
click to sign in

You are not logged in, your comment will be anonymous unless you join the community today (totally free - or sign in with your social account on the right) which we encourage all contributors to do.

2000 characters limit; HTML formatting and smileys are not supported - text only

Icon
DwarfCorp
Platform
Windows
Developed By
CompletelyFairGames
Engine
XNA
Contact
Send Message
Official Page
Dwarfcorp.com
Release Date
TBD
Game Watch
Track this game
News
Browse
News
Report Abuse
Report article
Related Games
DwarfCorp
DwarfCorp Indie Single Player Real Time Strategy
Related Engines
XNA
XNA Public Domain Released Dec 31, 2006