A new User Interface
It is one of those things which are inevitable in software development: mistakes are often obvious in hindsight.
If we go back several years, I decided that writing my own User Interface library was a good idea. This was a valuable experiment in a number of ways, providing valuable insight into the complexity of such a system: how do I bring fonts in? How does input need to be implemented in a multilayered system? What about popups? How difficult can it be to get the text in a text box wrapping correctly?
If I was just making an engine for fun and experience, that decision would have been fine. However, since I was actually trying to ship a game with it, that was a mistake. This mistake was further compounded by a reluctance to upgrade the UI system to allow for dynamic reloading, which meant that building and tweaking interfaces was very time consuming.
However, with HEXTERMINATE staying in development for the foreseeable future, there will be a substantial amount of UI work that will have to be done. For my sanity, I’ve decided to finally bite the bullet and layer a more advanced system on top of the current UI, allowing me to modify new UI elements on the fly and store the design as a JSON file.
This has allowed me to fairly quickly iterate on the main menu, bringing it to a much higher standard. Here’s the original main menu:
And here’s the new one:
Modifying a shipped product
Since HEXTERMINATE has already been released, there are some considerations as to how new, large updates are handled. I could write the new UI from scratch, but that would mean no updates for a long time, as all the pre-existing user interfaces would break and they would all have to be re-implemented before a new build was made available to the public.
Instead, I am building on top of the current system. This will allow me to swap in new UI elements over time, improving the quality of the build over several updates. Writing UI code is also not something I find particularly satisfying, so this split also also helps with managing motivation as I can mix in work from other areas.
The disadvantage is that there is clearly “the new UI” and “the old UI”, but it is a compromise I find acceptable until the old UI is completely phased out.
A quick look behind the scenes
The old UI was entirely created in code. Each UI panel you see in-game would have a wall of code behind it like this:
m_pBackground = gAllocate( Gui::Image ); m_pBackground->SetSize( backgroundWidth, backgroundHeight ); m_pBackground->SetPosition( ( screenWidth - backgroundWidth ) / 2, screenHeight - 200 - backgroundHeight / 2 ); m_pBackground->SetTexture( pBackgroundImage ); m_pBackground->SetHiddenForCapture( true ); m_pBackground->Show( false ); FrameWork::GetGuiManager()->AddElement( m_pBackground ); m_pDockingText = gAllocate( Genesis::Gui::Text ); m_pDockingText->SetFont( EVA_FONT ); m_pDockingText->SetColour( EVA_TEXT_COLOUR ); m_pDockingText->SetSize( 340, 64 ); m_pDockingText->SetText( "Press 'F' to dock" ); m_pDockingText->SetPosition( 197, 111 ); m_pBackground->AddElement( m_pDockingText );
Any changes to the UI would require changing the code (e.g. move a checkbox 2 pixels to the left), then compiling the game (which takes roughly 30 seconds) and finally launching the game again and getting back to the place where that checkbox was visible.
As you can imagine, this was very, very time consuming.
With the new UI, spawning a new element and defining the hierarchy is still done in code, but most other things are now done with an in-game Property Editor.
The Property Editor lets me find modify exposed properties (such as position, text, colour…) on the fly, without having to go through the modify code → rebuild → run loop. As mentioned earlier, the final layout is saved in JSON.
Improving ship movement
In HEXTERMINATE, ships have a fairly limited movement range: they are capable of moving forwards and turning. With the Reverse Thrusters perk, they’re capable of moving backwards at a limited speed, while Evasion Protocols provides the ability to dodge sideways on a very low cooldown. Finally, a ship can use Ramming Speed to charge forwards and deal substantial damage on impact.
This makes it easy to quickly get into the middle of a fight, relying on heavy armour and shielding while dishing damage. However, there are several issues with it:
- Evasion Protocols is all but essential. Due to the boost amount and very low cooldown, you can move very fast with it and it can lead to some silly behaviours, such as the space equivalent of bunny hopping.
- AI ships which orbit around their target struggle to adjust their distance due to the lack of fine control. And they don’t use Evasion Protocols, either.
- Ships that do try to get close have no way to keep to their optimal range. Ideally ships want to keep their targets at the maximum range of their weapons, as getting closer than necessary can bring them into the field of fire of shorter range, higher damage weaponry.
- As Ramming Speed is currently a multiplier on the ship’s thrust, lighter ships using it can move very large distances in a rather uncontrollable manner.
To address these issues I’ll be looking into making the following changes:
- Evasion Protocols will now have a single, longer cooldown (rather than two cooldowns, one for dodging left and another for dodging right).
- The thrust multiplier applied by Evasion Protocol will be reduced. It will still be of benefit to heavier ships, allowing those to get out of the way of the way of ramming ships or Particle Accelerators.
- The perk Reverse Thrusters will be removed. The ability to fly backwards will become a core part of the ship’s movement.
- The ability to strafe left and right will be added, also as part of the core movement. It won’t move the ship nearly as fast as Evasion Protocols, but definitely assists with keeping on target.
- A new perk (called Thrust Vectoring) will increase the effectiveness of sideways / reverse movement.
- Using Ramming Speed will be rebalanced for lower mass to weight ratios, making lighter ships easier to control.
- The AI will be updated to use the new improved core movement to better keep distance.
A new build will be coming this weekend, which will include the work so far in the new User Interface, as well as the changes to ship movement. Changes to the AI will come in a future update, as I am looking into some larger scale changes on that front.
The plan going forward is to have a regular release cycle, with an update a month (barring any patches if I notice something important is broken) as well as a blog post so you can see what’s being worked at.