Jump to content

Liquid Shenanigans: How do they work?


Recommended Posts

I'm talking about bead pumps and the like.

Recently I've been seeing some really clever stuff like this and this and I'm wondering how one goes about designing something like this without resorting to trial and error.  I understand that you can manipulate how much fluid is in/flowing through a tile by manipulating things like fluid pressure and accounting for viscosity, but are any formulas known for these mechanics?  The pressure I believe is well known, but I don't know about any formulas for viscosity and fluid spread, which I believe would also dictate the behavior of bead pumps and waterfalls and such.

I've tried searching the wiki, the forums, the subreddit, and the internet at large and I've not had any real luck.  If there's a post about this, I don't know what keywords to plug into the search engines to find it.  I even went looking through the game code to see if I could find the algorithm (I actually did this first, because there's nothing better than up-to-date first-hand knowledge), but stopped when I figured out that it was probably in SimDLL (a native library which could be decompiled in theory but would kinda suck to do in practice).  It seems like some of the people here know some details about liquid flow mechanics so I imagine that someone had figured at least some of it out at some point in time.

Can anyone point me in the right direction?

Link to comment
Share on other sites

1 hour ago, Zistack said:

Can anyone point me in the right direction?

Start here:

 

1 hour ago, Zistack said:

a native library which could be decompiled in theory but would kinda suck to do in practice

You can decompile the Assembly-CSharp.dll pretty easily with dotPeek or dnSpy and take a look at the code in general.

Link to comment
Share on other sites

8 minutes ago, Rocoto said:

Start here:

Will do.

 

5 minutes ago, Rocoto said:

You can decompile the Assembly-CSharp.dll pretty easily with dotPeek or dnSpy and take a look at the code in general.

That's what I meant when I said I went looking through the game code.  The actual fluid simulation code appears to be in a shared library called SimDLL (exact filename varies by platform - on Linux it is libSimDLL.so).  It would require a different sort of decompiler since it is almost certainly written in C/C++ rather than in C#.

Link to comment
Share on other sites

Actually, reading that post and seeing the reference to the post on heat transfer, I see that delving into SimDLL is perhaps reasonable - a detail that I hadn't really picked up on before (I've read the heat transfer post itself many times, of course).  How bad is it in there, @Yothiel?  What decompiler did you use?

Link to comment
Share on other sites

The magma pump in the post above  is using visco gel as the fluid to trigger the pump. That doesn't obey normal fluid rules since it stacks vertically instead of spreading out.


Never seem the example from the volcano tamer before that post so can't provide any information on that.

The only thing I have used bead pumps for in the past has been forcing gases up a narrow gap. I have seen it used to force lower density liquids upwards as well.

Link to comment
Share on other sites

Liquid properties can be found in \OxygenNotIncluded\OxygenNotIncluded_Data\StreamingAssets\elements\liquid.yaml. Flow rates and such.

DefaultMass in solid.yaml determines whether freezing liquid forms as debris or a solid tile, 80% is the trigger point. Niobium for example has a very low defaultMass which creates the need for the trickery in the linked post. Presumably this was an unintended consequence of making niobium, fullerene, and isoresin rare in map generation (they all share abnormally low defaultMass). One does wonder why a niobium volcano outputs sooo much of a supposedly rare resource, but hey ho.

Link to comment
Share on other sites

You can learn a lot from experiments, too. Here's how minvertflow is applied in liquids when both compressing and flowing normally. Please share what you learn from code diving. I would be interested to learn if viscosity is used at all in vertical flow.

Of course, viscogel obeys normal liquid flow rules, it just has unique values for viscosity and minflows.

Link to comment
Share on other sites

On 1/12/2021 at 6:35 PM, Zistack said:

I've tried searching the wiki, the forums, the subreddit, and the internet at large and I've not had any real luck.

