× Phaseshift FCOM Tutorials

Massive refactor on Phaseshift: Evolved for 0.0.5 release!



PS:E sheds it's prototype code for more performant and improved architecture.

The entire codebase has been re-written and optimised, and creation of new assets and features can commence! Of course this project was built upon a prototype - that said the code wasn't bad...(just I'm a perfectionist) and I want to create a game on top of a solid well-designed foundation. All (most) of the game design and data structures are in place so adding assets should be a lot easier in the future.

As a bit of fun, I test with 100 pilots simultaneously, each with Homing Missiles (6 each to be precise) to stress test...got an average of 120FPS overall so happy with the results! 

12, 16 or 24 pilots will likely be the norm going forward depending on chaotic races are when more features and track types are supported. Pleased at this stage how performant things are, and hopefully will only get better the more things are optimised.

HUD


To break up the mammoth amount of code I had to write for this version, I worked quite a bit on improving the HUD UI. I had completed a few mock ups before with static imagery, but now most of the dynamic elements are in play. As with most new features, especially UI (as it's an area I particularly enjoy) I like to soft launch, play test over a long period then iterate where necessary. I'll add in things like kill logs, skill logs, fuel meters and podium position rows when I have a better feel for the gameplay balance.

Start of the HUD construction, a lot more to add!
Start of the HUD construction, a lot more to add!

The HUD marks a bit of a departure from the style of the first Phaseshift. This style has a more traditional look, while combining some elements from FPS style games. The armour/shield pips will vary depending on the health status of the vehicle, and will animate in an obvious way when hit or damaged. The HUD this time around is to be more driven by simplicity and accessibility rather than maximalist cyberpunk interfaces. Please note that the artwork is of course a placeholder for now!

Scenario Builder


One part of this version was to create tool to help debugging and testing going forward. The scenario builder was one of them, it enables easy creation of crazy settings or modifiers to help stress test or log gameplay interactions. This will be vital when I built the AI proper, as this will have a lot of different interactions with the environment and other players -which I have a LOT of ideas for!

The current singleplayer scenarios menu
The current singleplayer scenarios menu

With every new scenario created (yep, you guessed it through a simple scriptable object creation) it will automatically populate this menu so I can create builds, wing 'em to my mates and test them out.

Assembly Definitions and Hiccups


I'd like to start using these spaces as more of a blog of sorts, detailing my difficulties with each version to better help myself (and hopefully help others!) with the various challenges of game development. The reason why I wanted to refactor so early was to help speed up the development process; create tooling, reduce code compile times, create scalable data structures, reduce code compile times and REDUCE CODE COMPILE TIMES. Seriously. Things were getting out of hand, and my project hadn't even gotten that large. I'm using Unity 6000.0.41.f.1 and my word the compile times are quite frankly ridiculous. I could change a comment in my code and it would take 2 minutes to load. As I intend to spend I don't know, maybe another couple years on this project, that is a lot of time wasted to wait for Unity to compile. So I checked out Assembly Definitions, which seemed to be the solution. In short, they helped. 

So Assembly Definitions help by telling Unity how to organise and compartmentalise your code. The caveat is that you have to design your code AROUND these assembly definitions. Each definition is essentially a file you create in Unity, and you set it up by telling which parts of the codebase it's dependent on. These dependencies NEED to be of a waterfall style of hierarchy, you run into all kinds of issues if you have cyclic dependencies (essentially a code dependency loop). If you have spaghetti code or scripts that reference each other you're going to run into problems. Saving that compile time during each saving of a script was worth the massive refactor...or so I thought. While I don't regret completely changing the design ethos behind my code (it is exquisite now) the assembly definitions didn't work as well as I had hoped. The more granular you break up your code, the better the compile time. The drawback is that your IDE can struggle to find definitions for methods as it's all in their own sealed little boxes, hampering productivity. Once I saw this drawback, I decided to cut back on how granular I portioned my code. I think I reached a happy medium where things are nicely portioned and self-contained within their own spaces.

All runtime code is now data driven, which is ironic considering I decided against Netcode for Entities earlier on because I had to completely change my code architecture (though I still believe I'm not there yet!) Using this method and a 'waterfall' style of code has made things so much easier to follow and debug. All data structures for static code have also been written and hooked up, and I'm really pleased with the results. Everything uses ScriptableObjects drastically improving scalability as well as performance. Settings files are also in ScriptableObjects, as are defaults - so creating entirely unique sessions and physics variables can be done by just changing a few values on a ScriptableObject. 

An example ScriptableObject of fan-favourite Kyro, with all the juicy stuff blurred!
An example ScriptableObject of fan-favourite Kyro, with all the juicy stuff blurred!

This is an example of an AI ScriptableObject, of course everything is subject to change, and the personality traits will define how the algorithm effects their inputs and behaviour in session. AI was my favourite thing to work on in Phaseshift, and am excited to expand on their intelligence in PS:E!

FMOD Priority


One massive problem I had been battling with is FMOD. I use FMOD as an audio engine, and have been a fan of it since I did Audio Engineering at uni. However a weird issue would arise in the build of the game, with many of the sounds being inaudible. After a couple days debugging I found the issue to be when you set 'priority' on a sound. As there are 24 instances of engines set as highest priority, this seemed to assign an immovable memory slot to this sounds, meaning other sounds could not play in and out when rockets or boost sounds were played. Meaning the engine would not allow that allocation, and not allow it to play. Not how I expected it to work, but all sounds are now set to priority medium!

The source of all of my audio related pain
The source of all of my audio related pain


Going Forward


So all in all, I am pleased with this update even though there weren't massive gains as far as assets or features. I did enjoy writing the code for perhaps the first half (was A LOT of work!) and I am aware of the time gains down the line with the framework now in place. 

Going forward then I want to work on building team liveries and designing how vehicle building will work. This will form most of the 'look' of the player vehicles in game and general aesthetics. I want to add some of the signature Phaseshift look from the first game, while maintaining a bright, warm colourful PSX palette. My attention will be mainly drawn to the resolution of the textures. I've done a lot of research lately on scaling of textures when using a pixelated point filter style of rendering. Some games looks great, while others look a bit disjointed, and a lot of it seems to be because of the difference in scale and resolution detail. I think with the current visuals it works; using low res textures, and then have the lighting engine do a lot of the heavy lifting. I intend to create a system of unlockable liveries that fit with the Phaseshift world and liveries much like Wipeout, Fast RMX and similar titles do, as opposed to full, unlimited control like Phaseshift did. It was far to easy to make something look awful! 

The aim is to allow players to select whichever liveries they like from the ones they have unlocked. Sponsors and decals can then be laid over the top of them to improve look and customisability. Of course vehicles are fully customisable; cockpits, engine/rear blocks, wheels and boosters can all be unlocked, purchased and mixed and matched to create your perfect vehicle.

Refactorv0.0.5


Jul 17, 2025
  • Static data structures all defined for teams, characters, vehicle parts, themes and more
  • All code data driven, improving debugging and readability
  • New HUD UI to improve player feedback
  • Added primative save data and session data objects
  • All settings are in ScriptableObjects for easier testing and defaults
  • Particle FX on vehicle destruction
  • Minimap blip is now coloured according to team
  • Removed all redundant files
  • All code tidied, organised, namespaced, assembly definitioned and commented
  • Fixed FMOD priority bug
  • Improved error handling and debugging
  • Added scenarios, a single player challenge builder with preset settings to challenge players (or let's be honest test the game)

Liked this article?

Please consider sharing!
Author

Josh Lyell

Game Developer

Other Combat Racing games

A futuristic bike races past a logo of the game titled Phaseshift

Phaseshift


Developer: Bubblehead Game Dev

Genres: Combat RacingRacingAction

Platforms: PC


Release date: Apr 8, 2022