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

Theoretically auto-balancing Democracy 3

The problem with games like Democracy 3, or indeed Gratuitous Space Battles, is that they are VERY hard to balance. Balancing a game is exceedingly hard, even if you agree, like me, that ‘some’ inbalance is actually what can make a game fun. (If all choices are equally effective, why pretend there is strategy to the game?). DFor big AAA studios with huge testing teams, pre-release balance is easier. For one or two man indie studios, its almost impossible to do in house.

The common solution is early-access / pre-orders with beat access, which get a lot of people to play the game. However this assumes that

a) Those players are representative in terms of skill, time, and play style to the wider public

b) You get decent feedback from all those players, not just the hardcore and

c) The feedback from the players is impartial and can be relied upon.

With a game like Democracy 3, c) is a real issue. A lot of people complain that capitalists are hard to please, but how do we know if that’s true, or if its feedback from socialist players? Anyway, as a geek, and a coder, and someone who embraces complexity, an alternative strategy of letting the game balance itself obviously appeals. So clearly, getting the game to play itself constantly and discover, then report, and maybe even auto-tweak and adjust its own rules, is the ultimate goal.

This would be an ideal ‘summer vacation’ project for me.

Actually, the bit most people are probably wary of (coding the bit where the game comes up with a strategy, plays the game and developers improvements to its play style based on the results), isn’t the bit I’m worried about coding. That bit wont be too bad (i’m not aiming for alphago levels of skill here), the bit that makes me roll my eyes and go ‘Can I be arsed?’ is the mechanics of introducing a wrapper to the game that lets it play itself. The problem here is just doing a nice, clean job of introducing such a system without breaking the game or introducing anomalies.

This is where Alphago is AMAZING, because it simply uses visual input. Frankly that ain’t gonna happen, so I’d have to embed code in there…or would I? an ideal system would be hands off, a new ‘GeneticD3.exe’ that launches D3, non invasively, makes player decisions, then handles everything without touching any D3 code directly… Surely that cannot be done?

Mwahahahaha. It possibly can…almost, because D3 is already set up to autosave each turn. And because its turn based, all the ‘decisions’ happen at once. So all I really need to do is to write code that parses the D3 save game (handily already xml), makes decisions as to what to do, runs those decisions through the D3 engine (that bit gets tricky), and then dumps out the next turns save game, repeat ad finitum. To do some rough maths, lets say saving and loading D3 takes about 2 seconds (I rule at optimizing), and we give a generous 2 seconds to make a turns decisions, thats 4 seconds a turn, 64 seconds per term in office, or a 4 term complete game in 256 seconds, so roughly 14 games per hour, or 300 games a day. Thats actually remarkable slow. If AlphaGo needed 100,000 games to learn, I’d need the best part of a year. Still, assume some cunning multithreading and optimizing (I don’t ever need to touch the disk really, all save/loads could be trapped in a RAM buffer), I could probably quadruple the speed, so 1,200 games a day?

I am seriously thinking about it. It would definitely be fun.

Coding for fun (but not profit)

I’ve had problems for at least a few years when it comes to coding purely for fun. Thats not to say I do not enjoy coding, I LOVE coding, its my passion, but I made the mistake (in some ways) of turning my passion into my job, and then my career and my whole livelihood & retirement plan, and when you do that, suddenly when you are writing code you have a little voice at the back of your head saying “who is going to buy this”. And thats not a problem, in fact its a GOOD thing because it means you release commercial games and not arty self-indulgent bullshit about crying and existential angst among cartoon Bolivian hamster-weaving. Thats how I’ve stayed in business.

But the problem with working for yourself, at home, when you are the boss, is that you can work WHENEVER you like, and this means the line between working and having fun gets not some much blurred but obliterated.

beach

If I decide to take a day off work (madness!), I really can’t go near a PC, because the PC is where I work, and my office is for work, not for fun. Its hard enough to sit here at this desk and play games instead of work, but if visual studio is open then I am IN WORK MODE. My Brain goers all serious and strategic and long term.

So I’m trying to shake myself out of that and re-discover the joy of pure creation as a hobby, as fun, as something experimental and silly, and not something that I expect to ever charge money for. I will probably never get around to achieving anything, and certainly not making anything public (unless miraculously I make something I’m not ashamed of). The main goal is going to be to learn how to code some stuff without getting all world-domination and work-ethic about it.

I know a lot of people do one-game-a-month stuff and game-jams, but thats just not my scene. I prefer to code for fun, than design for fun. Design is too intense for me. I can practically code while I’m asleep. Ask anyone whose tried to use my code :D.

Coding the GSB2 Radiation effect (directx9 C++)

I was never 100% happy with the radiation effect in Gratuitous Space Battles 2, so I’ve coded a better version for the next patch. Here it is in very short silent video form:

I thought maybe some people may be interested theoretically in how it is done. Now I’m sure if this was in 3D in unity there is already a 99c plug-in that does it without you even having to understand coding, but thats not how its done so here we go…

The first thing to remember is that the spaceship is not a 3D mesh at all. its a series of sprites rendered to different render targets and then composited. That means that I’m not wrapping a texture around a mesh, but drawing one sprite on top of another, but cropping the final output to the alpha channel of the base (ship outline) sprite.

