This development blog is going to focus on the re-design that happened when moving the engine from 2D pixel-art to a 3D view. It’ll be a bit technical, rather than mostly design problems. We suggest a strong espresso before continuing.
Moving Objects from 2D to 3D was a fascinating challenge. Some parts of the rendering code I could keep – some of the ship screen interfaces I could keep, but the major difference would be that I was not rendering them directly to the screen like this:
But instead rendering them to a texture as required and switching the texture of the monitor object in the rooms. Now, the previous way the game worked was that you could switch most screens to fullscreen mode (with the kludgy temp button you can see on the top-right above). This caused an issue in 3D.
Rather than going fullscreen per se, we did the (we felt) natural thing of simply letting you left-click on a screen to take control of it, and then animating the camera in as if you were moving closer to the screen to use it.
It ads a nice fluidity to the controls – left click always takes you into a screen or uses a UI element on said screen, and right-click takes you out. This way, almost the entire ship can be controlled using only the mouse – with keyboard shortcuts or interfaces for text terminals being the only exception.
Back to the point of this blog, though – I began to realise that my 2D prototype, unshockingly, was a terrible bit of code for building UIs. Really bad. See, being a prototype… it was all hard-coded. Each button you see above, each nav element, was a manually constructed bit of code.
This was time-consuming, and given we wanted three playable ships at the beginning, with their own user interface styles… it wasn’t going to fly (no pun intended). So I re-thought my plan, and what I did was this:
Meet the ship control screen. Looks much like the same aesthetic & interface we had above, no? Well, the major difference is the way it’s rendered. None of this is hard-code. This is the configuration file which generates the above:
It’s that simple. The linkto indicates which ship subsystem it relates to, so that it can show damage, turn off, indicate an error, etc, as the component it’s hooked up to takes damage.
Each UI element is a line, with positions, sizes, parameters, data feeds (for example, %.0f^,MOTION_ANGLE pumps out the current motion vector of the ship in degrees, with a precision of zero points.
UI elements can have existence checks, too. For instance, there are two identically sized and positioned buttons, reading ‘Burn’ or ‘Stop Burn’ depending on the state of the main drive. One appears when MAIN_ENGINE_BURNING is set, and one when it isn’t using the ! flag.
Even simple aesthetic elements, like the ship layout image or the border around the IFF segment can be drawn using these config files.
As for all these values & checks, identified by text strings, I simply have a ship Interface system which looks a bit like this:
…coupled with this…
Every time I add new ship functionality, I just expose a few more logic checks, data outputs (numerical or text), and ship command methods (such as FIRE_MAIN_ENGINE or DEACTIVATE_IFF).
Once the code is in place, I add in another UI element and give it a whirl.
This has the advantage of letting us design very different panels with a myriad of looks and buttons, try out the feel first, and even if the functionality isn’t in place we can just have the buttons and checks redirect to NONE or ALWAYS, and see how it feels.
It’s made development a lot easier, and gives us many more options for future ships and interfaces.
I’ve even exposed all these logic checks to 3D objects in rooms, too. Which lets us do something like this:
The blue button is the EMCON mode button. Its texture changes and it depresses when you click it, and its state is determined with the same logic. Above it is the reactor scream switch, and to the top-left is the multi-textured Christmas Tree – a simple way to check the status of the four most important things on your ship.
In the case of our Ceres-class Freighter, which we’ve focused on, these are physical switches. But for more fancy designs, they can just as easily be on a display somewhere, or remain in physical space outside of monitors.
The best part is – the more hooks I put in, the easier and more detailed our interfaces can become, making iterative ship interior & interface design much, much easier.
Yet another reason why the move from our prototype to a properly-thought out interface has made Objects in Space’s development so much easier.