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

Democracy 4 is in Early Access at last! omgz etc

I’m super tired and got little sleep, but whats the point of a release-day blog post if you do it weeks later? Frankly I need sleep, and a day off. Making this game is REALLY hard, and we had last minute problems, and I actually have a minor eyesight thing recently thats freaking me out. Argggh. Game dev is HARD.

Anyway, last night at 8PM my time (why? because I’m stupid), Democracy 4 went into Early Access. We have already sold a lot of copies, we had 7,600 games played yesterday, there are tons of emails, and forum posts, lots of youtube videos are cropping up, some previews and reviews…its all very hectic.

We launched with a bad bug for maybe 4-5% of players (maybe less), which caused major GUI mayhem. Icons would dissapear, or be massive, or the wrong icon. The game became unplayable, then there was major lag. It was a mess, and the worst possible thing: I could not reproduce it on any of my PCs. Fixing a bug that has no error message and you cant reproduce is…challenging. At the time of writing I’m feeling pretty good that I’ve fixed it, within 14 hours. Thats actually *not too bad*, although it still probably dinged our steam reviews a bit. (if you bought on steam and like the game PLEASE give us a nice thumbs up review!).

I made a lot of mistakes, and I guess this is as good a time as any to confess to them. Mistake #1 was that I didnt treat every warning in my code as being serious. I was seeing some warnings about icons being sized wrong, but it didnt seem to show up on screen, and I figured it was a harmless thing when they got resized correctly before being drawn. who cares right?

Turn out that on some PCs, in some screen resolutions and in fullscreen mode… This caused MAYHEM of EPIC proportions. I just wasn’t seeing it under any circumstance in my test cases. PLUS! we had a lot of pre-EA alpha players who had not experienced this. But… yesterday 4,500 hours of Democracy 4 were played in 14 hours. No wonder stuff cropped up we had not seen before.

