Orbitect, Spreadsheets, and JSON.
How we streamlined configuration management in Orbitect.
Setting the scene.
What’s up, world?
For anyone who works in and around super small indie video game studios, you’ll have noticed that individuals often have multiple roles in the project. People wear many hats. So many hats. More hats than a birthday party, fancy wedding and a day at the races combined. Maelstroms of hats. Hats everywhere. Hatters gonna hat, after all.
So for a project like our upcoming game Orbitect, which is an ambitious construction roguelite with a complex tapestry of configuration, it was super important that we utilised our time in a sensible, efficient way in order to stay as focused and streamlined as possible so that we could realise our vision without spending decades in the process and tying ourselves in a myriad of nebulous (albeit rewarding!) knots.
This post is about an example of how our small but mighty team have used some spreadsheet-based automation to streamline selections of our production in order to iterate and refine our gameplay balancing at speed and scale. We’ll be writing more in the future about exactly how we tackled the balancing itself, as well as how Orbitect is utilising configuration on the programming side, but for now — feel free to treat yourself to a little insight into how we’ve joined the two together in data-driven harmony.
What’s our problem?
In Orbitect, the player uses blocks and stat-based panels to craft a space station capable of destroying waves of space debris. Destroying that space trash earns the player money and resources to repair, upgrade and expand their station, so on and so forth, ad infinitum (well, until the end of the campaign at least). We have designed many levers of configuration in order to control the flow and feel of gameplay. For example:
All in we have just over 70 configurable attributes to work with, each with dozens (or more) entries comprising the overall configuration of the game. Can you imagine if we had to keep track of this manually in-engine? Tweaking the configuration to refine the game’s campaign experience would be a time consuming, miserable, communicative monstrosity and would most likely fail before it began. Thankfully, we are making use of a data interchange format called JSON to store attributes and their values across various files.
Here’s one excerpt as an example:
{
"wavePatterns": [{
"name": "Wavepattern 1",
"description": "Rest wave",
"speed": 1,
"direction": "All",
"spawntype": "Every 5 Seconds",
"target": "None",
"difficultymultiplier": 1
},
{
"name": "Wavepattern 2",
"description": "Build Back wave",
"speed": 2,
"direction": "All",
"spawntype": "Every 4 Seconds",
"target": "None",
"difficultymultiplier": 1
}
]
}
When it comes to refining the game design itself — updating multiple values quickly and accurately directly in the JSON is still a challenge. It’d still require us to manually scroll through and edit various attributes. And if we had multiple waves, debris, panels etc in the game (which we do), then we’d have to do this multiple times.
So what did we do about it?
Enter: The Spreadsheet.
That’s right. We’ve employed the old reliable stalwart that holds the entire knowledge working world together — a spreadsheet. We used one to lay out the various configurations across multiple tabs. For example:
Not only is this useful because of the use of rows, columns, and formatting that we all know and love, but because we can make use of formulas to create feux-JSON configurations in the spreadsheet itself. For example:
Here’s a snippet of one to illustrate what it looks like:
Great! That’s already saved us some time trawling through JSONs. However, we were still maybe spending around five minutes copying, pasting, zipping up and sending to one another every time we wanted to tweak a few parameters and test out the gameplay implications. Given we are iterating repetedly during our development, we had an opportunity to further help ourselves. So we utilised a google apps script (with thanks to this thread and this thread) to automatically copy and paste our feux-JSONs into (real life) JSON files, and store them onto a specific folder in our shared google drive, for anyone in our team to pick up and play in their local build (and eventually use in the main development build). We even made a little button to run the apps script and export them!
Now at the click of a button we have fresh Orbitect gameplay configurations ready to use the next time we run the campaign in-game. The couple of hours invested in making these little innovations (can I be so bold as to call them innovations? Probably! If you’ve read this far down then you must like this approach too, right?) has saved us exponentially more time in the run up to release. It has paid for itself within a couple of development days.
So there we have it. Is it rocket science? Hardly. Just a good old spit-and-sawdust approach to saving us a little bit of time, hundreds of times. Little friction-busting steps like this along the way help our team to release a game that reaches for the stars, and takes out the trash along the way.
Orbitect is an upcoming game by Propulsion Games and can be wishlisted here.