Ship Shape

How the Genesis Fleet is calibrated for visual and gameplay variety.

Void Runners
Void Runners
5 min readMar 24, 2022

--

Void Runners is a multiplayer strategy game on the blockchain. The Genesis Fleet is a collection of NFT ships with unique stats that govern their gameplay behavior.

We shared a little in a previous post about how we’re using Machinations to balance the overall Void Runners game economy. One of the inputs for that model is the ship stats. But where do those come from, and how do we make sure that there will be good gameplay balance across the full Genesis Fleet collection?

Void Runners is a game where the pieces are collectable NFTs. We think to do that well, the ships in the Genesis Fleet should be both meaningful in game terms and interesting as parts of a collection. We want variance in both those aspects: ships should look different from each other, often in big ways, because we think that’s what makes a collection cool. And ships should be different from each other, in game terms, because that’s going to make the game fun. We wanted Void Runners to offer players real range, not just in aesthetics, but also in playstyles and strategies. Not every blockchain game is able to combine those, but we were determined to try.

It’s also important for those differences to be legible. We didn’t want to end up with those things contradicting each other and creating ships that looked like one thing but behaved like another. A ship that looks fast should be fast. A ship that has lots of cargo containers should be able to carry lots of cargo.

So that was our goal — meaningful, legible variety.

We built our ship generator in the Unity game engine. Unity gives us access to a scriptable tool that we have lots of experience building games with, and its ability to publish to lots of different platforms leaves open a lot of possibilities for the future as this project grows.

We modeled hundreds of different ship components — wings, thrusters, cockpits, cargo containers, um, field boosters — and then we tell the generator how they fit together on any given ship hull. This manual layout process, combined with a recursive system for choosing pieces using weighted randomness (so some parts are rarer than others), is what determines the overall possibility space for a ship. Setting up the system involves some hand-tuning — we want to be sure that if a wing ever shows up on a ship it will always show up in an appropriate place —but it still produces a lot of possibilities, and the recursive nature of our algorithm means that branches can contain branches that contain branches, which helps us get the high amount of variety we’re after.

Each ship component isn’t just a visual asset, though. Each piece of a ship is also tagged with stats that contribute to the overall statistical make up of the final ships that get spit out of the generator.

It’s an intricate system which works great for that consideration of meaningful variety. It’s much more challenging for game balance. The stats of each ship are an organic output of the randomized build process, not an arbitrary constraint that we control upfront. No one knows, until a ship is generated, what its stats will be. We needed to tune the randomness to ensure that the set of ships the system creates will support the game’s design goals. How?

Spreadsheets.

We work direct from the output log from the generator, looking at the range of values we get back from our initial estimated parameters. That raw data looks something like:

It’s comprehensive but indigestible. So we then feed that into a sheet that plots more eye-friendly histograms for the three ship classes (speedy Vettes, efficient Scoots, capacious Luggers) to check that our balance across the collection is correct, and that each ship class is excelling in the stat it’s supposed to.

Some early histograms for initial data which helped us identify which classes were underperforming in which stats.

These histograms then let us verify the stat ranges and distributions for each class, and we can then take this data to build arrays of ship archetypes to use in the Machinations game model that we shared in our previous post

Each run in Machinations pulls a random ship from our array, and populates the model with stats based on the ranges we identify from the histogram analysis.

This end to end approach — data output from Unity feeding into spreadsheets that define our test cases for Machinations — gives us the ability to ensure that the when the Genesis Fleet mints, even though every ship is fully random, each will be meaningfully different, and calibrated to play its distinct part in the Void Runners game.

See more of Void Runners at voidrunners.io, read up on some ship lore, or (temporarily) risk life and limb in our allowlist game Void Adventures, playable on our Discord.

--

--