Devlog 3: Water system 3/3: visual effects


As I declared before, I aim to create a game that will run on any machine, no matter how old and slow it is. And that doesn't go easy with the simulation of liquids - they are really complicated, and a full simulation still requires a supercomputer. So, to optimise the game from the beginning, I’m looking for approaches that don't require in-time calculation, in other words, I’m using pre-calculation whenever it’s possible.

That’s why for graphical indication of currents I want to try using just a bunch of textures, that will cycle and create backed animation. Also, the mesh of the panel can be just deformed according to the shape of the water (water “terrain”). In general, it works like this:

So, in Update we’re just changing textures now. This should be the most optimal solution, let me know if you think differently! 

And since we just need a set of textures for each file, I think that I will do it in Python, together with analysing the raw arrow images. The algorithm is simple - we can go over the matrix, and analyse direction, curve (by direction of surrounding cells) and force, and based on this generate an image, or to be more accurate, a set of images, that will do animation while cycling over. But with many things, the difficulty is in the details – specifically how to make this look nice.

I decided to split images into categories, and for each draw animation using mathematical functions. For this probably the best library is Matplotlib. I worked with it before, and I can tell you that you can do literally everything with it (but for some reason for real graphs I still prefer R’s ggplot2 😆). For the convenience of prototyping, I decided to focus on one tile and draw it into an animated image. For some random reason standard solutions for creating html5 videos didn’t work in my Jupyter, so I did a custom solution – save the image as a gif, and load it to Jupyter. A positive side is that I can share pictures with you right away! E.g. here is the first iteration of the mild current (a cos function):

Well, I actually spent a lot of time at this point 😅 (hard to call it the first iteration)

For understanding how the procedural generation works, here are combined frames:

And here is animation for strong and weak currents:

And finally, by moving each element according to the grid, deciding what form to draw based on the force, and applying rotation, we have a set of images for animation!

Here is a gif next to a debug map. For now, force is indicated only by shape. Also drawing lines strictly on the grid (later I want to try to draw them more interesting). In my opinion, at least random shifts make the resulting animation look nice.

So, this part is done! For now, let’s stop on this. Since I don’t know whether I will keep the grid system, or if I will decide to create something way different, it would just not be rational to spend more time before a lot of playtests. And now we finally have the visualisation of the currents. When I feel ready to improve the system, all the scripts should be easy to adjust (at least I tried to structure them the way I like).

Once again, I want to remind you of the main driving point of my dev decisions here – optimization.  This cartoon-like animation is clearly visible, yet demanding only for RAM usage, which should not be a problem since low-poly surroundings are supposed to be lightweight. And the thing I like most is that the animation is baked – the animation should be the same on every device. And don't get confused with current grid-based animation. Firstly, I am planning to make it less boring, by combining several grids (making more complex patterns of animation generation). Secondly – this is only for low settings! The high graphic setting will be improved later – they need to correspond with fundamental decisions that are needed for optimization.

Assembling it all together!

With working currents, deformation of mesh and animation, and also new bumped surface water, we finally have all the water parts! Right before redoing the demo level, I only spend some time cleaning the code and file structure. Now, we have a prefab of the current, and a clear structure in files – a folder for each current, with one json file, one debug texture and a set of textures for animation, saved in a folder. Also, the Python scripts are also generating files according to this structure. I added an inspector-helper-function, so now I can click one button to load all the textures into the object (only need to specify the name of the folder). Another function sets scale and generates a template texture, with a proper size for the new current. The painting of textures for now is kept outside Unity - the raw editing I do in Paint, then I draw proper arrows and run all the scripts. I mean, I tested several tools for in-editor drawing, but I don’t like them at all. Once again, the perfectionist inside me screams in agony about the inconvenience and quality of the code, but rationally speaking I did a proper tools set for the beginning.

It’s already truly a big piece of work that I covered in this devlog. So, now I will only tease you with the reworked version of the first rapid, and I will continue my work. Stay strong!

P.S. The next step is the public demo... 🤞

Get To the Rapids!

Leave a comment

Log in with itch.io to leave a comment.