Game Design, Programming and running a one-man games business…

Improving accuracy of state employee & unemployment effects in Democracy 4

One of the problems with making a vidoe game with one person doing the development, where you try to model the entire world in inter-connecting detail…is that its impossible, so you end up doing a lot og guessing and thinking ‘yeah that looks ok to me’. Then eventually you find the free time (ha! its the weekend, who am I kidding?) to go back and check that the wild ass guesses you made were just wrong, and not OMG emebarrasingly badly wrong. Its a low bar, but i’m determiend to hit it.

My game Democracy 4 has a lot of policies that affect two important variables in the game – The membership of the ‘State Employees’ group, and the level of unemployment. For hopefully obvious reasons, these numbers are important in a government/ politics sim. They have to make some vague sense. Until now, the numbers in the game have kind of been guesswork, and result in equations like this:

StateEmployees_freq,0.02+(0.05*x)

That means that the effect of that policy will vary between a 2 percent and 7 percent boost to the number of voters who identify as state employees, depending how the policy slider is set. In other words, this policy assumes that at max capacity, this policy represents a seven percent higher chance of any voter joining that voting group, although in practice its much more complex than this, due to internal algebra that I wont bore everyone with…

The problem for me is that although I do not mind that seven percent figure being possibly inaccurate, I DO want the games model of this stuff to be internally consistent. To put this another way, if in the real world, a state health service employs 10x the people of a state postal service, the game should attempt to get that ratio correct, at the very least. With this in mind I have done some research, using the USA as my base case for the policies most impacting state employees:

These figures are NOT 100% accurate. This is mostly because the US does not have a state health service in the same way the UK does, so I had to take NHS figures and then adjust for population. I also had trouble getting energy figures, so I extrapolated from the top 10 companies employees and adjusted on a per-household basis. The point is that although the figures (like all figures) are a bit wrong (probably) they are massively less wrong than my guesses!

So now to make the game values make sense, I need to work out how to adjust those values in the second and third columns, which are my current effects (at max slider) on state employees and unemployment. Given that I do not want top massively unbalance the game, I thought it was prudent to keep the total combined effects of all of these policies the same (93% and 126% respectively) and just adjust the figures internally to fix the relative impact,

The way I’ve done this is to use the employment percentage (the actual percentage as a portion of total employment of all these policies) and multiply that by the total current in-game effect (93 or 126) to give me the new adjusted effects. That looks like this:

In some cases its not too big a change but in others its hilariously different. Currently the game is giving a HUGE (18%!) boost to state employees from armed police when it reality it should be about 3%. On the other hand state schools were set to have a 10% boost to employees, and should be having a 29% boost instead! So many teachers! Its also evident that in the grand scheme of things, prisons and a state broadcaster employ virtually nobody. (I scaled up the BBC employment figures to USA size to get that data too).

I have just done the data so far, but later today I’ll go through all the policies and adjust the values in each equation. I guess the takeaway from all this as a player is that if you really want to cut unemployment when you spend money on public services, you want to splurge cash on the health service and schools/universities. Everything else is trivial.

Keen-eyed economists might note that the REAL employment impact would be different. For example, the direct employment from the US military may be 1.3 million, but defense contractors etc will employ many more, and the knock-on effects from the contractors CEOs buying new ferraris is even higher. I agree, but that is best dealt with through a GDP boost I think.

Modelling the limits to growth in Democracy 4

Game design hates virtuous circles. If the player does well, throw a bigger monster with a +5 sword of game-balancing at them. If the player has too much gold, make the cost of health potions rise. Thats the way our forefathers designed games. Sadly, the game I am making (Democracy 4) is based on real life, and not J R R Tolkien, so I cant cheat like that. Plus, Democracy 4 is more of a sandbox than a traditional ‘beat level 6!’ style game. How can I solve this?

ITS ALL ABOUT GDP, STUPID.

Bill Clinton had this phrase, ‘its all about the economy, stupid’, to remind him what mattered. Bill was a big player of Democracy 4. If GDP is high, tax income is high, so you can cut taxes (happy people) or ramp up public services and welfare (happy people). Get the economy (GDP) higher, and re-election is trivial. This is all modeled with some accuracy in the game.

