The Unity ports of DOOM were very solid ways to play the game, but five years after their initial release, we had an opportunity to update them. Ported to Nightdive's KEX Engine, we also were able to add PlayStation 5 and Xbox Series support, which brought 4K 120hz rendering due to a major overhaul to the renderer, adding multithreading support. We were also able to license a clean-room implementation of Boom and MBF21, making the port even more capable of playing modern WADs. Finally, an online mod database, allowing console players to get in on the fun of the DOOM modding community.
For this project, we used Coherent Labs Gameface, an HTML/JS based UI library that runs everywhere. This means that the original 1993 UI was completely torn out, and replaced with what is basically a glorified web app, but without the massive overhead of Proton and a full web browser. I was responsible for the whole UI system, from the framework to content.
The frontend also uses Solid JS, a very fast UI library that doesn't have all the baggage that React brings along. Even though we're running a full JS engine and HTML renderer, the UI still basically runs in under a millisecond each frame.
This project brought some interesting challenges. A completely custom implementation of gamepad navigation had to be written, since tab index navigation is too simple and does not have the level of control needed. Navigation supports horizontal, vertical, and grid based layouts. Handling gamepad actions uses custom events that bubble from the selected UI element upward. This lets me attach per-page handlers like previous and next page, or go back, while allowing widgets to either act as sliders, carousels, or whatever other actions are needed, without affecting other elements. Modals need to be able to pop up, and not send input to what's undeneath. All of this also needs to work with a mouse and keyboard, in addition to a controller.
The id Vault and Bethesda.net mods sections were more traditional frontend applications: image viewers, browsing through content, async requests to third party services. These were funneled through native JavaScript functions; the UI doesn't make any web requests to outside resources on its own.
What we ended up with was a simple set of reusable components, with the ability to spin up new menus, add or remove options, and generally iterate very quickly. I'm very happy with the way the UI turned out, for how often game UI programming feels to be in the stone ages, the amount of tricks I had at my disposal felt limitless.