Set Engines To THRUNT!
10 November 2016
The last week or so has seen some decent progress in Thrunt. I expanded the test level to roughly mirror one of the stages in the original Thrunt. This was a level called “Fanny Hole,” which sees the player weaving between the blades of turbines, each one rotating slightly faster than the one before. Here’s a video comparing the two versions:
I’d placed it relatively early on in the level roster of Thrunt: fifth of about 14 stages if I recall correctly. It teaches a specific skill in ship control: slaloming at speed. Despite being quite short and simple it was actually seen by many players as one of the harder levels to complete. That surprised me at the time. It just goes to show how hard it is to judge a skill-based game’s pacing and difficulty curve when you, as the developer, inevitably become an expert. This is something I intend to correct in the final version, by listening to player feedback, and providing many more opportunities to learn the basics of control in easier environments.
Hand-Tuned For Speedrunning
One thing that’s still as true as ever is that Thrunt is a game about flying fast and taking risks. It was always my intention from the very earliest version of Thrunt that carrying speed through the levels should reward the player. Sure, obstacles can be tackled one by one, and players will inevitably start out with this approach. You have to learn the layout of new levels and the timing of the moving parts before you can go for the fast times. But once you know where you’re going, you can start to look for places where speed makes obstacles flow into each other. At this point, yes, you’ll crash a lot. You’ll swear a lot. But when you get it just right the payoff is a rush of success, and a chance at hitting the target times which usually seem impossible.
They’re not impossible. The formula is simple: they’re my best times plus ten percent.
So after getting most of the collidable obstacles into the new Fanny Hole I spent an evening testing, refining, tweaking. It takes a long time to hand-tune the levels for speedrunning. The speed and initial position of every obstacle has to be set precisely, based on the ones before it, to open up a sort of minimum-energy solution for the level. Furthermore, the path has to be open enough to be inviting to the player, but tight enough that any delay is punished.
Speedrunning through Fanny Hole HD is now at least as hard as the original. Here’s the last 17 seconds of a 10 minute bails video…
One thing I wasn’t happy with in the videos above was the engine flames. In my mind I pictured them as a sort of blue-hot afterburner cone, but the early attempt at this (seen in the videos above) was far from perfect. Last night I implemented a much better version that captures the look I intended much better. Here’s the video:
If you’re not interested in the technical details, you can skip to the end now…
I was using a simple particle effect, with very fast but short-lived particles smeared out by velocity dependency. The main problem was that the velocity inherited from the player ship was never quite tight enough. If you were thrusting in a straight line it wasn’t a problem, but if you were traveling quickly along the X axis while thrusting perpendicularly, along the Y axis, the particles would appear to lag behind the engine and be rotated slightly away from the direction of thrust. You can see the problem quite clearly in the speedrun video above. The particles themselves also didn’t look right, more of a flickering cone than a smoothly dissipating flame.
So last night I had a think about a better way, which I’ll explain. I realised I wanted the particles to follow a curved surface, so they’d blast outwards then be smoothly pulled into a point. I also wanted a constant glow near the engine nozzle itself. Most importantly of all, I wanted them to be so fast that the shape of the flame is essentially fixed with respect to the engine.
Here’s what I do now. First, I render a little mini-scene into an offscreen render target. This scene contains a simple blue gradient quad and two particle systems – one fading blue to yellow and the other plain white. It’s rendered by a separate camera with orthographic projection, and then has bloom and motion-blur applied to it. This uses a floating point texture and HDR-happy additive blending. The offscreen texture results look like this:
Then, I created a 3D model of the flame shape I wanted. This is UV mapped so that the seam is around the back, but untextured. In Unity, this is scaled a bit and attached as a child of the player ship, as shown:
The render target of the secondary camera is then used as the texture on the cone, and the final effect is again rendered with additive blending so the HDR bloom of the main camera will give it a nice glow.
There’s a few small issues. The transparent shader doesn’t write to the depth buffer in time for the depth of field effect to correctly keep the effect in focus. I intend to see if I can do a depth-only render of the flame hull during the rest of geometry rendering, but this would then cause the background to be incorrectly in focus. I could also potentially render the effect to another separate render target and composite it in an image effect that would sit after depth of field in the post processing chain. However, the added blur actually looks quite nice, even if it wasn’t what I originally intended, so I may just leave it as it is.
A bigger issue is that the whole thing will clip through thin geometry. There are two possible ways around this. I could generate the geometry of the flame cone on the fly by raycasting many probes against local geometry. Or, more likely, I can use the single raycast result that’s already generated for the dust kickup effect to fade out the rendering of the offscreen particles and glow at an appropriate distance. This wouldn’t be as accurate and would still have issues with corners, but most remaining error would likely be covered up by the dust particles. A more accurate but still reasonable approach could be to use a cone-trace against the geometry, or perhaps two additional probes by raycasting at the edges of the cone, and using the three results to provide a heuristic measure of the local geometry, which could be transformed back into the space of the particle effects and used to mask off the portion that shouldn’t be rendered. I dunno, some more experimentation needed here.
I’m pretty happy with the result though. I might later pre-render the two particle effects into a sprite-sheet and just use a looped animation. That would eliminate the need for the offscreen target, but it would also make it harder to introduce cute dynamic variations to the effect, like a little burst or sputter when you enter and exit cruise mode, or a slightly more gradual transition between on and off – it currently just shows or hides the flame mesh accordingly when you thrust. It would also be harder to apply the dynamic clipping against local geometry. Ultimately I’ll have to keep an eye on graphics performance, perhaps swapping the dynamic effects in and out depending on the player’s PC grunt.
That’s a later question though. For now the goal is to make it all look as sweet as possible before hitting Steam Greenlight in the new year. At the moment, trailer content is king.