William J. Clinton quote: It's the economy, stupid.

However… its not balanced right yet in the game (hurrah for Early Access), because far too many hardcore players of the game shout at me that their GDP is 100% and will not go any higher. This is because there are not enough effects that reduce GDP, to balance the game, and the boosts to GDP are likely too linear…

There are a LOT (79 distinct things) of inputs to GDP in the game, but to list some of the biggest ones:

  • Worker Productivity
  • Corruption
  • Oil Price
  • Global Economy
  • Foreign Investment
  • Corporation/Carbon Taxes
  • Business Confidence
  • Income & other taxes…

There are also some good, and bad situations that can have huge effects, such as a debt crisis, hyperinflation, corporate exodus and strikes, or technological backwater… GDP also has a LOT of outputs (80) the largest of which are:

  • Currency Strength
  • Foreign Aid Inflows
  • Air Travel
  • The Environment
  • Costs and income from many different policies/taxes etc
  • Unemployment
  • CO2 Emissions
  • Obesity

There are basically three ways to fix the problem I have where GDP gets too high. I can change some of the inputs to GDP so they follow more of a curve, declining towards the top. I can boost some of the negative impacts of high GDP, maybe accelerating at the top, and I can imagine new links/situations/impacts that are negative, yet associated with high GDP.

For example, if we look at one of the strongest impacts that boosts GDP (Worker Productivity), its equation in the game is as follows: GDP,0+(x*0.44). This is, to put it bluntly, pretty simplistic, and maps onto a curve like this:

I know how simple this looks, but don’t forget there are THOUSANDS of equations in the game. They are not all works of art :D. The obvious solution to avoid the kind of game-design problem I have is to make that curve less linear. Maybe adjusting it to GDP,0.4*&x^0.76) which looks like this in comparison:

This feels a bit better, because it implies that the earlier productivity gains have a stronger effect (which sounds true… worker uses horse instead of ploughing by hand!) and the impacts taper off as productivity rises (horse replaced by tractor).

The big SCARY thing about doing stuff like this, is not working out how to do it, or having the idea to do it (both fairly easy), but the balancing. You can see from that graph that a change to this equation has boosted the GDP of all those countries with lower productivity, and reduced the GDP of all those with higher productivity. Have I gone too far? Does this make Italy too easy? France too hard? The USA? UK? South Korea… and so on. Even changing this single equation is possibly going to affect dozens, maybe hundreds of other policies, situations and so on. If GDP falls, tax takes fall, immigration falls, maybe racial tension then falls…and so on and so on!

Because I’m only one person, and time-bound, there are always going to be negative impacts of GDP growth that I have no thought of, and I welcome suggestions. Frankly, the game is so complex that its hard to keep track. Only this morning I had the sudden realization that yes, all things being equal, it does seem like high GDP will raise inequality, and I should model that…only to discover its already in the game :D.

Oh and I recently made changes that allow me to use 5 variables instead of 3 in each equation and to automatically calculate and use values like (1.0-GDP) as a single variable, which means I have more flexibility now to introduce complex links between values…

Over the next day or two I’m going to be going through the GDP effects, inputs and outputs to make them less linear and more sensible. Then I have some other tweaks to make to the game, and a lot of testing to do, and eventually we get around to doing another update. The current changelist already shows a LONG LIST of updates for the next version before I even look at GDP… so hopefully the next build of Democracy 4 will be noticeably better balanced :D.

Ongoing language support for Democracy 4

I have been doing a bunch of work on language support for Democracy 4. The game is still in Early Access, and I’ve been adding new content (mostly new countries, and some associated policies and situations for them) as well as play balancing and tweaking stuff, and fixing bugs. Out of all of these, the language support one is probably the most invisible to the majority of players.

Initially, like most games, Democracy 4 was just in English. We had gone to VAST expense and trouble to make it natively support Unicode text and rendering any text imaginable, which meant that we really did need to leverage that investment by supporting multiple languages. Right now, the completes supported language list for the game is as follows:

  • English
  • French
  • German
  • Italian
  • Spanish
  • Polish
  • Russian
  • Brazillian Portuguese

