Day: July 2, 2018

AI War 2 v0.747 Released! “Improper Handling Of Forcefields”

Release notes here.

We remain back on a quicker release schedule, now that we’re past that initial hump of the pivot.  At this point there’s a fair bit to clean up, though, so I’ve been focusing on that instead of heading straight for the lobby revamp.  I’m pleased with the progress that we’re seeing, based largely on the excellent testing and feedback we’ve been getting lately.

This build fixes up the nanocaust and risk analyzers (read: spire civilian outposts replacement) so that they’re functional again.  There are more new units from Keith, and then a grab bag of fixes and improvements from Badger and myself.

I again wanted to mention: we have a new Steam Developer Page.  If you go there and follow us, you’ll be notified about other upcoming releases (including this one, of course).



Postscript: Technical Investigations of Performance

Today has been a bit of a funny one, for me.  I’ve spent a fair bit of time looking into SIMD, in particular Unity’s new ECS/Jobs system, but also System.Numerics from Unity’s implementation of .NET 4.6.  Doug originally turned me onto SIMD a while ago, but you had to manually include Mono.simd.dll, which made me nervous in a multi-OS environment.  Since then, user “dv = i ln(w0 / wf)” has turned me on to the ECS stuff.

I’ve been heavily considering my options on this, now.  I need better performance out of the vis layer of our game, because right now in a midsize battle I’m seeing some performance bottlenecks on the CPU side where it’s doing calculations to decide what models to send out to the GPU, what to cull from the view frustum, and then of course vector and matrix math.

I’m not sure which is the more expensive thing at the moment on the CPU, the culling and whatnot or the vector/matrix math.  I have a feeling that the culling is the killer, but the unity profiler is nonspecific enough (the very act of profiling causes a skew in the results of the profiler; repeated calls of small methods are weighted more negatively than a few calls to actually-more-expensive methods because of the overhead of instrumenting) that I can’t be sure.

I’ve been talking about switching to DrawMeshInstanced forever now, but I’ve not been excited about having to do the frustum culling manually in C# — the logic is simple enough, but I worry about the performance hit of it.  Potentially now if I use System.Numerics to get fast SIMD-based math, it won’t be an issue anymore.  Plus I can adjust the frustum culling to only work at the squad level, not at the individual mesh level, which would be a big savings in the number of checks in any case.  It’s just a fair bit of work without a guaranteed payoff, so I’ve kept putting it off.

I think that the time has more or less come for that this week, though.  I’ll probably dip my toe into this with shots, and then move on to ships and squads.

The benefits of ECS/Jobs are notable in that it lets us forego GameObjects and then push things to being multi-core.  And that is attractive, but it’s not meant for production environments yet and the syntax there is horrific in my opinion.  It has a lot of advantages in the core functionality of things being very well-ordered in memory, but that comes at the cost of readability and heap-flexibility in exchange for stack usage.  Frankly I think that I can cut out GameObjects on my own without doing that, and keep everything away from expensive virtualized methods just like they do, and stick with something that is vastly more readable and maybe 80% as performant.  I just pulled that number out of my rear, but it’s a gut feel based on reading their specs in detail today and being aware of the sort of performance I’ve seen in other similar situations in our other titles that were largely GameObject-free.

So I think that means I’ll wind up wierding things in terms of making our own C#-based pooled objects that then use DrawMeshInstanced, and which use System.Numerics for calculations, and that should be a pretty good translation.  I might start out without frustum culling and see if that’s “good enough for now,” and then add that in later if need be.  Or sooner than later if it’s a problem, I guess.

I keep going back and forth on whether or not we should make the leap to Unity 2018.2 or not even though it’s still in beta.  That has a more mature version of .NET 4.6 in it, which would be useful for my purposes.  It has a few other benefits, as well.  It also includes the Scriptable Render Pipeline (SRP), which I’m very interested in.  I’m particularly interested in the potential savings of the Lightweight Render Pipeline, but I’m REALLY not sure that it will be much savings in our particular case (since we only use one directional light as it is), and I’m not super keen on re-coding all my shaders to work with that only to then find out there’s some issue.  Other developers have complained that it’s still not lightweight enough in general, anyway, since apparently some of the culling work is still a bit non-ideal.  With DrawMeshInstanced I’d be bypassing that anyhow, so my gains would be even less, potentially.  It is open source, which is really nice, but I’m also concerned about compatibility.  Most notably with Amplify Bloom, which I don’t know if it functions on the lightweight SRP or not.  It’s really hard to get non-flickery bloom without that particular product, so I wouldn’t want to just move to the regular post-processing stack v2 (believe me, I’ve already tried that a ton).

So there’s a lot of food for thought that I keep mulling over.  Biggest hitters are probably DrawMeshInstanced and getting rid of so many GameObjects, then changing to having System.Numerics in place, so for now I’ll start there.  I’m pretty sure that even if I went to ECS/Jobs eventually, I’d still need to take this approach for truly excellent performance in the vis layer, so I think I can do this with a pretty high degree of confidence I’m spending time on the right thing.

Now I just have to start ripping into that…