Before I learned much about shaders, I had a system that did this using mostly fixed function, which I use here, but build on with better shaders to do more stuff, making it a hybrid approach and fairly complex :D. To simply draw one sprite on top of another, but use the alpha channel from the bottom sprite, I use a custom vertex format that has 2 sets of texture co-ordinates. One set is from the splatted image ‘radiation’ and the other is from the alpha channel of the ship outline.

It gets a bit fiddly because where I’m drawing the splat sprite could be anywhere on the ship, so I need to work out the offset and dimensions of the splat in relation to the ship image, and store that in the second set of texture UVs, and pass that into a shader.

The shader then simply reads the color data and alpha data from the radiation splat, and multiplies the alpha by the alpha at that point on the base ship texture, and voila, the image is cropped to the ship.

But thats a very simplistic explanation because there is more going on. To make things fast, all of my radiation gets drawn together (to minimize texture / render target / state change hassle), so its done towards the end of processing. In other words, there is no painters-algorithm going on and I need to check my depth buffer against this ships Z value to see if the whole splat is obscured by some nearby asteroid or debris. That requires me passing in the screen dimensions to the shader, and also setting the depth buffer as a texture that the shader can read.

So that gets us a nicely Z-cropped image that wraps around the ship at any position. It also fades in and out so we need to pass in a diffuse color for the splat sprite and calculate that too. We also have to do all this twice, once for the splat, and once for the slightly brighter and more intense lightmap version, allowing the radiation effect to slightly light up areas of the ship hull during final composition.

At this point the shader is a bit complex…and there is more…

I wanted the radiation to ‘spread’, and to do that, I need to splat the whole thing at a fixed size, but gently reveal it expanding outwards. To do this I create yet another texture (the spread mask) which also gets passed to the shader. There were various ways to achieve this next bit, but what I did was to ‘lie’ to the shader about the current UV positions when sampling this spread mask. Basically I calculate and pass in a ‘progress’ value for the spread, and I use that, inverted, to deflate the UVs of the source image (which is CLAMPed). So effectively my first UVs are -4,-4,4,4 and the spread splat is a small circle in the center of the splat, expanding outwards to full size.

Because I’m only doing this when I sample the alpha channel from the spread mask, the color and alpha data from the base ‘splat’ texture remains where it is, so it looks like its a static image being revealed by an expanding circular (but gaussian blurred) mask.

I’m pretty pleased with it. The tough bit I’ll leave for you to work out is how that works when the source radiation image is actually a texture atlas of different radiation splats :D

Fun fun fun.

 

 

SQL headache

Gah, I spent all morning wracking my brains to fix a rendering order batching bug (fixed! yay!), and now I suddenly have a second daily headache with some SQL. If you use SQL a lot you can probably tell me how trivial this is…

Imagine a table of scores

DaveĀ  PlanetA 4,200

Mike PlanetB 2,200

Dave PlanetA 4,100

Chas Planet A, 7,200

And so on. What I am doing right now is a SELECT to get the top 20 rows from this table where the planet is (for example ) PlanetA. What I *want*n to do is to get the top 20 rows, but only the TOP entry for each player. So you only appear once in each high score list.

I can’t get my head around how to do that. I want something like SELECT * FROM scores WHERE scores.planet == ‘zog’ AND scores.score IS HIGHEST FOR score.player ORDER BY score

But of course I’ve made that syntax up and its imaginary. Albeit cool.

Tell me there is an easy way to do this thang?

And ooh guest what! Democracy 3 is the #1 strategy game on the ipad right now, due to a rather insane price drop I’m experimenting with…

Fixed the low-hanging bugs…. pause for breath…

Yikes,. so we had a lot of MUST FIX NOW issues in the first four days of releasing Gratuitous Space Battles 2. I think in retrospect I had bitten off a bit more than in possible for a single coder / designer to do.

GSB2 involved a phenomenal amount of re-engineering to support the kind of graphical fidelity I wanted. I sometimes read comments like ‘its just a new engine’, as though I just went into a drop-down box in unity and selected ‘new engine’, then hit the ship-it button. Arrggghhh. This new engine took well over a year of mind-mangling stress to develop. I love it, but its still hard work.

Anyway… Lesson learned #1: Multithreading increases your bug count by at least tenfold. Especially on ‘other peoples hardware’.

spag

Lesson learned #2: Don’t do a multi-platform release. Do a Windows release. Fix everything, THEN worry about mac & Linux. Or hire another 3 or four people. Or make a much, much simpler game.

The good news is that after tracking down some pretty obscure stuff, I’ve got version 1.26 out there, and early reports suggest it is MUCH better. MUCH more stable, and a lot of silly dumb-ass mistakes by me have been fixed. The only *big* bug left is some series of actions that leads to ship designs being (temporarily) deleted until you restart the app. I reckon thats easily fixable today. Which then means I can get on with what I wanted to be doing all along: tweaking values, improving GUI elements, supporting modders, and getting a feel for what features people would like improved or added. I know people want galactic conquest put in, but thats a HUGE project, and not one for the next few months. That didn’t ship with GSB1, and that was with good reason, I assure you. Every single weapon and module from every race & expansion pack of GSB1 is in GSB2. It also has more initial missions, but even then people complain it doesn’t have enough content. Argggghhh.

Anyway, at least I can smile now for the first time in a few days. If you are enjoying the game, please leave a positive steam review. Even better, tweet about it :D.