Simulation testing

Posted by

The heart of any game is the simulation logic. That is, the rules which govern how high you can jump, how many shots it takes to kill you or how much Vespene gas you can mine per second. And of course, War Worlds is going to be no different. I've been building out the simulation logic over the last few weeks, and I think it's starting to get to the point where it's actually quite playable.

The trick with getting the simulation right is the balance between a few different ideas:

  • The rules should be simple enough that a new player can get an intuitive feel for what they are without having someone actually explain it to them, without having to read pages and pages of boring statistics and without having to have a degree in advanced mathematics (for example, things like "increase mining focus to produce more minerals" is a pretty obvious rule).
  • The rules should be complex enough that a advanced player can spend time tweaking the input parameters and make a big enough different to the production capacity of their colony that it actually makes sense spending time doing it. They should also be complex enough that while you can get an intuitive feel for them quickly, really understanding them takes effort.
  • The game's backend is an App Engine app, so we can't rely on there being some server process running 24/7 (technically, you can do a "backend" in App Engine that runs pretty much 24/7, but we're not made of money here...)
  • Above all else, the game needs to be fun.

Before I got into the rules I'm working on, I just wanted to make a quick side-track and show the "backend" web site that I use to tweak parameters, a debug the game itself. The War Worlds backend lets me do things like adjust the "Message of Day" (which is what you see when you first log in to the game, I can put status updates there, messages that I need players to read and so on). It also has a "debugging" section where I can go in and query the current state of the universe. You can see an example of that here:

Sector debugging

On this screen, I put in the coordinates of a sector I'm interested in (remember, "0,0" is the "centre" of the universe). In each sector is a number of stars. If any stars are colonised, a summary of the colony is returned as well. The output you see here is basically the same data that is sent to the photo (the difference is that the client-server protocol the phone uses is based on Protocol Buffers, whereas this is just JSON, see my previous post for details of how this works).

On the output here, there's a colony. The various XXX_key properties denote keys used to identify things like the empire who owns the colony, the star the colony belongs to and so on.

Simulation

Simulation in War Worlds happens at the "star" level. Each star is simulated independently of all others, and this allows us to keep a faily simple request-response style of interface. Basically, all the details about a star and the last time the simulation was run for that star are stored in the data store. Then, when you request details about the star, the simulation is run just for that star to bring it up to date.

When you make changes to a colony (for example, when you request a new building to be built, or you adjust the colony's focus) the star needs to be simulated up to the point where you make the change, then stored back in the data store with the new parameters (so that subsequent simulations will use the new parameters from that point on).

Simulation

This view shows the debugging output from the simulation of a star. The simulation runs in two main steps, a "production" step and a "consumption" step. The simulation is conceptually turn-based, which each turn running for 15 minutes. To make the game appear to be real-time, though, we might only run part of a 15-minute turn for the last turn.

Production Stage

In the production step, we look at each colony's farming and mining focus as well as the planet's farming and mining congeniality, combine these two to work out how much goods and minerals are produced in that turn. In the screenshot above, you can see the first colony (which has a farming focus of 30% - quite high) produces 53.9 goods that turn.

The actual calculation is:

goods = population * farming_focus * farming_congeniality/100

You can see the second colony has a much smaller population, and also a lower farming focus and congeniality which is why the goods produced is much lower.

Once each colony has finished the production stage (a similar calculation also runs for mining/minerals), we move onto the "consumption" stage.

Consumption Stage

Technically, we still "produce" things in the consumptions (buildings, population) but we also use up the resources that were generated in the previous stage. Each colony works out it's updated population and also works on building buildings and ships in this stage.

For every 10 "units" of population, 1 "good" is required per hour to sustain it. You can see that reflected in the total_goods_required number: add up the population of the three planets, divide by ten to get 64.4. If there's not enough goods produced, then we'll dip into the star's storage of goods. You can see our colonies this turn generated about 63.1 goods which means we need to dip into the storage for the last little bit. If there's not enough goods stored then it affects our goods_efficiency factor. This is basically a number between 0 and 1 which we use to adjust how much our population increases (or decreases!). Since we have plenty of goods still, our goods_efficiency is 1.

The population increase is calculated as:

population_increase = population * population_focus * (goods_efficiency - 0.75)
if population_increase > 0:
    population_increase *= population / population_congeniality
else:
    population_increase *= 1 - (population / population_congeniality)

Basically, what this means is your population increases in ratio to your population_focus value and also depending on whether you have enough goods to support your current population. Then, a factor is applied depending on how close your population is to the planet's population congeniality. Your population should never go above the planet's population congeniality.

Presenting the numbers

One of the really difficult issues I'm facing is how to present this data in the user interface in a way that's intuitive and doesn't take up loads of space. I don't want my game to be just "spreadsheets in space" or something, so I need to find a succinct way to display all this data. For now, this is what you see:

In-game view

Under the "Colony" heading, you can see the four facets of your colony. The progress bars represent the focus you've configured (you can see this corresponds to the second colony in the screenshot from the backend). So it has a low population focus which is reflected by the fact that it's currently only 126 +3 / hr (meaning it should increase by approximately 3 per hour). Mining focus is quite high, and you can see that corresponds to an equally high rate of around 23 minerals per hour.

Buildings

I've also got logic in place to build buildings, but I'll go through that in another post (it's complicated enough in itself). I haven't figured out the best way to describe construction in the UI yet either, so I'll wait until I've figured something out before writing about it.

Conclusion

I'm still not convinced I've got the balance quite right yet. For example, I'm considering adding a popup with more detail for when you tap on the four focus areas (or maying making the "focus" window more useful in general). I'm also not enough sure the exact equations I've displayed above are exactly as they'll appear in the final game. I guess play-testing and time will tell.

blog comments powered by Disqus