Site Logo

loucraft - fluid simulation in Minecraft

Posted on

I’ve always been drawn to coding Minecraft clones. (I mean, ever since playing it, circa 2010.)

It feels like the perfect sweet spot for a good technical challenge.
Plus, every “improvement” on the original game seems like the greatest idea.

This is the story of one of those delusions.

Context

In summer 2020, I live-coded on Twitch a minimal version of a Minecraft clone inside Unreal Engine 4.
This was quite fun!

In less than a week, we had:

  • a naive voxel mesh generator
  • some noise-based world generation
  • the ability to place and break blocks
  • a basic character to experience it all

A solid base, I would say.
I had no plan to turn it into a real game, but I still wanted to keep toying with it.

So I embarked on the ambitious journey of fluid simulation.

Here is a little preview of the final result:


Assembling the team

Making the base of “your first cube-based game” is actually quite fast and easy once you understand the fundamentals.
But fluid simulation? That’s a whole other beast.
I knew nothing about fluid mechanics. I needed help.

Luckily, my good friend Rémi was a PhD student in fluid mechanics at the time (now a full-fledged doctor 🎉).
Perfect timing.
So I reached out, and he generously agreed to help me with my ridiculous project.

You should check out Rémi’s games !

Okay, everyone is here — let’s get to work!


Technical difficulties

Flow

Our first approach was to give each cell a single velocity vector.

As you can see, it took several steps for water to spread in multiple directions.
I didn’t like that.

Next, we tried computing a momentum flux per cell face.


That was more what I had in mind, so we kept it.

Pressure

Early on, I wanted some kind of pressure-like behavior.
(Skipping over a lot of trial and error…)

We ended up with a hidden pressure value per cell that would propagate over time.
Not the most realistic choice — but I think it gave the best results.


Playing around

Alright, everything kinda works — time to have some fun!

Stress test

Let’s drop a ridiculous amount of water on the world and see what breaks.


Not perfect, but not bad.
Looking back on it now (5 years later), I’m not thrilled with the performance — but hey.

The shape of water

I then tried fancier mesh generation by averaging the water quantity at each cell corner.

I liked the look — but not so much how it hid the true water content per cell.
It even caused me to miss an instability bug for a while.
Eventually, I switched back to the blocky version for clarity.

Going with the flow

I then made it so the water could push the player, relative to the flow —
which obviously meant: I had to build a waterslide to test it.


Weeeeeeeeee!


Turning it all into a game?

At some point, I started wondering what kind of game could truly take advantage of this system.

There are already plenty of god-style sandbox games with fluid sims, but I wanted something more human-scale.

Introducing: the magic crystals!

By placing these special blocks, the player could create various types of currents.

Here are the ones I implemented:
(Names subject to change)

The Sink Stone

Pulls the water all around it.
Useful to build water sculptures, I guess.


The Prophet’s Stone

Pushes the water away.
You could build underwater bases with that!


The Jet Stone

Makes a simple current.
When you need to steal some water from the ocean for your swimming pool.

The Vortex Stone

Creates a whirlpool.
To wash your clothes or something, I don’t know.


Conclusion

I had a lot of fun, and learned a ton.

But…

This took months — way more than I expected.
Of course, self-education and entertainment are nice, but nothing more came out of this.

I didn’t turn this into a game.
I mean, I didn’t even plan to in the first place — and I was never confident it could be achievable.

And yet, I didn’t want to stop.
I was stuck in that awful mental space where you can’t continue, but also can’t stop.

When I finally did stop coding, I tried to capitalize on all this work by making a YouTube video.
But I’m not great at making videos — and not even sure I enjoy it.
By that point, I was mostly driven by sunk cost fallacy.
Eventually, I aborted that too.


So what went wrong?

  1. Unreal Engine 4 was too heavy for me. (Still is.)
    These days, I make my games “from scratch”, building a little specific engine alongside the game.
    UE4’s long build times and convoluted nature made it difficult for me to comfortably iterate on the simulation and tooling.

  2. I didn’t set up the collaboration with Rémi properly.
    I should have studied way more before diving in.
    Instead, I kept trying things I didn’t fully grasp, hitting walls and coming back to him with new random uninformed questions.
    That turned him into a bottleneck and left me in the dark — not great for either of us.

  3. I failed at project management.
    I started without a clear direction, without enough fuel to reach anywhere meaningful, and no defined stopping point.
    I should have at least formulated a plausible exit plan so I could quit cleanly at any point — and not get stuck like that.


Still, even failures like this are valuable learning experiences.
I wouldn’t say the journey was worthless — and hey, I’ve got some cool fluid sim videos to show now.