Search the Community
Showing results for tags 'liquid'.
Found 3 results
Hello, I probably have the solution under my nose, but have not tried the right connexion to solve this problem. Water arrives from the left and I'd like the other source from right (pump) to merge only if pipes empty. So that's a simple filler, a bridge should let the water pass, if the pipes are empty. But no, a bridge gets priority.... and the output tile of it is not empty. How to solve this?
It's been a long week with lots of sleepless nights. I think I've finally cracked liquid flow. This is my first post in a new series, from ONI University. Today we'll be studying fluid mechanics, namely the branch of hydrodynamics (liquid flow). In this post we’ll give an algorithm that perfectly predicts the horizontal flow of a single layer of liquid that lies on a horizontal flat surface. Applications of this algorithm, and multi-layer flow, will come in other posts. This post focuses solely on the algorithm, and you'll find a spreadsheet to play with as well. Perfect Prediction? Who cares? Once we understand exactly how a universe deals with liquids, we can build contraptions that utilize this. Bead pumps, waterfalls, magma pumps, and more are going to be optimized. For example, a water waterfall should hold itself through save load with a valve setting of 184.7462277, or 185 (I'll let you figure out which geometric series formula I used for this). We can optimize any contraption that utilizes moving liquid. We can explain exactly why the "Plinko Vacuum" approach only goes 7-8 tiles to the right, and predict how far left it will go with one 200kg load of water. We can optimize a design for a magma pump, similar to @Zarquan's work a few days ago. So many more contraptions can be built, with the ability to predict the future (it's what we do in real world science). Assumptions We'll decipher how the game computes liquid flow along a single tile tall horizontal solid surface (with or without walls). This means that we are restricting ourselves to the case that (1) each tile of liquid has no more than the maximum mass of the liquid. These maximum masses were recently displayed in picture form here, but you can grab them from R9MX4's Material Handbook. Hopefully all important liquid properties will soon be available in @f4rtux's ONI Database at oni-db.com. We will also assume that (2) we are in a vacuum (though the computations do not change provided any gas has an escape route that it can move to). Liquid Properties and Game Engine Notes For this model, we need to pick a liquid. The key liquid properties (from the Material Handbook) needed for horizontal flow are the following: MaxMass (Examples: MM = 740 kg for Naptha, MM=1000kg for water) Viscosity (Examples: V=30 kg for Naptha, V=125 for water) MinHorizontalFlow (Examples: MHF=10 kg for Naptha, MHF=0.01 for water) Here are a few notes before we get in. The game engine updates the liquid properties every tick (0.2s) of the game. The game performs computations iteratively, starting on the left and working right one tile at a time. All displayed values appear truncated (not rounded), so the value 2895.99999734 will appear as 2895.9 (this made finding the model somewhat tricky, but knowing this simplifies further model finding). This also means that if you manually try to add up the total liquid values, you often end up short a bit of liquid. The liquid is there, despite the actual value not being shown. The Algorithm We now examine pseudocode for the function that returns the “NewMass” of a given tile. There are 4 input variables and 2 output variables. Input Variables: CurrentMass - The current mass of the cell we are updating. MassSentLeft - The mass that the cell to the left took away, equal to the previous cell’s InflowMass.. If this value is positive, then some of the liquid from the current cell was sent left. If this value is negative, then the cell to the left sent liquid to our current cell. If the cell to the left, after its computation, does not have liquid in it, then this variable is zero. In space, liquid on the left side of the map does not flow left either, so the default value is zero. RightCellAvailable - TRUE/FALSE - If this liquid can inhabit the cell to the right, then this variable is TRUE. Otherwise, this variable is FALSE. RightMass - The mass of liquid in the cell to the right (0 if no liquid is there). Output variables NewMass - The mass of liquid for the next tick of the game. InflowMass - This is the mass of liquid that gets pulled from the next cell. This value is the input “MassSentLeft” for the cell to the right, and can be positive or negative. Heuristically, the game finds the difference between the current cell, and the cell to the right, divides this difference by 4, and sends this amount to the lower mass tile. However, this simple model (which works great for a single blob of liquid) has a few quirks addressed below. Here is the algorithm: TempMass = CurrentMass - MassSentLeft; //The mass of this cell after removing what was sent to the cell to the left. If (RightCellAvailable = FALSE) THEN RETURN NewMass=TempMass and InflowMass=0; //This cell cannot pull or push any liquid to the right. The computation is done. InflowUsingCurrent = (RightMass - CurrentMass)/4; //The mass we should pull from the cell to the right, using the current mass. InflowUsingTemp = (RightMass - CurrentMass)/4; //The mass we should pull from the cell to the right, using the temp mass. AdjustedInflowUsingTemp IF ( MassSentLeft<0 ) THEN AdjustedTempInflow = TempInflow - MassSentLeft/4; ELSE AdjustedTempInflow = TempInflow; //If the cell to the left caused our mass to increase, don’t include that mass in further computations. This keeps an increase in mass from moving more than one cell right. UseFlow IF (AdjustedInflowUsingTemp>0 AND InflowUsingCurrent<0), THEN UseFlow=FALSE (0); RETURN NewMass=TempMass and InflowMass=0; //If the cell to the left sent so much liquid to current cell that we went from having less liquid than the cell to the right to now having more liquid than the cell to right, stop. ELSE UseFlow=TRUE(1) - Continue; UnclampedFlow = whichever of AdjustedInflowUsingTemp and InflowUsingCurrent is closer to zero. The following code would give this. IF ( | AdjustedInflowUsingTemp| < |InflowUsingCurrent| ) THEN UnclampedFlow = AdjustedInflowUsingTemp; ELSE UnclampedFlow = InflowUsingCurrent; //Just make sure you grab the flow with a smaller magnitude. InflowMass IF ( UnclampedFlow < MinHorizontalFlow) THEN InflowMass = 0; //The game requires a minimum flow. ELSE IF (Unclamped Flow>Viscosity) THEN InflowMass=Viscosity; //The game has a maximum flow rate. The cell to the right will be sending this amount to the current cell. ELSE IF (UnclampedFlow<-Viscosity) THEN InflowMass = -Viscosity; //This cell will drop by the viscosity, and send the mass right. ELSE InflowMass = UnclampedFlow; NewMass = TempMass+InflowMass; Parts 5 and 6 above were the trickiest parts to decipher, as odd things can happen when you have liquids jostling around with high and low masses rapidly alternating from left to right. I’d love to have someone simplify the code above. Where is the Promised Spreadsheet? Here is a google doc spreadsheet that performs all these computations for you, showing you the intermediate computations at each stage. Make a copy of the spreadsheet if you wish to edit it. The 4:9:3 rule One simple application immediately follows from above. Drop 16kg of water on a tile. You'll see the following occur after 1 tick (0.2 s). The left most tile (with the 4 on it) grabbed one fourth of the liquid, leaving 12 kg behind. Then the middle tile sent 3 kg right (one fourth of the remaining 12kg). Liquid masses above the min horizontal flow, and below the viscosity, initially move more left than right. If you want to see some fun things, try any of these in the spread sheet: Use Naptha (MaxMass 740, Viscosity 30, Min Horizontal Flow 10) and paint between 40 and 53.3 kg. Note that what you observe means any time you drop Naptha from a liquid vent, it all flow left. If you drop it on a ledge, then it will never flow right, ever, even without a wall. If liquid pumps could be rotated, this would be a super cool feature. Any liquid with a high viscosity will have a hard time moving right. Now see if you can find the exact mass where the left side caps at 30, and then find the mass where the right side caps at 30. Then swap to a different liquid and play some more. There are a lot of cool patterns here. Look up the stats on ViscoGel, and convince yourself why it does not move left or right. At high mass, the stuff does really weird things (another post coming soon). I found an error - What can I do? Please comment below and share. I have played with Water (so PH20, SaltWater, Brine, and more), Crude, Petro, Magma, Naptha, and Liquid Gold. I've tried to break it, but can't. I'd love to fix any flaws.