Generally speaking, in the old days of shipping stuff to retail, people used the term EFIGS, for English, French, Italian, German and Spanish. That was considered the ‘sensible’ list of languages to support. I think in 2021 its worth expanding into Polish (they love strategy games) and Brazilian Portuguese. There is a strong argument also for Japanese and Chinese, although the sales chances for a game called Democracy in China may be lower than normal.

I know a lot of devs use crowd sourced translation services like localizor, and I *started* doing that,m but basically its hellish because the work is hard to verify, can get stuck at 95% complete, and you cannot easily be sure that everyone is using the same terms. This really matters, because using president in one sentence and prime minister in another and chancellor in a third…all as translations from the same English source can be a confusing nightmare.

So we ended up getting paid translations, either from individuals, or from a professional translation service (which is more expensive, but I guess easier to manage and ultimately sue if they were to just send you a badly done mess.

As with every translation ever, done by anyone, at any point in human history… people always complain that some phrases or words are badly translated. As someone who only speaks a single language (C++) I really have no idea. I have to just read every comment and in extreme cases do a reverse google translate to see if everything looks legit.

Of course, getting text translated is just part of the battle. In most cases, the other 99% of this blog post would be about Unicode, and rendering languages that have so many characters you cant fit them in texture memory (joy!) but actually I’ve handled that before, and Jeff managed all this for me using things called pango and cairo and other magic, so actually this is a ‘solved problem’ in many cases.

So now I am down to the final part of the puzzle, which is making sure it all ‘looks’ ok. As expected, there are lots of places where things go wrong. For example here:

And also here:

I’ve already those, and a bunch of others, but its by no means exhaustive. I guess the lesson learned here is to assume that ALL text may be 100x as long as expected (or 10x as small), and code defensively at all times to accommodate this. It feels like 99% of devs currently use unity and unreal, so you are relying on the 3rd party vendors to have automatically fixed all this for you I guess. And if it isn’t fixed…well good luck?

The only problem with going through and doing this is that its hard to persuade players that this is valuable work. Someone who speaks English and bought the game in Early Access is not going to care that certain screens (that look fine to them anyway) now look better in Polish or Russian. Because EA players can be VERY DEMANDING in terms of expecting the developer to work 24/7 throughout Early Access, my only worry is that people think development slows down as I fix all this.

Thats probably unlikely as I already have a bunch of stuff listed as going into the next update:

[1.26 (in development)]
1) Removed duplicate effect from firearms laws to armed religious communities.
2) Removed duplicate impacts on luddite riots.
3) Fixed some harmless debug warnings about missing neurons.
4) Intel readouts are now inverted for situations where a policy reduces security effectiveness, such as Press Freedom.
5) Fixed error where a total ban on handguns actually reduced security, instead of boosting it. Ooops.
6) Fixed support for names for each slider setting in modded policies.
7) EU situation now renamed to EU membership, also now boosts stability and foreign investment.
8) EU countries now benefit from the Erasmus programme, which boosts youth income & happiness and also education.
9) Import tariffs can now not be implemented by EU members.
10) Made some impacts of banning low mpg cars scaled by EV transition, and introduced support for inverse variables and 6-variable equations.
11) Cyberbullying Awareness Policy now slightly reduces Internet Crime.
12) Universal Basic Income (UBI) cost now quadrupled so it reflects the correct figure.
13) The Polarization situation now explains its effects better.

I think ultimately tweaking the UI for multiple languages is very worth doing, because its a BIG world out there, and frankly the majority of humans do not speak English. At some point, (maybe we have already crossed it?) the majority of strategy gamers will not speak English either. If you want a game to be around a while (I hope to still be selling this game in 2028) then you need to plan ahead and look at who will be playing it.

Improvements to the political compass / voters opinions

I’ve been trying to improve voter behavior in Democracy 4 with a bunch of goals. Firstly to maker the political compass Overton window not look so ‘forced’, and more importantly, to allow for more realistic modeling of the variety of opinion. As some players have pointed out, there is always SOMEONE in the electorate who will not ever vote for you, always some communists, always some capitalists, and so on. How to fix this?
Here is the political compass for a new game as Australia:

