Rolling Dice

Between working on Galactic Impact the first time in the late 20-aughts and today, I’ve done a lot more board gaming than video gaming, and that’s also where the bulk of my ‘game design’ brain has been. Comparing that world with video games is an interesting exercise, especially because there’s a lot of conversation about “app integrations” on the board game front these days.

This all came to mind as I was dove in to rebuilding “population growth” for Player’s “Worlds” in Galactic Impact. In the old version I did a blanket percentage growth calculation — for example, if the target was 1% growth, multiply the population by 1.01, save that as a the new population and call it a day. Got the job done, but was completely deterministic, which is somewhat unrealistic for population growth. (Also unrealistic when using that same calculation to determine the numbrer of deaths on account of hostile atmospheres).

Board games use dice as a primary way to generate random values, so I wondered if something similar would be feasible here, on a larger scale. For a lark, I tapped out one of Ruby’s shorthands for generating a whole slew of random numbers. Specifically, 100 values between 1 and 100:

Array.new(100) { rand(1..100) }

This spat out a nice looking list of numbers, but I was worried about how sustainable this would be for larger volumes of values. I checked the current US Population growth rate (0.6%) and used that as a baseline, but converted it to “permille“, so I would have a whole number (6) to work with, then took a look at the size of Ships I had created, to see what kind of population a new Outworld might have during its first update phase. A mid-size ship was 2500 people, so I ran the following:

Array.new(2500) {rand(0..999)}

This is a little bit (a lot bit) like rolling a 1000-sided die for each ‘person’ on the planet. If we decided that the permille growth is “6”, we can increase population for every ‘person’ who rolled a 994 (1000-6) or higher. Also easy to pull the deaths with this, if we say the “death rate” on a planet with no atmosphere (like the moon) is 7‰, any ‘person’ who rolled less than 7 is killed off. No longer deterministic! At some point, the law of averages will mush all these outcomes together, so if there are performance issues at higher population counts, I can address that, but I did some quick benchmarking and this method is (I think) fast enough in Ruby up to at least 1 million die rolls… in tabletop terms: 1,000,000d1000!

Now I’m left trying to picture what that would look like to roll a million dice at once on Board Game Night 😜

Evolving 4X Terminology

It’s a core belief of mine that language is important — after all, if you and a listener don’t have a common language of some kind, you can’t communicate — so as I’ve been rebuilding Galactic Impact, I keep being struck by the word “Colony” everywhere in this type of game (Sending Colonists to another world… to Colonize that world when they arrive…).

Without doubt, the term is common parlance when we talk about setting up permanent human habitation on worlds in outer space, “a Moon colony”, “a Mars colony”, and beyond. In fact, NASA has entire articles about it. But in reality it’s a term rooted in a really horrific period of human history. It doesn’t often get this framing in History classes in the U.S., but Colonialism was a seriously fucked up era when entitled European empires showed up on foreign shores to kill, loot, and occupy as they saw fit. These actions redrew the map and world affairs in ways that are still visible four hundred years later, and lots of people around the world are still experiencing the negative downstream effects.

Since my main objective is fo Galactic Impact to be a fun game for the most number of people I can hope to entertain, I don’t want to be using language that calls back to that history. And just maybe, by making an intentional change, others may reconsider language in the entire 4X genre, or at least think twice about it.

To help me out with finding suitable replacements, I reached out to an internet buddy of mine, Calvin Wong Tze Loon (@ithayla on Twitter), who I know cares deeply about these issues, and is an English Language Nerd to rival my own. After some back and forth, he suggested that Outpost could be a suitable alternative. Which I think is a super cool option. It also sparked the term “Outworld” which could be a rad way to describe both smaller Outposts and larger, more highly populous Capitals or similar.

Does making this change in this game really cause a dent in the overall course of the universe? Probably not. But I really don’t see how it can hurt to remove the language of oppression from our entertainment spaces.

Template tags and partials

