A "falling-sand game" is a game where every pixel is simulated. The player can interact with the world by placing or removing different material within the world. By using logic simular to cellular automata you can create moving worlds with only simple rules. My goal for this project was to create a easy to use and build upon with three different state of matter which all get affected by other elements in different ways.
My main source of inspiration is, one of my favorite games, Noita. They use the same simulated world with simple rules to build a much larger and complex game.
Every element in this simulation uses the three different states of matter as a base.
The different states comes with predefined behavior can be modified per element basis if needed.
Solids come in two forms, non-movable and movable.
Non-movable solids are very simple, they don't move. Not much more than that.
Movable solids moves downwards with gravity. If it touches the ground it will look diagonally to see if it can continue falling, otherwise it stops.
Solids have different inertial resistance causing them to stack differently.
Fluids works like solids but they can also disperse to the side. A unique attribute to fluids is their disperstion rate, a higher dispersion rate causes the fluids to flow faster.
Fluids have different dispersion rates causing them to spread out faster.
Compared to solids and fluids, gas moves upwards while wandering a little bit to the side. Gases are either produced by burning flammable elements or boiling fluids.
Gas rising.
Gas being generated from water and oil.
Every element has an internal temperature and reacts accordingly. If water gets warm it evaporates into steam which in turn can condense and turn into water once more.
If flammable material gets warm they ignite and spread the fire to its neighbors.
The different elements also use density as a way to sort themselves. Oil has lower density compared to water so it will lay on bodies of water.
Solids that are resting don't continuously check if they can fall diagonally. However, when a falling element comes in to contact with a resting material it reacts and starts the falling process again, causing an avalanche like effect.
One problem I got stuck on for a long time was when i was updating the whole map. Because I used a large array for the map whenever I iterated through it would update objects twice and cause a huge bias towards moving to the left.
I fixed this by ensuring that no element gets updated twice and whenever a objects want to move it picks it's direction randomly and uses the previous result to balance out the directions overtime.
Before.
After.
Another problem I had was when I was implementing fluid dispersion. Since it causes fluids to move multiple positions within the grid that meant they could go through walls. So I made a function for traversing the grid by returning the last valid position.
Before.
After.
I really enjoyed working on this project and I think my end result is in a good state given the limited time frame. During the first three weeks everything flowed very smoothly, up until I encountered the "left bias" problem which halted my week plan I had setup for myself. After spitballing with other classmates and educators it led me to try new ideas to solve the problem. Overcoming this obstacle got me back to producing new features and interactions which was my favorite part of this project.
There are still many things I would like to add, such as:
In the future I could see myself recreating this project with a larger scope using my own custom-made engine instead. One improvement I would make is to change so that instead of every element residing within a large array, the world would be comprised of smaller grids to allow the world to be larger than the screen.