Better Fluid Storage

A while back, I posted a prototype fluid storage system with a mechanic for handling breaches in a pressurized system. I thought I’d be clever by storing fluids as a percentage of a defined volume and pressure. For a “simplified” system, it was quite complicated, and fundamentally flawed.

This time, it is straightforward. Keep track of the amounts of each fluid, a total sum, and volume of the container. Pressure is the sum divided by the volume, and the percent of a fluid is its amount divided by the total sum of all fluids.

tank = {
  volume: 200, sum: 300,
  contents: { hydrogen: 200, oxygen: 100 }
}
pressure = tank.sum / tank.volume -- 1.5
percent_hydrogen = tank.contents.hydrogen / tank.sum -- 0.67

Everything needed from a container can be accessed immediately or with a single calculation involving only two variables.

But what about hull breaches?

Fluids vs Mechanical Classes

I realized that I should define fluid containers very narrowly, all they need care about is a small set of numbers, and have a few functions to modify that state. Enter the Breach class.

Breach(fluidA, fluidB, volume)

Specify which fluid containers are interacting and the volume ( I guess technically it should be area) of the breach. Each update cycle moves the pressure difference multiplied by the volume (area) of the breach from the higher pressure container to the lower pressure container.

What about pumps? I have those, with a “volume” and a “rate” modifier to allow you to adjust how fast the pump works. Pumps only work in one direction, but have a function to reverse them.

Want only one fluid to go through..say, a filter? Made that as well. Valves, so that you can adjust flow rate, filter-pump combos for pushing just the right amount of one fluid, and one-way valves to allow pressure to escape but not allow any blowback.

The Flaws

  • Once pressure is equalized, contents do not mix between fluids.
  • All fluids have the same density. This probably isn’t that hard to fix, but is unneeded for my purposes.
  • All fluids mix. This may or may not be harder to fix depending on how it is approached.
  • Temperature isn’t simulated at all. I would love to have heat transfer and heat affecting density, but these details are not necessary for my current project.

The Code

As of publishing this article, I don’t have a library to give you, but I will update it as soon as I do release it. For now, here is where I have the beginnings of a library. No matter what, I can promise it will be available by the end of April (or upon request).

Simplified Fluid Storage System

One of my game ideas involves constructing 2D spaceships, and the concept of a simplified system for storing fuel, oxygen, water – really any kind of fluid mixture – in storage tanks. Along with this, it allows simulating breaches between containers, hard vacuum, and the pressurized areas of the ship itself!

{ -- a rough approximation of Earth's atmosphere
  pressure: 1
  volume: 4.2e12 -- 4.2 billion km^3
  contents: {
    nitrogen: 0.775
    oxygen: 0.21
    argon: 0.01
    co2: 0.005
  }
}

{ -- hard vacuum
  pressure: 0
  volume: math.huge -- infinity
  -- the contents table will end up containing negative infinity of anything that leaks into the vacuum
}

It all comes down to storing a total pressure and volume per container, and a table of contents as percentages of the total mixture. The total amount of mass in the system can be easily calculated (volume * pressure), as can the amount of any item in the system ( volume * pressure * percent).

Breaches are stored as a reference in the container with a higher pressure, and a size value is added to the container with lower pressure (representing the size of the hole between them).

Limitations

  • Everything has the same density and mixes evenly.
  • There are no states of matter, everything is treated as a gas.
  • Attempting to directly modify the amount of a fluid is prone to floating-point errors it seems, while mixing containers via the breach mechanic is working as expected.

The code was written in MoonScript / Lua and is available here.

Realistic Star Frequencies/Colors

UPDATE: A much better resource for frequencies of types of stars is on this wiki page for Elite: Dangerous.

I’ve done a lot of research on stellar classification, perhaps too much. Here’s a visual representation (not at all to scale!) of stars by type from O to L.. and L is a brown dwarf, so it’s not technically a “star” per say.

Stars by type, in order: OBAFGKML

And here’s a table of those color values (in percents RGBA):

  O: {0.521, 0.521, 0.996, 1}
  B: {0.701, 0.898, 1, 1}
  A: {1, 1, 1, 1}
  F: {1, 0.996, 0.780, 1}
  G: {0.988, 0.972, 0.250, 1}
  K: {0.905, 0.549, 0.015, 1}
  M: {0.847, 0.011, 0.031, 1}
  L: {0.302, 0.187, 0.177, 1}

As for the frequencies (as in, percent of stars that are a specific type), they have been slightly manipulated (if I am remembering correctly) to make the rarest types a little more common, but are based on my best guesses from research:

  O: 0.00003
  B: 0.13
  A: 0.6
  F: 3
  G: 7.6
  K: 12.1
  M: 76.45
  L: 0.11

A couple last notes:

  • There are two more brown dwarf / substellar mass classifications I could be using (T and Y), but I am not because they are not commonly visible.
  • Because L-type (and T & Y) “stars” are so hard to see, it is entirely possible they could outweigh the existence of other types, but we just can’t see them!

Code to create the image above is available here.

A Years’ Late Post-Mortem (LD34)

Opcode-Powered Shuttle at the end of LD34

The Beginning

Suddenly it was time. I didn’t plan or prepare, I hadn’t coded in a little while. I decided the jam would jolt me back into coding, I also livestreamed most of my development to force me to keep working at it.

The Story

The first evening and morning worked great (Ludum Dare starts at 6pm in my timezone). A few hours on the idea, several more designing the controls (in retrospect, I spent too much time deciding on the structure of the opcodes). At some point, I hand-drew graphics, but threw them out because I could not get my scanner working.

I built the graphics for a few things, started placing them in-game, and decided I needed to rewrite everything. I quit streaming, took a laptop out to a Starbucks, and spent a few hours doing just that. It was a good break, good exercise (cycling a few miles), but wasted a lot of time.

The 2nd evening involved more streaming, things moving and generating.. Now for the game part, the 2nd morning, I didn’t stream because I was fully in crunch-time-mode over the last few hours. I focused on a communications system (which was broken, badly coded, and led to me releasing a game-crashing bug).

The Result

I decided to make something with a huge scope. All my time went into working on UI components and controls. There is no game, but a few mechanics to build a game within.

Positives? I got back into coding for a bit, I got to check out a lot of others’ games because I made sure to rate a bunch of them, and I felt more on track with my life.

It did burn me out though, so much so that it took a long time to write anything about it.. and even longer to actually publish it!


Want to play it? Click here.

Thinking in Orders of Magnitude

I am obsessed with creating a game inspired by the likes of Elite, Space Trader, and No Man’s Sky – all about exploration, trading, mining, combat, etc, and in space. I have given up on trying to be very realistic in terms of celestial masses, sizes, and distances – it’s too much for me to handle on my own – but I still want an approximation of this.

One of the problems with this is simply trying to keep track of huge numbers in mind. (Was my “average” planet 107kg or 108kg?) In an attempt to classify and simplify, I ended up creating a chart that sorts objects into 5 broad classes with 5 size-based subclasses within each.

It also conveniently solves a problem I had with trying to keep track of the relative sizes of small planets and large moons, and tiny moons compared to generation ships. There’s a lot of potential overlap between these classes of objects, which is clearly demonstrated. It’s also very nice for setting up orders of magnitude to generate mass or radius values within.

There is a lot of simplification in what I’ve done already, but there is more to be done before I even have a prototype to play with. Perhaps I’ll make a seed-based toy for generating and exploring systems from an overview as the next step.