I promise we’re going to finally get to actual programming in this post, but first a huge aside.
When I started this project, it was 2010, and my wife had just purchased me the Star Trek Enterprise D blueprints. I was inspired. But it was an odd kind of inspiration. The kind that starts building connections into other parts of your life and making you think strange thoughts.
It began innocently enough. I noted, as I was pouring over the plans, a certain similarity to the masonry script I had written a few years prior. I was feeling the need to get back into coding, and this seemed the perfect opportunity! Just re-purpose the old code to make starship floorplans! How hard could it be?
It didn’t hurt that I had some experience making space ships from floor plans. Back in 2007, I started working on a 3D model of a spaceship based off of some bitmap floorplans designed as headquarters for a Starwars fan-fiction group. The project was never really “finished” because there was never really a goal. It was mostly motivated from “wouldn’t it be cool to have a 3d model of this whole spaceship that we’ve been writing stories about?
So I figured it wouldn’t be any trouble to have the computer build the space ships instead of doing it by hand.
It Was A Lot Of Trouble
Turns out I’m a crazy person, and the project stalled out. But not before producing what I am resurrecting in this article.
You see, I began working backward to a starting point, simplifying over and over until I had something I could wrap my brain around. The star-trek guys started with the Enterprise C, which was an iteration from the B, which was based on the A which was, from the looks of it, based off a toilet seat cover and some toilet paper rolls. A “shape first” approach. Which, when all you really need is the outside of the starship, is a fine place to begin. Sure you have the problem of having the geometry “read” properly as to scale and function, but those are problems with potential solutions, as I have been attempting to demonstrate with this series so far.
So, me being disagreeable, I decided to start at the other end. With the internals. I didn’t just want to wave my hands at the problem and say “it has space magic technology that goes “vroom” and “pew pew” when it needs to.” I wanted these ships to make real sense. The Enterprise D had a crew of 1014, but what did they all do? What was the skeleton crew? Sure, there were 4 staff on duty in the sick bay because that makes for good drama when one is a main character, two of them are holding down a patient, and the last one gets killed by the disaster of the week, but I wanted more technical answers. I wanted to be able to perform a calculation!
So I built a calculator.
Well, technically I used a giant absurdly powerful hardware calculator to run a calculator based calculator platform to run a different software calculator to iteratively program another, different, smaller, less powerful calculator. In the engineering business, they call this:
Re-inventing the Wheel
And while it’s often used with a deeply derogatory connotation, and while that connotation was probably appropriate in this case, there are certain advantages to re-inventing the wheel. Sometimes, the wheels you need just aren’t readily available! Sometimes you want to better understand the wheel instead of just buying one off the shelf! And sometimes the wheel you want to re-invent is a super-ordinate meta-wheel which, as it rolls, stamps out other smaller wheels. You also shouldn’t try to re-invent the metaphor.
Get to the Point Already!
But that’s the point, isn’t it? Once I started making a calculator for calculating how many crew cabins you would need in an arbitrary space-ship, I realized it was a very small step to making a calculator for calculating how many abstract production groups you would need in an arbitrary resource network balancing system. So I did that, and it worked fairly well.
Before further excursions into madness, I’m going to mention that rockets have a bad problem that, while not unique to them, is at least fairly uniquely bad for them, where they need to carry fuel, and the more fuel they carry, the more fuel they need. This calculator was designed to solve just this sort of iterative self-referential problem.
But then I had a further realization that if the calculator could be based on nodes, which in turn could contain other nodes, then it would be able to calculate everything. And if I could calculate everything, then I could:
Don’t you see? It’s all so elegant! The basis of a net-production network undergirds all sustainable systems, and when non-sustainable resources are given abstract trans-finite sources, one can calculate not only the spatial dimensions, but the temporal dimensions as well! N-dimensional computation would be trivial! Every problem had only to be defined as a linearized solution space! And even non-linear solutions could be approximated by a set of discrete linear segments, represented by nodes! The spatiotemporal output maps onto an effectively infinite set of implementations, allowing for style and preference, all based on a single unifying ruleset used to generate the nodes! It could:
And you could procgen game mechanics, and time itself, and minds, and stories! The possibilities!
So, that was ten years ago.
I still hope to be able to procgen everything. At some point. I’ve written in fits and starts about it from time to time, which you’re welcome to read if you like the craziness of the above.
But in the meantime, I’ve made tremendous strides, and today I am happy to announce that the calculator can very nearly handle nested nodes. I mean, it definitely works for nested nodes, but it can only solve one layer at a time, though it should be a fairly trivial to add the ability to…
Ahh, see, there I go again.
To avoid dissipating into the infinite sea of the possible, I’m going to strictly limit myself to the here and now. As in: Here is what I have right now.
The calculator is UA_Calc.py which is a Python program. I wish I had the time to go over the whole thing in depth, but you can read the code and the comments if you are interested.
It takes a specification file (Specification.txt is an example), and solves the specification, and outputs specification files of the solutions. You can then copy-paste those specifications into other specification files, and, well, you get the idea. There are a few examples of the output in that folder as well.
Although the program itself is written in Python, the specification file itself is a very simple flexible format which I made up, and which I hope is easy enough to pick up yourself.
For example, if you use this as Specification.txt:
Potted Plant -7
!Box of Pots
!Bag of Soil
then the calculator will spit out this in the “Garden.txt” file:
? generated in 3 iterations.
? Originally calculated from Specification.txt
? petals generated 35.0
? odur generated 7.0
? Soil generated 24.0
? Soil consumed -16.47
? Pot generated 10.0
? Pot consumed -7.0
? All local nodes and resources are as follows:
? Soil -15.0
? Potted Plant 7.0
? Bag of Soil 2.0
? Box of Pots 2.0
? node results for Garden complete
The details of how to write your own specification file are in the example specification file.
As you can see it can calculate anything at all, as long as that anything can be expressed as a set of nodes that produce and consume resources. I would start listing examples, but we all know where that leads.
And yes, there are a lot of things wrong with UA_Calc.py and I want to make it more robust and add error checking and all the rest, but I’ve already missed two weeks of articles fiddling with it instead of releasing it as-is. So, here’s what I propose. While I work on getting back around to exploring a few more of the visual aspects of starship design that I’d like to touch on, perhaps the more programming minded of you could suggest improvements to the calculator, and the systems minded could build specification files that result in the kind of starship content manifests that you would like to see visualized. And then, eventually, I’ll get back around to improving the calculator, and maybe we’ll make a bit faster progress together than I could working on this in spare moments snatched here and there.
I’m looking forward to reading what you come up with! Thanks for putting up with my insanity in this post. I’d really like to procgen everything, but you’re going to have to bear with me for a while. Or, you know, do it yourself.
The Disappointment Engine
No Man's Sky is a game seemingly engineered to create a cycle of anticipation and disappointment.
Push the Button!
Scenes from Half-Life 2:Episode 2, showing Gordon Freeman being a jerk.
Silent Hill 2 Plot Analysis
A long-form analysis on one of the greatest horror games ever made.
Marvel's Civil War
Team Cap or Team Iron Man? More importantly, what basis would you use for making that decision?
Mass Effect Retrospective
A novel-sized analysis of the Mass Effect series that explains where it all went wrong. Spoiler: It was long before the ending.