Friday 9 August 2019

Last & Furious

In November 2017, Ivan Mogilko and Jim Reed created Last & Furious for a MAGS competition.  Unusually for AGS, it was a top-down racer in the mould of SuperCars II.  It went on to win a handful of annual AGS awards as it spoke to the versatility of that engine.  

Fortunately, they also shared the source code on github.  A previous attempt at porting it to XAGE hadn't gotten very far, as it relied heavily on functionality I hadn't yet implemented (DynamicSprites, new audio mechanism, scripted keyboard handling etc). 

As work continues on [REDACTED], I periodically return to old ports as a palette-cleanser and also to see how far the conversion tools and engine have progressed.  After a few weeks of late nights (with some additional pointers from Ivan), I'm happy to say the port is complete and now available on

Download link:  (40MB, Win x64)

This is using the latest version of the XAGE engine, running on a standalone deployment of .NET Core 3.  It is not using a CoreRT build as the .NET foundation have recently decided to instead focus on a different AOT approach for .NET 5 once it launches in 2020.  

Performance seems decent - on my 6 year old laptop it averages at about 5% utilisation for both CPU and GPU while in the middle of a race.  By comparison, the AGS version averages about 20% for CPU.  This is likely because it is using a software renderer whereas XAGE is able to offload more work onto the GPU.  I also optimised a handful of things along the way, so not exactly a fair comparison.  Where AGS still trumps XAGE comprehensively is memory usage.

The conversion process was 95% automated.  The C# generated should look very familiar to anyone comfortable with AGS Script:

There were a few manual tweaks to:
  • Correct some AGS variable type inconsistencies (as with every port).
  • Simplify some of the walkable areas, here used determine obstacles and how the car controls on various surfaces.
  • Suppress pathfinding (as everything is handled manually).
  • Change the scope of a handful of arrays to reduce the amount of garbage being generated (the game still generates a lot, but mainly Gen0, and not enough for it to affect performance).
  • Prevent new DynamicSprites being created for every single rotation - instead let the GPU handle it.
  • Force a custom texture to be stored locally (to speed up GetPixel calls).
I left in the debug hooks so pressing the usual console key (`) will open the ImGui debug console.  It should otherwise look and feel identical to the original AGS version.

As I've been working primarily on something behind the scenes, it's nice to be able to show how general engine development is progressing!

No comments: