GALAHAD 3093
Mech-based Hero Shooter
Description
GALAHAD 3093 is a Mech-based multiplayer Shooter developed in Unity. Sophisticated custom multiplayer netcode. Procedural Mech motion. Extensive use of compute shaders and many advanced Unity engine-specific techniques. My text is not wrapping the way I would expect, so I am adding some longer line here just to try and debug what is going on.
Advanced, custom netcode
Fully procedural motion synthesis
Custom Effects System
Custom Match Making
Nakama backend (meta game)
VOIP Integration
My Contribution
Like virtually every project I've worked on, I was the lead from concept through completion. I was the lead developer, involved with every aspect of the client and server development, from netcode to compute shaders.
Some notable aspects of this project:
Effects and Compute Shaders
The large-scale battles, with heavy effects, were simply not possible with Unity's various built-in particle systems. Two techniques were required to maintain frame rate:
1. Unity Particle System Batching
The default way of using Unity to render particles involves placing an emitter in the world and having it manage its own particles. This is great for quickly setting up explosions and bullet hits, etc. But it falls apart when you have a whole lot of this going on.
To make this performant, I innovated a technique where a single particle emitter could pose for any number of emitters of a given effect. Within certain constraints, which were pretty adaptable to the types of effects a game like this has, I could reposition a single burst-style emitter to every place an effect needed to go off. The emitter would, in essence, batch all of its particles together for a massive speed-up in terms of computation and rendering.
Compute Shaders
Some effects were just too much for even this the above technique. In particular the animated fire and and smoke effects. For this, I created a compute shader that acted as a very greased-rails particle system to simulate animated fire, smoke and embers.
The compute shader managed fixed buffers of these objects, animating the sprites and the ember particle physics. All of this was batched together for extremely fast rendering. Since smoke is opaque, sorting was required. Traditional sorting techniques are not parallel-friendly (thus being excessively slow on GPU), so I used a form of bitonic mergesort. Keeping the number of these fires to a fixed max of 256 allowed me to avoid the merge part of the sort while maintaining all of the parallelism.
Procedural Motions
Our Mechs had to be able to navigate arbitrarily complex 3D environments. Traditional animation techniques, even with post-IK fixups would just not work. So I crafted a procedural motion system that allowed the leg and foot placement to adapt to the Mech's motion in real-time. This involved many interesting challenges such as augmenting an off-the-shelf IK system to support prismatic joints (a very uncommon joint type in off-the-shelf IK systems for some reason).
Figuring out how to determine proper foot-fall locations as the Mech rapidly (and chaotically) traversed the free-form terrain was the bulk of the problem-solving. A lot of sensing the world around the Mech, and specifically the feet was required so I employed a lot of parallelism in my physics queries. Additional logic was required to carry through momentum in the chassis and keep the whole thing looking natural. As Mechs are wide-stanced, proper solutions were impossible for a lot of circumstances these machines would find themselves in, but fortunately we could augment the Mech legs with thrusters to handle most any circumstance. Scifi to the rescue!
Custom Netcode
We developed our own custom netcode that was extremely robust, adopting state-of-the-art techniques for lag compensation and robustness. This code had to be very fast.
Custom Server
Originally we attempted to use Multiplay as our server farm. We found their solution to be a poor fit in many ways. For one thing, they sort of assume that you had no idea how to write quality code and would just kill your server if it was running for any significant length of time. They just assumed, strangely, that your server was locked up if it didn't just vanish all the time. So much of their code was built around restarting servers (if you wanted it to or not) that we got tired of fighting that battle.
Obvious Mutliplay works, it just wasn't a good fit for us. So we created our own server infrastructure that was much better behaved and manageable.
Custom Matchmaking
Again, no solutions out there really worked the way we wanted. We built our own system onto of Redis, with custom functions running in the Redis server to do proper matching and load balancing.
… and much more!