So the first big difference I’m running into between the Old Way (Django) and the New Way (Rails), is that Django uses a templating tool like handlebars or mustache (I’m not sure how to tell which from what I’m seeing in the code here), which has the nice effect of really forcing the developer to separate the logic from the view.

Note: Django’s pattern looks more like Model-View-Template in practice, because what a Raisld eveloper would call a Controller, Django calls a “View” which then renders a template, rather than a Rails Controller/Action rendering a View Template.

Using Django templatetags

The challenge is, that in order to force this strong separation of concerns, when a developer (me) wants to render something more complex in Django, it’s necessary to define a custom ‘tag‘ or a ‘filter‘ that the templating engine can then load and use. In the world of “basically all programming languages do the same thing“, this is really pretty equivalent in outcome to a Rails ‘partial‘, though the latter doesn’t offer any guardrails to prevent the commingling of logic and display, which can be a problem for debugging. But a sawzall doesn’t prevent one from cutting through a power line either… doesn’t make it less awesome of a tool. The user just needs to be cognizant of what they’re doing.

Read More

Data Driven Design and Component Architecture

Oh shit, I got access to the old database. Not really a surprise, but as I’ve been digging through models, I realize that I’d done a lot of things well (even this long ago!) by using data-driven design, such that they could be modified on the fly, for example if populations were getting out of control, or mines didn’t seem to be turning enough ore to resource or whatever, the ratios that drive those economies could be changed with a database value in a table called “UniversalConstants” — a notion I later carried over into Terraformist. Also, the ShipDesigns, the different classes of ships that could be built But as I’ve been starting the process of rebuilding the model classes, I’ve had this nagging worry that some of that was going to be missing or lost. But it’s not! Sweet.

Perhaps surprisingly in 2020, Data Driven Design was somewhat of a newish concept back in 2009 (or at least it felt like it), and not something everyone was doing in game design, but I had a friend and early biz partner Paul who was really keen on the idea, and had forced me to read a paper on the topic the year we attempted to found a gaming studio in 2005.

Read More

Let there be stars

Yesterday, I went through some of the basic object modeling — Stars, Planets, and some classification systems for both of those things. The Star classifications are loosely taken from the Hertzsprung-Russel diagram, and will give the map a bit of color by having the Stars show up differently, maybe down the road these will have various impacts on their planets’ resource generation. The Planets each have an “atmosphere type”, one of several arbitrarily chosen gasses, which can have major impacts on how suitable they are for living on, or for setting up resource extraction.

Read More

Kicking off

Normally, when I’m leading an engineering team, or consulting for one, I’m always firmly in the camp of avoiding a full re-write of your codebase. If you’ve got a functioning product, and customers, you just can’t press pause on development there, leaving current customers without bug fixes or improvements while the team spends 6-12 months rewriting everything from scratch… But I digress. Luckily(!?) in this case I don’t have a functional system or any existing customers… just a dusty codebase. In fact, I did a little infrastructural work this weekend, just trying to power some things on, I got a warning that a component I was using was deprecated… not that uncommon, generally, but this deprecation warning was SO OLD that the component it was recommending I upgrade to HAS ALSO SINCE BEEN DEPRECATED. That’s how old it is 😧

(Cue joke about Arthur in Hitchhiker’s Guide searching for files in a disused lavatory)

Read More

Dawn of Rails

Twelve years ago, I was frustrated with the technology we were using at work, and I set out to learn something else that I’d been hearing about, and wanted to try, Django. Nothing guides a learning project like a target, so I set out to build a game in the style of the old classics Master of Orion, or more specifically Pax Imperia (for us Mac nerds), but generally a web-based multiplayer “eXplore, eXpand, eXploit, eXterminate” (4X) style game. In fact, the original title, before I settled on a name was fourx

So, bit at a time, I built up what I needed to make this happen — learning each piece of the framework as I needed it, and each, successively more complex need for the game lead to incrementally covering most of the framework.

Read More