AI War 2 v0.783 Released! “Go Ahead And Shoot Me, Eyebot!”

Release notes here.

The name of this release comes from a pair of contradictory bugs fixed in this build.  They’re best summed up by a fun savegame that HeartEater7 provided:

Longwinded Storytime

  • 200ish Eyebots and Agravic Pods of his are sitting on a planet, staring at an enemy Concussion Guardian.
  • They refuse to shoot it unless you tell them to shoot it manually.
  • Meanwhile, it has less than 1% health left and is slowly shooting at them, not doing much damage because it’s just one ship and they’re all pretty high-mark.

So… what was causing the problem?

  • The Concussion Guardian erroneously had data on it stating that massive damage was incoming from shots that no longer existed.
  • It’s almost a certainty that these shots were aimed at it when it was under a forcefield, and the forcefield blocked the shots but didn’t bother to tell the Guardian that the damage was no longer inbound.
  • Because of this, the Eyebots and Agravic pods ignored the Guardian as a potential target because — any second now! — it was about to be obliterated.
  • Manually giving them an order would cause them to go “whatever, pile on the overkill!”  And it would thus die.

The fix was fairly simple: I have the ships track their literal incoming shots now, not a cache of the incoming damage from them, and so they immediately notice when a shot has been blocked without hitting them.  If we later add some other mechanic that clears shots without them hitting a ship, this will also still work.  If the Guardian had managed to warp out of the planet via a wormhole right before incoming shots hit it, this also handles that sort of case.  So that problem was fixed, and your ships won’t ever be shy about murdering the enemy anymore.

So what happened next?  Well, this particular savegame then fell prey to another oft-reported (in the last month) bug.  Lucky for me, since it had been hard to repro otherwise.  Here’s what went down:

  • Those same 200 ships are staring down the concussion guardian when I load the save.
  • When I unpause, they all unload into it at once, murdering it before it can get off a single shot, and then they start circling the spot where it died, firing into the voice for a good 5 more seconds before being satisfied.
  • Good grief that overkill!  One light breeze would have knocked it out.  Take it easy, guys!

I had overkill-prevention logic in the targeting code, where ships would avoid targeting things that they knew were going to be targeted.  But that’s part of making a target list, which then the ships choose viable targets from for the next partial second.  Once they have the list, they have at least part of a second for some of that data to get stale (such as, in this case, one ship firing a shot that now means it will be overkilled — as soon as that first shot is fired, it’s time to stop any further firing at it.  If this was a larger battle, it would be time to shoot something else).

The solution to that was pretty easy: just add the overkill-check logic in the “get ready to fire at a target in our list” part of the code.  Then they say “he’s already about to die within 1-2 seconds, what else can I shoot?”  The answer in this limited scenario is “nothing,” so they just sit there.

In the case of a bunch of Ambush Turrets waiting at a wormhole, the situation was much different, though.  Puffin had a savegame where they would frustratingly overkill just a single ship in a volley, wasting tons of ammo while more ships poured in.  Why shoot that one guy so much!?  After this fix, the Ambush Turrets immediately and efficiently murder everything, like they were always designed to do.  Expect your turrets to be far more valuable now, along with… well, everything really.  But that goes for the AI, too.

So that fixed everything, right?  Not quite.  Now here’s what happened:

  • Same scenario with the 200 ships v 1 guardian.
  • Unpause, and a single shot from an agravic pod fires out and kills it.  Yay!
  • …and as soon as the guardian explodes, ALL 200 SHIPS START FIRING AT THE SPOT IT DIED AND CIRCLING IT!
  • Guys!  Seriously, cut that out!

