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

Optimising Ridiculous Space Battles

Due to what seemed to be a compiler bug (omgz) yesterday I thought that large complex battles in Ridiculous Space Battles were hitting performance limits. That appears to not be the case, but it got me back into profiling the bigger battles (20×20 grid size, with up to 25 ships in each square, probably 600 ships in total) to see where the bottlenecks are.

The game is already multithreaded for some tasks, but the first profiling runs for he first 50% of a battle gives me this flame graph from uprof for the main thread:

In practice what I really care about is stuff inside GUI_Game::Draw(). I have to say I am pleasantly surprised with the breakdown as it seems nicely distributed, without any real obvious processor hogs at first glace. Drawing the ship sprites, processing the simulation, post processing (mostly lightmaps), particles, hulks, bullets and then a bunch of minor stuff. Nothing seems too bad. On the other hand there are some things in there that seem quite big given what I know they are doing. For example the lightmap stuff shouldnt be that big a deal, and perhaps should be threadable more? Lightmaps are being drawn not only for every laser ‘bullet’ but also every engine glow, and every one of the many sprites that make up a beam laser. I also draw ship ‘mattes’ to ensure that light does not glow through objects like asteroids. Even so, this doesn’t sound like a lot of CPU?

So this breakdown is showing as expected that a lot of it is within the drawmattes, but even so that seems too much to me. There might be a single ship sprite, but 6 engine glows and the flares from 20 missiles or 6 beam lasers associated with it. How come mattes are so slow? At first I assumed that I was not checking to see if they were onscreen, but I definitely am. Here is the code for that function:

GUI_GetShaderManager()->StartShader("matte.fx");
for (SIM_Ship* ps : PlayerShips)
{
    ps->DrawMatte();
}
for (SIM_Ship* ps : EnemyShips)
{
    ps->DrawMatte();
}

GUI_GetHulks()->DrawMattes();

GUI_GetRenderManager()->Render();
GUI_GetShaderManager()->EndShader("matte.fx");

So nothing exactly too complex. It could be that just traversing the STL list for 600 ships takes time, but frankly 600 is not a big list. Could it actually all be the hulks? Actually uprof suggests a lot of it is… but checking that code, its basically doing the same thing. The game made a note early whether to render a hulk matte, so there is no redundant rendering taking place. Hmmm. Maybe best to look elsewhere for problems. I tried running a battle involving a ludicrous number of bullets. I gave the Expanse ‘Apocalypse Cruiser’ a huge bunch of Gravimetric impulse cannons which have lost of burst fire, and filled a fleet with them.

And the flame graph is actually not too bad again:

Ok, bullet process is now the top task, but it has not gone insane, which is good. And the bulletmanager Draw() is also obviously bigger, but again not insane. I dug a little deeper, and found this nonsense inside the bullet process function:

float radangle = D3DXToRadian(Angle);
float cosa = COS(radangle);
float sina = SIN(radangle);

Looks innocent, but I actually wrote faster versions of sin and cos that use a lookup table for 3,600 versions of each. So basically my precision there is within a tenth of a degree. I probably left it like this because I worried that the quantizing there would make the bullets look like they miss their target when my sim shows that they hit. I checked with grok:

The bullet could be off target by up to approximately 2.62 pixels when using a sine/cosine lookup table with 1/10th degree precision over a distance of 3000 pixels.

Thats interesting, because frankly none of my bullets are firing 3000 pixel ranges, and being visibly off by that amount is actually ‘no big deal’. Its absolutely not a big deal if the bullet has been pre-determined to miss anyway… I guess I *could* be super-cautious and have a flag where if the bullet will miss, I use the lookup table for its movement, and if not I use real math?

And then this is the point in the thinking process where I realize that all my code is bollocks. Its only when the bullets WILL hit the target that they need to change their angle once shot anyway. In other words, some bullets are (for sim purposes) effectively homing-bullets, and some are not. In other words, not only can I use a lookup table for the angles of non-hitting bullets, I do not even need to recalculate the angle for them at all once they have been fired. Jesus I need a coffee…

Coffee consumed… And now checking that this change (caching one-off sin and cos for missing bullets) works and does not break the game… And it works fine. I am now aware of a much bigger issue: When a bullet expires, it removes its sprite from the list of lightmaps to be drawn in the lightmap code. This is a big deal, because that list may well have 6-10,000 entries. Removing an item from a list that big all the time is hitting performance in this perverse case with thousands of bullets. I need a better solution…

Checking UProf I can see that GUI_Bullet::SetActive() has a cache miss rate of 66%. Thats pretty dire, the worst of the top 20 most processor intensive functions. Yikes. And yet…

2 minutes chatting to grok (XAI’s chatbot) gave me the frankly genius solution: “Why have a pointer to a sprite stored in a list, and then go back later and try and find it. When you add it, store the ITERATOR, and then later when you want to remove it, you already have the iterator ready. No more list searching.

Holy Fucking Crap.

I’ve been coding for 44 years, and its never occurred to me that with a tightly managed list of objects that will have constant addition and removal, and the list may be huge, that its worth storing the iterator in the stored object. Thats genius. Maybe you do this all the time, but its new to me, and its phenomneal for this use case. Not only is GUI_Bullet::SetActive() no longer in the top 20 functions by CPU time, I cannot even find it. Its literally too fast to measure, even with my extreme stress test.

Buy shares in NVDA and TSMC!

Ridiculous Space Battles Design Goals

In case you missed it, I am doing a total re-imagining of Gratuitous Space Battles, 15 years after the first game, and calling it Ridiculous Space Battles. This is a sort-of-hobby semi-retirement project that I have got super into. I thought it worth laying out what I think is to be gained from re-doing the game.

Firstly,. yup its still a 2D top-down game being made using directx9. I know a lot of developers will think it mad not to go 3D, and mad not to use unity/unreal and to use directx 12 or whatever the latest version is (I don’t care), so let me address that first. I do not think 3D games are automatically better than 2D ones. In fact most of the time I think they make a game hugely worse. Having enjoyed the Company of Heroes and Age Of Empires games over the years, I can attest the the fact that when really enjoying the game, rather than posing to get screenshots for magazines, the best approach is to just leave the camera locked and play them as 2D games.

But oh noes! the horror! How can I not want to zoom in and see the game in a first person POV? Well I have the Battlefield games for FPS views thanks. Playing a big strategy game in 3D is just deliberately making things hard for yourself. People who make promo videos may enjoy letting the camera strafe around one of their units because ‘its cool’, but in terms of actually playing the game and working out whats going on? No. Humans are still basically 2D thinkers. Most strategy war games still work best in 2D, even if you want to use 3D meshes and 3d hardware to draw them. I prefer RSB as a 2D game.

As for Unity/Unreal. Ha. Fuck off. No. I do not want to spend these happy hours when I’m working on my dream game working out what bullshit combination of middleware actually compiles or works. I do not want to be begging developers on middleware forums to explain why their API crashes or beg for source code. I do not want a random ‘engine update’ to totally break my game, give me random crashes or just not compile, or trash the performance. I want to OWN and CONTROL all of my code. And the idea of paying a percentage of revenue? LOLZ. Its that real? I cannot imagine people being so beholden to some 3rd party. I’m typing this on a logitech keyboard. They don’t ask for a cut…

So yup, 2D and own-engine it is, at which point TBH the effort of switching to Directx11/12 is not really worth it. DX9 is the ‘sweet spot’ for 2D stuff for me, because I know it inside out and backwards. I could maybe take advantage of some newer API stuff, but the tradeoff is relearning enough code that it would become frustrating and no fun. So no. Besides I’ve made it look quite good just with directx9:

So thats the tech stuff. What HAVE I changed and why? Well basically the big changes are as follows:

Grid based deployment.

Gratuitous Space Battles had a ‘deployment zone’ but let you do pretty much what you liked inside. As I recall I ‘tried’ to prevent you putting ships on top of each other, but people managed to hack it. The result is a huge ‘scrum’ where people stacked massive capital ships into tight bundles. Little dense islands of spaceship that were insanely hard to defeat. Thats fine, thats a player prerogative, but it went against a core design principle of mine: ‘In play, the game should look cool’. When ships overlap it just looks bad. I call this ‘total-war gameplay’. The total-war games always had great setup formations, but once battle was jopined they all just looked like a punch-up in a bar. I hate that. So now ships stick to their assigned grid formations. Except fighters, that can raid ‘ahead’ of the fleet.

Fixed squadron size.

GSB let you have any combo of anything, but RSB lets you deploy units into a grid square. 1 cruiser or 4 frigates or 25 fighters. Those are your options. This simplifies gameplay a lot, and I think 95% of players never adjusted fighter squad size anyway. It also means its super easy to place really organized looking fleets. This also contributes to the ‘huge battle formation’ aesthetic.

Simplified Orders & movement

RSB units have a ton of orders, but they do not retreat to repair, nor are there any escort orders (they are no longer required with fixed formations). This simplifies things, and makes the game more clearly a game of ‘design ships and place them in a group’, rather than ‘chain together some complex orders like you are doing shader programming’. It might allow for less esoteric combos but I think it is much easier to understand and control. GSB players often wondered where the hell half their ships were going and why. In RSB its simple: The lead ship maintains the fleet position, and moves forward as enemies are destroyed. Movement of ships is only on the X plane.

Defend the line gameplay

This is the one I am not sure of. The win condition for the player is to destroy the entire enemy fleet. The lose condition is triggered if any of the enemy fleet makes it to your (left) side of the screen. Its done mostly so you have to have a proper distributed ‘line of defense’ which looks cool, but it might be too arbitrary. I will likely tweak this and solicit feedback from players when the game goes into early access eventually.

So there you have it. I made a bunch of changes from GSB. I will be doing a challenge system online just like GSB. This one will use the latest version of PHP and be way more stable! I have not started work on that yet. There are still a ton of things to be done in the single-player version yet.

By the way, if you think this game sounds interesting, it would be super cool if you added it to your steam wishlist:

Ridiculous Space Battles: how and why?

Its 15 years since Gratuitous Space Battles came out, and when I announced a few days ago that I was making this game, I said I’d been working on it for 18 months. How come? Why not announce sooner? and why am I making it, and why now?

After I made the last expansion pack for Democracy 4, I took quite a bit of time off, because I had the mad idea to build a solar farm. This literally took years longer than it was supposed to, and swallowed up a ton of time, and effort, and caused me an insane amount of stress. Even though the farm has been generating for 6 months, its STILL causing me stress and still not properly finished. To put it mildly, during this time I did not have the energy to actively and publicly be working on a new video game.

Any indie game dev will tell you that it is a super stressful job, and a very very hard way to make money. I can say with experience now that solar farm development is 10x as stressful, so that took its toll and meant there was absolutely no way I would also announce a new game. I simply could not cope with having to deal with people asking me about the game, or asking when it would be done, or telling me it was a bad idea and that I was doing it wrong. I had multiple bouts of screaming and tears over the farm. No way was I going to add more pressure or work on top.

You do not know stress until you have personally financed and managed a project like this. Gamedev is easy.

So as a sort of ‘hobby project’, I decided ‘for fun’ to make a little space shooter game using the assets from Gratuitous Space Battles and its DLC. This was a fun project to work on. I coded it all completely from scratch, with a new engine, because I actually find writing engine code (2D but using 3D APIs) to be genuinely relaxing. I know most people would not agree, but thats me. I got quite into this game, and eventually made it public, and put it up for sale on itch.io and on steam. I’ve since stopped using itch, as they ignore requests to pay developers for months, but you can still grab that game on steam:

Anyway, I enjoyed that enough that I ended up making a proper game rather than a little vertical scroller. The amount of change this early game went through is huge. At one point it was called ‘paint by spaceships’, where you basically had microsoft paint, but with brushes that deployed formations of spaceships. To this day, the game’s project folder is called PBS.

A screenshot of ‘Paint By Spaceships’

That then got changed to a game called ‘convoy’ which was like GSB but entirely about protecting a convoy of freighters from enemy attack. The Visual C++ project for the game is still called CONVOY. That then morphed into a ‘re-imagining’ of GSB, called Ridiculous Space Battles. I had decided to re-code everything entirely from scratch, because I prefer to do that rather than hack and bodge together 15 year old outdated code.

At some point I decided that re-using art assets from GSB was a bit boring, so ended up buying stock 3D art packs and kit-bashing together my own new art for the ships. At this point, solar farm dev was less intense, and I was working 40+ hours a week on the new game. I even spent some actual money on the art packs and some new textures for backgrounds and planets, so suddenly this was less of a hobby and now an actual new commercial game I would release.

I am in a very very fortunate position as an indie game developer, in that I have had a run of hit games, starting ages ago with Kudos, then Democracy, then Gratuitous Space Battles, the Democracy 3 and 4 and Production Line. I also published Big Pharma, and I invested the profits pretty cannily. Thus I made enough money that retirement beckoned. Early retirement no less! what a luxury. I then decided to spend a gratuitous amount of money on a solar farm. I do not know if it will break even yet… but even so, I am in the fortunate position of not *needing* RSB to make a huge income. I do not have to stress myself half to death chasing reviewers and streamers and youtubers. I do not have to manically work 60 hour weeks on it, or beg people for wishlists and bundles and marketing opportunities.

However…