We converted the game to be 64 bit a few days before release (Mistake #2), which sped up the start-up time, and future proofed the game against any insane move my microsoft to ban 32bit…but this seemed to be the cause of the bug. It also stopped it running under WINE. I decided the 64 bit middleware had broken the game. I reverted to 32bit, it achieved nothing (but got us WINE back), but wasted my time in tracking down the real cause…

Eventually I think we have found whats going wrong, and here is Mistake #3. Some of our code was just blindly accepting data and doing what it thought was right. This is BAD. You should code defensively, and if you are about to draw an icon on the screen, its worth checking that the width is not -25 or 10 billion pixels wide. if it is… then somebody probably screwed up, so don’t draw it.

Anyway… this sort of thing is SUPER stressful, because we have moved from the lovable, friendly ‘community of friends’ atmosphere of my early-access players on my own discourse forums, to the terrifying confrontational angry wasteland of the steam forums, where people pull no punches. Its always fun to be told your game is rubbish, or biased, or you are a stupid/lazy developer who doesnt know how to code etc. Oh fun times!

Anyway… its out there. it was in the steam top sellers. it might still be, I’m too busy to look! And you can now get the game from us direct using the widget below, OR from steam gog or the humble store.

At some point I’ll do a proper update with a bunch of stats about wishlists and release and all that (we had about 20,000 wishlists on launch day), but I need to deal with the huge list of stuff in my inbox first… Thanks to everybody who put down their hard earned money on buying my game, its hugely appreciated. I hope ya like it!

The irritating last-minute bug

So…I am 99% sure I’ve fixed this, but it was a bug hell nightmare and worthy of a blog post. It also kept me coding till midnight last night, so I did probably 14 hours work yesterday. arrrghhh. no wonder I slept late this morning. Anyway…

Democracy 4 releases into steam early access on Tuesday, but we already have 3-4,000 players, and I had no showstopper bugs., Most noticeable the game was 32 bit, and only in English. Very recently we switched to 64 bit, and I guess some combination of that, and some people playing in different countries started me on a journey of bug tracking hell.

I got one bug report “game crashes on next turn, or if you change sound volume”. I tested my copy, worked fine. Tested on my laptop too, worked fine. Asked them to try and repro on another PC, arrogantly assuming user error. Then another customer reported the same thing, then a third. This is NOT GOOD. I asked for debug logs, which handily my engine does do, and are fairly comprehensive.

Nothing in the logs explained the actual crashes. Everything looked good. nothing was especially shocking except an error about failing to find a specific neuron (no name supplied). This could be just a typo, or a badly written mod. This *shouldnt* happen, but the game should recover. its not critical… but then why didnt MY copy give me the same error… weird?

I put together a new build of the game that outputs the NAME of the neuron it can’t find (should have done this anyway tbh), and I get back a log from a user where the missing neuron is called 0,00.


That sounds like a bug with a comma somewhere, as the equation Socialist,0.00+(2*x) for example must have a typo, so instead of the name ‘Socialist’ we are getting the value. Ha! a simple typo. But why am *I* not getting the bug? I do a windows search of the whole data folder looking for 0,00. I get two hits… neither file actually contains the string. Windows search is WORSE than useless. Weird…

So I change the code again to output the name of EVERY attempt to get a neuron by name so I can compare mine with the users, and see where in the code they were just before this goes wrong. This turns out to be no help, as its inside the Voter processing, which makes no sense… there is simply no way any string like that is being passed at this point in the code. this makes ZERO sense.

And then I notice it. I’d normally missit…but it was weird. REALLY weird. In the debug logs of the players:

PreCalcCoreSimulation time: 0,70 seconds

No big deal, this value will vary based on CPU, but on my PC it said this

PreCalcCoreSimulation time: 0.92 seconds

Yup. Mine has a period/full stop, theirs has a comma. No big deal, its debug logging, who cares. Maybe its even an artifact of copy/pasting the log to my forums… I check this…nope. I ask the player to verify thats really a comma in that log file, not a full stop, they confirm its a comma. How? HOW is this possible? I check the code:

char temp[256];
sprintf_s(temp, 256, "\n\nPreCalcCoreSimulation time: %.2f seconds\n\n", elapsed);

This is simple stuff. I just used the very low level, very basic, very simple good old fashioned sprintf function to convert a value into a decimal number in a string. I do some googling and… what the actual fuck? apparently even good old c++, ignoring anything higher level, is looking up the regional settings, and deciding whether or not commas or periods are used in decimal strings. In english its full-stops (.). It is VERY VERY important to the structure of my code and engine that its full stops. When the majority of your data uses comma-separated values, you cant go messing around with the definition of a comma for fucks sake…

So theoretically easy fix, find the function that hacks in the ‘locale’ to be English for this app…and boom! No! it doesn’t work. Sure, I can use

setlocale(LC_NUMERIC, "en-US")

to force the number format to be full-stops, and when I check that the locale really has been set…it has! and everything is fine but… once the game loads a new level, everything has gone haywire, all the values are wrong, all the policies are set to zero, and checking the locale returns what the PC has set it to (I temporarily changed mine to commas as a test). In other words….my setlocale is being overrriden.

Arggh. Now its late, I am tired, I am thirsty, but not enough to leave my desk and lose my concentration. I am very tired now. I spam the code with multiple checks to read the locale at every possible location to see where the hell it goes wrong… And eventually I find it. Its the text renderer, which does use some middleware, to convert fonts into vector graphcis, render them into memory and then paste them as strips to the screen, dynamically. Its all very clever and supports any language, any font size, its super l33t. It also has its own opinions about locales.

So now the game is fixed, by me setting the locale to the US the millisecond the game starts, and then the minute its rendered its first bit of text (and thus the middleware has overrriden me, it sets it AGAIN, to ensure no funny business. Everything now seems to work. Hurrah. I hate computers. I need sleep. Why the hell cant humans agree on what a decimal point looks like in 2020?