But this was actually great news for me, because this meant that this was that other big bug and I could repro it 100% of the time.  Turns out that the problem here was kinda stupid, since I was able to instrument the code and see what was happening.  200 ships v 1 was absolutely ideal for that scenario.  Here’s what was happening under the hood:

  • Guardian is on death’s door, all the 200 ships read this correctly.
  • One shot is fired, all others correctly read that it’s about to die.
  • Guardian dies.  At this point, its object gets put back into the “object pool” for use.
  • At this time, the “HasBeenRemovedFromSim” flag gets set to true to let everyone know that it’s dead.
  • All is well so far.  Now it’s time to blank out it’s data so that it’s fresh to load next time as another ship, whenever it is needed from the object pool.
  • Uh-oh, like a moron I was immediately setting HasBeenRemovedFromSim back to false!  So they immediately thought it was alive again.
  • And even worse, we store health as an “amount lost,” which I was clearing back to 0, which meant that suddenly they thought it was at full health!
  • The only reason they ever stopped firing at that ship was that its object got repurposed for something else, and then they detected that condition (thanks to SquadWrapper noting the new PrimaryKeyID) and thus treated it as gone.

So… the solution was pretty easy.  First, have it not set HasBeenRemovedFromSim to false until an object comes back OUT of the pool.  Secondly, just to be on the safe side, set the health lost to an obscenely high amount so that everyone thinks the ship is dead no matter what.  Don’t set that back to 0 until, again, the ship comes back out of the pool.  Either one of these conditions should be sufficient for every reference to this ship to say “this thing isn’t valid anymore,” but having both in there just makes me feel a little more comfortable.

And now all that stuff works perfectly.  Yay!

So, What Else?

Mmm, lots of good stuff:

  • Yet more brief-ening of ship tooltips, which feels oh-so-good.  The original text is still there if you hold Ctrl, as it notes in the tooltip.
  • Improvements to the profile screen thanks to Dominus Arbitrationis, based on notes from Bobtree about how unclear that was as the very first thing the game shows you.
  • More improvements to the tutorial by Badger, thanks to a bunch of great notes by rkfg and Pepisolo.
  • Ships should no longer do that “blip into a different place for a bit” thing when they first enter a new planet, or when you first switch planets.  That was a really annoying one!
  • Ships staying selected when going through wormholes sometimes-but-not-always, in a very confusing way, is now gone.  So the “accidental orders to ships on other planets” issues should be gone.
  • Fixed the issue with really slow ships not turning to face their movement direction, and moving in a really jittery fashion.
  • Open-sourced several significant portions of the ship logic code.

More to come soon!  My hope is to focus on the view/edit controls screen, and the lobby, as probably my last main pre-EA-launch things.  Then we start EA and get working on whatever seems most pressing to people.  Only a few more days, now!

Problem With The Latest Build?

If you right-click the game in Steam and choose properties, then go to the Betas tab of the window that pops up, you’ll see a variety of options.  You can always choose most_recent_stable from that build to get what is essentially one-build-back.  Or two builds back if the last build had a known problem, etc.  Essentially it’s a way to keep yourself off the very bleeding edge of updates, if you so desire.

The Usual Reminders

Quick reminder of our new Steam Developer Page.  If you follow us there, you’ll be notified about any game releases we do.

Also: Would you mind leaving a Steam review for some/any of our games?  It doesn’t have to be much more detailed than a thumbs up, but if you like a game we made and want more people to find it, that’s how you make it happen.  Reviews make a material difference, and like most indies, we could really use the support.



AI War 2 v0.774 Released! “Five Thousand Days”

Release notes here.

Holy guacamole am I excited about this one.  Buckle up, because this is going to be a long post.  I’m going to post a video in a separate update later tonight, too.


Let’s start with the “boring” but important: looooads of bugs have been squashed in this one.  Most if not all of the carnage wrought by the performance overhauls of the last few versions has been smoothed out.  Plus a variety of longstanding issues.  There are still bugs to hunt for sure, but it’s finally a net-positive compared to the last two weeks.  I’m really excited about that.

AI Defenses

Badger spent a lot of time reworking both how the AI initially defends its planets, and how it chooses to do reinforcements… and a few things relating to offensive waves, as well.  The net result is that the AI planets really feel a lot more like they did in Classic, which makes me very happy.

Oh, quasi-related, the AI targeting (your units and theirs) is better yet again.  They won’t get caught up with metal harvesters forever anymore, etc.  And so many bugs fixed that were causing them to go the wrong place or chase the wrong thing, etc.

Map Generation Stuff!

Badger also made several new map variants for clusters, and made it so that you can finally choose how many planets your galaxy contains.  The default is still 80 at the moment… but in general I’m leaning towards raising that in the future, and making the minimum planet count and maximum planet count higher than they were in the first game.

More planets does not equal more CPU load for us, most of the time; assuming the same number of units in both scenarios, having twice the planets would actually be a quarter of the load in a lot of cases (many bits of work have a squared cost to them based on unit counts at a single planet).  Given that we’d of course have more units if we had more planets, we could still do something like 50% more units in the galaxy but at only half the cost of what a smaller galaxy would be; something to that effect.  Anyhow, that’s all just xml data at this point, so it’s easy to change later.

Quality of Life Improvements!

You no longer need to build hackers or science labs to deal with those resources on your own planets — your command stations now gather those resources, too.  You still need those units if you want to gather resources on planets you don’t control, and to do hacks on AI planets.  But you no longer need to shuffle around those guys in the basic areas.

Similarly, ALL of the objectives are finally actually showing up on the sidebar.  It was previously not telling you about data centers, or Advanced Research Stations (ARSes), etc.  There are also some additions to the tutorial, and to the beginner objectives, which also help out a lot.  There’s nothing on the galaxy map that you need to pore over the map to find anymore; it’s all right there on your objectives tab of the sidebar, waiting to be clicked to take you straight to the planet in question.

Oh right, and you can also see the number of squads per category in the ships tab of the sidebar; I’ve already gotten so used to that that I forgot it was new in this release!

Lots and Lots of Ship Renames

A lot of names for things in AIWC, or early-AIW2, have been changed.  But it’s not just cosmetic; their functions are different, and we didn’t want folks to be confused by something working differently but having the same name.

There are also some units that were just generic, like “Laser Turrets” and similar… what did those do again?  Just… basic damage, I guess?  (Yes).  Those now have distinct roles instead, and took up new names in order to reflect those roles: Laser Turrets are now Nucleophilic Turrets, for instance, meaning that they do more damage against targets with higher energy usage.  They still do great as general damage dealers, but now they have a specific niche bonus.

Advanced Research Stations (ARSes) have been renamed and split into a trio of units, too.  They are now Fleetship, Starship, and Turret Schematic Servers.  It’s kind of a lot to explain if you’re a fan of the first game and want to know what’s different, so here’s a link to the details.  But the short of it is that there’s more to capture now, and the capturing starts earlier in the game.  This gives you more units to command, and gives you more choices in what to capture versus just having to take what you find.

Lots more to come this week!

Reminder: RocketAssistedPuffin has stepped into a volunteer balancer role, and he is not only looking for feedback, but he’s actively integrating lots of things that other people are suggesting on our forums and Discord, as well as things that he’s finding and coming up with himself.  The more feedback the better, for sure.

Balance Tweaks!

Hoo boy has RocketAssistedPuffin been busy.  He’s been really fleshing out all of the units so that they fit better into the world.  The nanocaust is a lot more threatening to starships now, for one thing.  Armored Golems got a bonus tesla coil.  The Cursed Golem got a buff.  Plasma weapons got a bit of a redefine, and split into two groups (burst area damage ones, and single-target ones).  Lots of really good stuff.  Oh, and the Botnet Golem now fires 50 shots per salvo instead of 16.  GOOD GRIEF, PUFFIN! 😉

One that I snuck in there, which Keith suggested a week or two ago, is the return of brownouts.  They work just like in AIWC: if your energy balance goes negative, then all your forcefields shut off.  Note that the actual shield health doesn’t go down on anything, just the projected bubble goes away.  So the survivability of the shield generators themselves isn’t affected… but they won’t protect anything anymore.  Some of the most exciting wins that the AI would get against players in AIWC involved last-minute brownouts, and it was a big thing for players to juggle when being invaded (in a good way, not a micro way), so I’m definitely pleased to have that back.

Icon Overhaul

Part of the reason why this release took so darn long (6 days!) is that I redid almost all the icons in the game.  Well, we kept 56 of them, and added 105 new ones, and took out… I don’t know, 50?  So “almost all” is a stretch, but in practice that’s what it feels like.  The icons for most of the units beyond the basics have either been reworked to be more legible, or have been made unique for the first time; a huge number of units previously just reused icons temporarily, but now none do.

This makes the galaxy map AND the planet view AND the sidebar a lot more legible.  One thing that was often pointed out was that Turrets were basically illegible before, but frankly I found guardians and starships equally unintelligible.  I guess they only seemed clear by comparison to the turrets.

We actually upgraded our icon system a fair bit in order to accommodate this, now including a third “overlay” layer that can go onto your two-tone team-color icons.  The overlay is just colored however it’s colored, and goes over any part of the icon that we want it to as we design them.  The result is that now “starships” all share a same backplate, and then little sub-images make it clear what KIND of starship it is.  You don’t need to be able to see the details of the little sub-images, even, because their vague shape and color is enough to differentiate them.  But they all have sensible details if you get up close.

Here, let me just show you:

One of the coolest things about the icon overlays is that I can do things like what you see with the Military Orbital Command Station you see there: it has a colored shield icon inside it, rather than some sort of little flair or whatever off to the side.  But then if you look at the turrets on the sidebar, or the starships also there, you can also see the icon background is the same, but the little marker is different.

The bump to usability this has caused is just crazy, and I’m super stoked about that.

Shot Visuals Overhaul

Basically, almost all the shots in the game got a rework, and they look better both up close and far away, AND perform better.  It’s about time these felt like a proper space battle!

One of the nice things about this change is that it actually helps with the ability to read the battlefield.  You can tell quite a bit about who is shooting, and what kind of shots they have, based on the colors and shapes you see going past during battle.  This was my major project over the weekend, and it really makes things feel so much better.  The nature of shots is something I came up with for this game, too, and they’re insanely performant.  I’ve had 30k shots onscreen at once (plus 10k ships) at 120fps on a GTX 1070.  Our shots are done in a way that their deformation is on the GPU and yet we’re still able to make use of GPU Instancing, so the CPU load of them is comparably low.  That code isn’t new, but we’re making much better use of it now.


The last of the pre-Early-Access ships have now been added to the game.  Auto-Bombs have been added as a player-only ship, thanks to Puffin.  The Warbird Starship and Parasites are in, making a return from the first game also thanks to Puffin.  SuperTerminals and Co-Processors have been added in thanks to Badger, leading to yet more targets out in the galaxy to go for.


Yep, we made even more strides on that front.  There ARE, however, still some savegames that are frankly intractable performance-wise.  They’re late-game situations with huge AIP counts, and basically should be losing situations.  But rather than just getting it over with, the simulation slows down and the targeting loops take up to 50 seconds at the moment on my machine.  Normally a targeting loop takes under a third of a second.

So what to do?  Well, I’d hoped to get this in this release, but I wound up just getting the framework in.  Tomorrow’s release will hopefully have them: Unit Stacks.  Basically, there will ALWAYS be a point at which a galaxy is able to become intractable if players push things far enough.  That’s just a given, since hardware isn’t infinitely powerful.  We had players spawn 30 million ships into a campaign in the original game using cheats, for instance, and that gives you a framerate of 1 frame per 20 minutes in that game, roughly (I’m not kidding).

So anyway, there has to be a “pressure release” valve somewhere.  People will always exceed what we have planned since there aren’t strict unit caps.  In the first game, we mostly got around that by having AI Barracks and AI Carriers, and what we called “cold storage” for AI units that were on idle planets.  The new game is a lot more efficient in general and hopefully won’t need those sort of measures.  But something a bit more elegant has occurred to me, and is my focus for tomorrow: as I said, Unit Stacks.

Basically when there are too many ships on a planet, the game will go through and combine like with like, bringing it down into realms where your computer can do the math in a timely fashion.  Each stack of units that gets combined will have a little multiplier number right on its icon in the main view, and on the side view won’t show differently at all.  There are a few more nuances there, but mainly it will just keep the performance from ever getting runaway bogged down and the game from having an over-abundance of icons in a meaningless way.  Basically I was thinking about Civ IV as an inspiration.

But more on that tomorrow!

