MaxBittker / sandspiel

Creative cellular automata browser game
https://sandspiel.club
MIT License
2.97k stars 199 forks source link

Particle fluid pressure system idea #253

Open Charlieee1 opened 1 year ago

Charlieee1 commented 1 year ago

It would be cool if particles exerted pressure on each other. For example, water in two basins, connected by a gap in a wall, would eventually level out to the same level. Different materials could have different pressure thresholds (ie, water is 0, rock is higher, wall is infinite). If the pressure on a particle exceeds the pressure threshold of the material of the particle, it will be forced away. Pressure can propagate through particles from each other. For example, a particle applies n+1 pressure to the particle below, where n is the pressure on that particle. It will apply n-1 pressure to the particle above. It will apply n pressure to a particle beside it. Each particle (cell in the code) would need another value, called pressure. I'm not sure if this would conflict with the core idea of the simulation.

Charlieee1 commented 1 year ago

Actually, I forgot about something. The pressure threshold would be for particles that are attracted to same-species particles, so it would simulate rock cracking under enough pressure. If the particle is not connected to another same-species particle, it will not have pressure threshold rules applied to it.

labbo-lab commented 1 year ago

Love this idea! (Especially the water pressure)

I don't think the pressure could be stored when posting (though the alpha channel is still available I think 👀), but it might be possible to have it as a separate thing

Charlieee1 commented 1 year ago

I forgot about that. The particles would have to store four different pressure values (up, down, left, right). By having four different values, the particle will know which way to push. The pressure would propagate a little different than previously described. Water would, for example, distribute the pressure from above in all directions, whereas rock would only propagate it in the opposite direction from where it comes.

In the water basin example above, the water at the top layer in the emptier basin would be pressured from below, and therefore would move up. The water directly below it would also be moved up, and so forth until there is no pressure on the top layer. I don't know how to implement it to ignore gravity (as the top layer water would try falling back down once it moved up). I don't know the order in which the particles are updated.

Let's say there is a wall of rock, and water on one side. Let's say the water is enough to create enough pressure at the bottom to surpass the pressure threshold of the rock. The rock will propagate pressure sideways (not up or down, according to the first paragraph), and the rock particles on the other side of the wall will be forced away (note that the rock particles above will not be forced away, because the pressure threshold is not exceeded, thus they "stick" to the other particles of rock). The next particles will be forced away similarly, and so on and so forth until the water can flow out from where it was trapped.

A little detail on the implementation of the pressure system outlined in the first paragraph. When a particle gets updated (update function is run), it will check its neighbours pressure levels (right pressure level for particle to the left, downwards pressure level for particle on top, etc.), and run the calculations as follows:

  1. Calculate the pressure the particle would exert in all directions, as follows:
    • Denote the pressures in each direction up_p, down_p, left_p, right_p and initialize all at 0
    • If water (or similar material), the pressure from above is added to down_p, left_p and right_p. If rock (or similar material), the pressure from above is added to down_p
    • If water, repeat the step above for water, but for each of the other directions. The pressure should propagate to all other sides. If rock, the pressure goes through the particle to the opposite side.
    • Add 1 to the pressure below (or can change if you're implementing so different particles have different weights), and subtract 1 to the pressure above (can change based on weights, and add check to prevent negative pressures)
  2. Now set the final pressure values to the pressure values calculated above.
  3. Move particles in correct directions if necessary. Tell me if I missed anything!