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:
- 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.