So What’s That “5000 Days” Title Mean?

It’s a bit of a lame joke on my part, relating to the fact that I changed some of our 64bit integers into 32bit integers.  If you want some technical junk, read on.  Otherwise, feel free to skip this section.

Basically, Keith and I both come from business software backgrounds.  In such an environment, we’re familiar with situations where the limitations of a 32bit integer have been hit (that’s about 2.2 billion).  So basically, if Amazon used a 32bit integer to track orders, then after 2.2 billion orders their system would break.  Evidently in 2015, they shipped about 5 billion orders via Amazon Prime, so that gives you some sense of scale of what we’re talking about.

Well, we were tracking ships, and shots –and even the number of fifths-of-a-second a campaign has lasted — all as 64bit integers in order to avoid that sort of problem.  I don’t know the name of this number, but this is the largest a 64bit integer can store: 9,223,372,036,854,775,807.  Is that quintillions?  I think that’s what that is.  Anyway, that’s an unimaginably huge number, as if 2 billion were somehow comprehensible in a meaningful sense to us.

64bit math, even comparison operators and addition, take a lot longer compared to int32.   In this table, it’s showing the nanosecond costs of various operations of ints (32bit) versus longs (64bit) in C#:


As you might notice, the mere addition of a long is 5.6 times slower than the addition of an int.  To check time, there are lots of situations where we have to do things like “if ( Now > LastShotTime + 5 ).”   So the shift to an integer is a nontrivial amount of speed boost when spread across the literally millions of operations that we do of that sort in one second during gameplay.

The downside, however, is… bum bum bum… there’s now a time limit on campaigns in AI War 2.  I’m sorry to tell you this, but you cannot run a given campaign of the game for more than about 5000 straight days (24/7/365) before it will break.  (Note that this is NOT something to be concerned about, it’s a joke I almost regret sharing, probably most games have a similar limitation, it doesn’t limit things across campaigns, etc, etc).

To put this into perspective: 5000 days is 13.69 years.  Of continuous running, just one campaign ever, never turning off the power or adjusting anything.  Arcen isn’t that old.  I didn’t start coding the original AI War until just under 10 years ago, and it didn’t release until almost exactly 9 years ago.  I will go out on a limb here: if you can’t win your campaign in one hundred and twenty thousand hours, I think you need to choose a lower difficulty for your next campaign.  Also: do drop me a line, since it’s now the 2030s.

The joke, as it is, is basically at Keith’s and my expense.  We both somehow felt quite concerned about the limitations of a regular int, as if we’d hit the cap on that and the game would die.  (As it stands, even in the new version I have it cycle back around if it passes 2 billion shots or ships created in one campaign, so that it can’t break on that; yes I’m that paranoid).  The idea that we’d ever approach those sorts of numbers really shows that even the gut feel of math-inclined programmers can really be way off when it comes to what a billion means.

Well, I’ve thoroughly derailed these release notes now…

The End!

That’s it!  There’s lots more to read in these release notes, but I don’t have anything more to say about them here.  There should be another release tomorrow.  Lots more to come in the next few weeks.

Thanks for reading!

The Usual Reminders

Quick reminder of our new Steam Developer Page.  If you follow us there, you’ll be notified about any game releases we do.

Also: Would you mind leaving a Steam review for some/any of our games?  It doesn’t have to be much more detailed than a thumbs up, but if you like a game we made and want more people to find it, that’s how you make it happen.  Reviews make a material difference, and like most indies, we could really use the support.



A fantastic conversation.

Just general forum humor.

BadgerBadger: What does “lerping shots out of ships” mean? I know larping, not lerping.

Keith: Please, please don’t let the shots larp.

Cyborg: The AI will now say, “Lightning bolt!” before each attack.

Chris: “I’m attacking the darkness!”

Keith: 20,000 MkV Gazebo Guardians to Murdoch in 0:32…

Chris:  My favorite version of that skit:

Hey, do you remember the Gazebo monster we put into Valley 1 as a bit of an easter egg? Most of the Gazebos were harmless, but a tiny minority were absolutely deadly murder machines.

I completely forgot about that. 🙂