And here it is with my new changes I am considering:

The voters are less confined to the Overton window, and yet are still influenced it. We clearly have people far to the left of the political consensus zone, but not quite as far left as Stalin and Lenin. I think this makes sense. Even people who are claiming to be outsiders and not swayed by the mainstream media or mainstream politics are still vaguely influenced away from the extremes.

The (debug-mode-only) tooltip data for impressionability illustrates this. The game has always modelled the ‘impressionability’ of voters, but with recent changes, I’ve improved how this calculation is used to determine a final opinion. Here is the final calculation:

Final Socialism = (CurrentGlobalSocialism * Impressionability) + (InnateSocialism * (1-Impressionability))
(This is a new equation for this version, it was different before)

So every voter is born with an innate predisposition to socialism (also liberalism) or not, and this is their ‘starting’ position. They then get swayed towards the ‘consensus’ position (Global Socialism) by how impressionable they are.

Impressionability is calculated as a normal distribution but then squeezed in so its between 15% and 85%. (Its then multiplied by 0.95 which is an internal value and not important…)

Note that if the ‘Polarization’ situation is active, the value of InnateSocialism gets pushed out to the extremes by the strength of the situation.

I need to do a lot of play testing, but I think this change will make the game feel more realistic.

Balancing Democracy 4 using stats and number crunching

I’m still working away on improving the balance for my political strategy game ‘Democracy 4‘ which is in Early Access, and likely the hardest game to balance in the history of humankind, due to the insane number of interconnecting variables.

Something I was working on today was the likelihood of each dilemma popping up. These are occasional ‘situations’ that are urgent and need the player to make a choice one way or the other. Basically the choices are always hard, because they mean upsetting someone, or causing an effect that may be undesirable given your goals.

For example, if a company is about to collapse, you could bail it out (pleasing the workers, but setting a bad example for other companies, maybe upsetting capitalists, who prefer a free market), or not, and your decision depends on who you can afford to (or choose to) upset at that moment.

Some of the dilemmas are totally random, but most are influenced by some variables so that they seem fairly ‘relevant’ to the way you are playing the game. So they all have inputs based on certain variables, and thus as the game designer I don’t know in advance when they will happen (they are not timed or scripted in a conventional way).

This is all very easy to design and code, but the problem is you can end up with the inputs being unbalanced, and thus maybe everybody is sick of seeing dilemma A, regardless what they do or how they play, whereas interesting and exciting dilemma B hardly ever gets triggered. For a small studio with a limited budget, having any game content that is rarely seen by the player is an efficiency disaster.

Luckily I (anonymously) keep track of every trigger of a dilemma by version number, so I can guild up big databases of such events. The events database is currently about 4GB in size, and is testing the limits of my MySQL optimization abilities. Thus I copy the last 2 versions events into a much smaller (600MB) database for me to query. That lets me get cool charts like this:

Which lets me visualize the extent to which some dilemmas (the ones with long red bars) are triggering WAY more than they would if their distribution was completely random. I’ve been using this data for the last few versions, but I still have the unbalanced issue despite a lot of manual revisions, so I’m working on code today to visualize this better.

I actually found this easier in excel, once I had data that showed me every dilemma, and what percentage of dilemmas each one represented, over the previous 2 versions:

I can then work out what percentage they *should* be, thus the error in terms of over or under representation. Luckily I’m analyzing 100 dilemmas, so its a simple 1%. I calculate an error in percentage terms, for each version, then calculate the change. A positive value is movement towards better balance, a negative one is movement away, (worsening the balance). This can then be conditionally formatted in excel:

Which is a cool trick, but also depressing to see the extent to which I often am having a trivial effect towards balance, or even making things worse (negatives).

However, at least having a nice process to visualize this stuff makes it more obvious to spot where I am being too timid in my corrections. In an ideal world, this would all be integrated into a single web query, and in an ideal, ideal world, some sort of cool machine-learning AI would be making these adjustments instead of me…

But hey, its a big step up from just ‘setting some numbers and then playing it a lot before release’ which is what I did ten years ago :D I’ll gradually get this stuff more and more optimized.