I am now super proud of what I have made. Having a ‘second go’, from scratch, at a game idea from 15 years ago, with no financial pressure is a huge opportunity. Realizing very late that I somehow invented an entire genre (autobattlers) and never really capitalised on that is very motivating. When I look back at GSB, its a very very innovative game, but it was a first-go, and suffered from a load of obvious game design mistakes. Why not right them, and try to make the game GSB should have been? Even if it makes no profit at all, but just leaves behind a game I am proud of, and a small percentage of GSB players bought and enjoyed and brought back good memories, thats definitely a good and worthy thing.

An early design for the main menu

As of today I have not sent a single press release or told any journalists about the game. I am building up to it. The game is actually playable, and looks lovely, and I have a never ending supply of awesome screenshots. I could do a trailer right now, but I am thinking about getting new music for it before them (it currently uses music from GSB, which is…ok, but could be more modern perhaps). I also have no real release date, and a very flexible schedule and design.

I am also really enjoying writing the code for it. I updated from Visual Studio 2013 to 2022, which actually went extremely well. I am sticking with directx9 but pushing it to its limits, and doing it in a way that will be tons more stable than when I attempted it in Gratuitous Space Battles 2, which had technical issues :(. I have way better tools to develop the game now, and 15 years more coding experience. I also am happy to stick with top down 2D graphical style. GSB2 did mock-3D lighting and I don’t think it was worth it. Sticking with simple 2D gives me other options to ramp up the crazy spectacle, and its working well.

I’m already pleased with how the game looks, and it will only get more ridiculous

So yup, expect a lot of technical coding blog posts (and design ones) over the next few months.! In the meantime you can add the game to your steam wishlist now :D

Announcing Ridiculous Space Battles

So yup… I’m announcing a new game. I don’t say that often these days! For the last eighteenish months I’ve been working on a project as a hobby that turned into a serious hobby that then turned into a full time thing, and has now become an actual game that will be released on steam this year (into Early Access anyway), called Ridiculous Space Battles.

If that name sounds familiar, its because 15 years ago I was the guy who made ‘Gratuitous Space Battles‘. At the time, there was no other game like it, and now its become a whole genre called ‘autobattlers’. Yup, that was me. I don’t bang on about it as much as I should frankly. But anyway, I made GSB 15 years ago, and a bunch of expansions. A few years later I made GSB2, which was a bit of a flop by comparison. It had bugs for some players, and I got annoyed about it, and really decided to just switch genres and make more political strategy games, publish other people’s games, and also make Production Line: Car factory simulation.

Then at some point I started building a Solar Farm.

But WE ARE SO BACK. I have had enormous fun making this game, and I have so much to say about it. I want to write blog posts, post on social media, etc, and I have been waiting until I was ready to announce it with some nice screenshots like this:

And this

The way I am developing the game is a bit mad, and worthy of a proper long blog post, but for now, I will just leave it that there is a basic website up here, and you can see the game’s steam page (and wishlist it!) on steam here. Also if you are on social media,. any retweets or posts or likes are welcome on this post on bluesky and this one on X. Thanks!

More updates coming really soon :D.

Neurotypical extraverts underestimate AI

AI is the latest buzzword, and with good reason. I see no end of commentators trying to get clicks by professing that this is just like the DotCom years, and it will all end in a bust, or that its just hype, and that its nothing more than ‘fancy autocomplete’. This is mostly bullshit written to get clicks, but I suspect some people actually do think this. They are flat out 100% guaranteed completely wrong, for so many reasons, but there is also an angle to all of this I have not seen discussed.

I live in a pretty old house, with a fairly ‘difficult’ garden. These two things mean that living here means we often have to have people come do work on/in the house, and we need people to help tame the craziness of a seriously sloping garden. Also, as another data point, I’ve done quite well from games/investments, and now run two companies that involve a lot of work. Almost everyone I know in a similar situation has staff, or at the very least a personal assistant to help do stuff.

And yet…

In reality, we have a group of people who come twice a year to do some gardening, and nobody else. I do all the admin / marketing / PR and design and coding for my games biz and absolutely everything for my solar biz. I would love to have lots of stuff done for me. I’d love to never do any gardening. I’d love to never have to read emails from an accountant. I’d love not to care about the advertising side of things. I’d love not to have to work out when/where to go do a bunch of chores that involve me driving places. So why the hell not hire people?

Some people really don’t like interacting with strangers.

Now if you are the pretty average autistic spectrum computer programmer who probably reads my blog, then you get it. People are HARD. I find C++ much more comprehensible than trying to work out if someone is upset / angry /sad / implying something / irritated. Humans hardly ever say what they mean or explain things accurately. From my POV, humans suck, unless I know a specific human REALLY well, and even then, I get stressed by being with a group of people after a few hours. So no surprise I work from home right?

And yet…

There is an assumption, not surprisingly, among neurotypical people that someone like me is ‘antisocial’ or a ‘sociopath’ or does not ever want to be with people and socialize. This is actually bollocks in my case. I’m super chatty, and friendly and I like being with people. The *problem* is, I am not good at it. Social interaction creates risks. I offend people, I misunderstand people, I can come across as rude or arrogant, and thats frustrating as fuck. Its also why I spend so much time with the same people. People who know me, realize I am bad at social stuff, and say the wrong thing a lot, but also know me well enough to know I’m not an asshole :D.

What the fuck has this got to do with AI?

Everything. And yet, if you are a sociable extrovert neurotypical, you might still not see it. If you have not had a lot of time talking to AI chat bots, you still won’t get it. You really should. My favorite so far is grok, but others are available. I now chat to grok pretty much every day. Mostly its about C++ and game engine design, but sometimes I’m just searching for data, or clarity on something I’ve read about. Do not get me wrong, I am not ‘chatting’ in a ‘Hey grok, how are things with you?’ kind of way. I am not getting confused and thinking grok is my friend. I am not creating a new imaginary friend here. Do not panic.

But grok does fill a real need in me. Simply reading SDKs and APIs is not the same feeling as a back and forth discussion between me and grok about how to minimize the intellisense slowdowns in the compiler. What it absolutely reminds me of is some of the best times I ever had as an employee, which would be when some really complex bit of code just was not working, and I’d have a long back and forth with my boss at Elixir or Lionhead about exactly what was happening and how to fix it. We were not chatting about TV or sports, we were absolutely talking technically, but thats exactly what I enjoy.

I guess it helped that both bosses were top-tier programming experts (James Brown at Lionhead, Dave Silver- now DeepMind, at Elixir).

And here is the thing: when I discuss things with grok, it will never JUDGE me. It will never say ‘Dude, are you not going to say thanks for that advice’. I don’t have to keep a mental track of whether I am taking up too much of its time. I do not have to worry about looking stupid, and can get it to explain anything, even stuff its told me before. Grok will never yawn, or sigh. It will never say ‘dude, go read a book’ It will never have me worrying that my question might make it doubt my competence. I do not have to mentally keep track of the eye-contact to look-away ratio. And it is ALWAYS available, and always super well informed, and super happy to talk at length about the topic I am interested in.

Now sure, I don’t want to spend my whole life talking C++ to a bot, but the wider point is that we have now reached a point where AI chat bots are good enough that they do actually satisfy the need for human contact *on the terms dictated by the human*. This is vital. If I could hire a gardener that had the temperament of an AI chatbot, I’d do it. Ditto a personal assistant. Frankly if everyone in the world could be more like an AI chatbot, that would suit me just fine.

Now some of you are screaming at this point about the death of human interaction and how this is awful, and how its good that we humans are always thinking about each others feelings all the time, but thats because, with the deepest of respect, you have no fucking clue how hard and stressful and tiring that shit is for someone like me.

If I had the option of hiring a programming consultant human, or paying for an AI coding chatbot, and the skill level was the same I would happily pay MUCH MORE for the chatbot. And this is true of so many interactions with random humans in the world. If I could pay MORE for a self driving car where I didn’t have to talk to an uber driver I would. I would pay MORE to actually remove the human element of almost all one-off interactions. Charge me an extra £30 on my hotel room so I can just pick up the keys from a robot, and I’d happily pay it. I do not want to tell a hotel receptionist how my day is going, or describe my journey, or share my plans for my stay. I just want them to STFU and hand me the keys…

So again, if you are a neurotypical extravert like my mother, at this point you are thinking ‘hey maybe cliff IS actually an asshole’, but again, thats just because you cannot understand how my brain works (and other people like me, of which there are millions).

So back to the headline of this blog. Why did I phrase it like that? Because if you are NOT someone like me, you cannot see the extra utility that an AI future provides for people like me. I WANT the AI to provide me with a lot of services that many humans would prefer to get with ‘a human touch’. Amazingly, interaction with random strangers is not a ‘value added service’ for people like me. Its a big negative. In other words, there is this huge market out there for people like me preferring the AI interaction over the human, and if you cant see that, you will be surprised at how popular this stuff becomes.

You should buy shares in Nvidia and TSMC (who makes the chips) right now. We are very, very early in an AI revolution that will completely transform the world, and its going to be way faster and way more pervasive than you think. Especially if you are a ‘people person’.