Honestly, the wiki should have a page on fluid/gas flow, but doesn't. You could take some initiative and start one. I'm thinking something like the thermal conductivity page (https://oxygennotincluded.gamepedia.com/Thermal_Conductivity)

 

Link to comment
Share on other sites

@nakomaru: Code diving has not gone well.  It is written in C++, and decompilers only really understand C binaries.  The lack of debug symbols was expected, but the extra complexity of dealing with inlined STL code everywhere and no C++ standard type database makes reverse-engineering the meaning of the game-specific structures way more difficult than it should be.  I might try again at some point once I figure out how to get a plugin that can help with the C++ part.  If anyone else has previously dived in there and had any level of success, I would appreciate any knowledge that they could share with me.

@Rocoto: I did find the ONI University post which contained a variety of helpful links.  It would appear that, at least for liquids, something like 90% of the behaviors are all pretty much understood.  It doesn't look like gasses are as well understood, though.  I also hear the gasses are a bit more buggy, which doesn't help.

@ghkbrew: The wiki idea isn't the worst.  There's some other stuff that I've been thinking of putting up there as well, like the amount of time various recipes or dupe actions take (I've dug a lot of that out from the C# code already, among other useful things).

Link to comment
Share on other sites

On 1/12/2021 at 4:35 PM, Zistack said:

I've tried searching the wiki, the forums, the subreddit, and the internet at large

Using the search string "site:forums.kleientertainment.com" in combination with anything else you are looking for can yield quite a bit. My guess is you've eventually stumbled on most things that are known (I try to include lots of references in my posts).  I spent a great deal of time with liquid flow, and @TripleM999 basically completely cracked gas flow in the post above.  There are some interesting interactions with convection in liquid that I have seen briefly displayed, but I don't know about numbers. You can get heat to move upwards really quickly in liquid... I spent most of my time with material flow, not heat flow. If you haven't yet studied partial melting/evaporation (flaking), make sure you get a good education on those before you start trying to optimize contraptions. 

I look forward to seeing what you discover. 

Link to comment
Share on other sites

@gabberworld: The issue isn't that I can't read assembly or even decompile the program to C.  The problem is that, because the library wasn't compiled with debug symbols, none of the variables have meaningful names of any kind, and all structure information is completely lost.  In order to actually make any sense of the code, you have to have some idea of what memory locations are actually being used for what purpose.  Decompilers typically allow you to annotate code with type information and more informative variable names to assist you in recovering these associations and making sense of the code.  They also are typically aware of standard C library functions and types, and will automatically annotate the decompiled code with that information for you, so that you can focus on reverse-engineering the application code rather than waste a bunch of time on boiler-plate.

The reason that the library being written in C++ confounds things is that these decompilers typically don't have a database with standard C++ functions and types, and C++ compilers like to inline things a lot, especially template code (which the C++ standard library is almost entirely comprised of).  This means that I have to reverse-engineer the various uses of the C++ standard library in order to get to the actual algorithms being used by the game.  Additionally, if the program itself uses classes, there's a lot of under-the-hood stuff that goes on to make classes work that the decompiler is completely oblivious to, like vtables, that I have no good ways of reducing into more readable class definitions.  This really sucks, and consumes an enormous amount of time and effort.  There are plugins that supposedly address these issues in the decompiler I'm using, and I'm looking into them.

I'm not sure how @Yothiel was able to extract the heat equations, though it looked like the methods for calculating that stuff were smaller and more self-contained than the liquid- and gas-flow methods to me, which might be a factor.  I might have a little more luck now that I've read about the mechanics as understood so far, since that'll give me an idea of what the algorithms should look like in the code.

Link to comment
Share on other sites

@FIXBUGFIXBUGFIX: Thanks for sharing.  That message is very informative, but sadly a lot less helpful than I was hoping it would be.  I'm impressed that @Yothiel had the patience to perform that sort of manual reverse-engineering from raw assembly, though I can definitely see how the debugger would have helped a lot.

I'm using ghidra, and I'm looking to use OOAnalyzer (there is a ghidra plugin that wraps it) to save time on the C++ stuff.  These are somewhat more powerful tools than the disassembler that Yothiel was using, so I ought to be able to move pretty quickly once I get a foothold on the codebase.

Mostly, I haven't gotten very far because I was in the middle of working on some heat exchanger design formulas when I started looking at this stuff, and I haven't quite finished that up yet (I'll be posting on the forums about it once I'm done, of course).  Once I do, I'll be able to focus on this some more.

Link to comment
Share on other sites

Heya @Zistack, sorry for the late reply, though FIXBUGFIXBUGFIX kind of answered in my stead!

It looks like you're better equipped than I was at the time. The beginning of my quest was really just about throwing myself at the disassembly and blindly looking for heat-related functions. At the time, I specifically search for processor instructions doing min/max on float numbers (since I expected conductivity values to go through such instructions) and looked for other operations typical of heat equations (like multiplying a presumed conductivity by a delta of presumed temperatures to get a heat energy flow).

As mentionned by gabberworld, you have access to the PDB for simDLL, which that Ghidra tool is able to retrieve symbol names from. I've done a quick try and could for instance find functions called "DisplaceLiquid" or "DoLiquidPressureDisplacement", which seems to be the kind of stuff you're looking for.

At this point, there's little more my previous experience can provide. It looks like there is more "C++-specific" stuff in the code than before, which probably is bad news for decompiling (both manual and automatic). At least, you won't have to use a notepad like I did for taking notes / replacing variable names.

Anyway, good luck to you! I'm looking forward the answers you'll bring to the community on the topic of fluids!

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

Please be aware that the content of this thread may be outdated and no longer applicable.

×
  • Create New...