I should have written this post two years ago while I was still in Wargaming Prague. But I still think about my time there a lot because it was very different from the work that I have done before or since. In this post, I want to take you to the time when I used React to build the in-game UI of the World of Tanks PC client. (If you prefer watching over reading, you can find the talk I gave about it here)

Hand drawn sketch of UI with React logo within it

Becoming a game UI developer

I started working with React in 2016 when I built a mobile app using React Native. Since then, I have worked on several React and React Native projects. I considered myself a frontend React developer and game development was the last thing on my mind.

In early 2020, I was working on an online concierge web app in Mews after working on their hotel reservation web app for over a year. Both apps were built using React. Mews had grown incredibly during my time there but I liked being there so I had no plans of changing my role. But 2020 had other plans.

Suddenly I found myself without a job as Mews tried to stay afloat. As an expat, I needed a job to stay in the Czech Republic and losing one in the middle of a very uncertain time was not a good place to be. Through some friends in the community, I reached out to several companies in Prague. But then I got a message on Linkedin that caught me by surprise.

When Wargaming Prague's recruiter, Valeriya, reached out to me about a game development role, I thought she was yet another recruiter who had mixed up the tech that I was working with. As I was about to write her back saying that they don't want me for my C++ skills, I read past the first few sentences of her message. I saw that she was looking for someone with experience in React to work on World of Tanks. I read that paragraph again to be sure. Yup, it definitely said React and World of Tanks. I was intrigued. So I set up a call.

On that call, I met my future tech lead, Michal, and I suddenly found myself entering a parallel universe where React was used not for websites or mobile apps but for in-game UIs.

What are game UIs?

Game UIs are the elements in a game that show your current status. They are also the elements that allow you to interact with and customize the game. In 3D games, these are usually the 2D surfaces that are drawn on top of the 3D scene.

Screenshot of the Hangar screen on World of Tanks PC with the UI elements marked with green boxes
UI elements on the Hangar screen of World of Tanks PC

Screenshot of the Battle screen on World of Tanks PC with the UI elements marked with green boxes
UI elements shown during a battle in World of Tanks PC

Game UIs can also be full screen as in the case of customization, settings and in-game menu screens.

Screenshot of the in-game shop on World of Tanks PC
In-game shop on World of Tanks PC

Screenshot of the settings screen on World of Tanks PC
Settings screen in World of Tanks PC

The closest experience I had to game development before I joined Wargaming was the 3D graphics programming course I took in university where we built small 3D demos using OpenGL and C++. This gave me the impression that game development was mostly about implementing complex physics using high-performance languages. Browsers and Javascript have a reputation of heavy and sluggish so I was surprised to learn that web tech has been used in game development for quite some time.

Web tech and game UIs

It is easy to forget that Adobe Flash dominated the web in the 2000s and early 2010s. I have vivid memories of my dad driving me to the library in the city where I borrowed massive operating system guides and played flash games on the library's computers. Through those games and the original YouTube player, Flash was a big part of my youth.

Screenshot of Miniclip in Internet explorer running on Windows XP
Hours and hours of my life

What I didn't know was that Flash was also powering many of the PC games that I played at the time. This was thanks to Scaleform GFx, a middleware that allowed game engines to render Flash within a game. The creators of Scaleform chose Flash because it was popular with developers and had an established set of authoring tools. The gambit paid off. Many major PC games in the 2010s used Scaleform for their UIs, including World of Tanks.

Screenshot of Crisis 2
Crisis 2

Screenshot of GTA V weapon wheel
GTA V

Screenshot of an early version of World of Tanks
World of Tanks PC in 2010

But thanks to HTML5 and Apple's refusal to adopt Flash for their mobile devices, Flash started to fade away from the web. In 2017, Adobe deprecated Flash entirely and advised developers to move to HTML5 and other open web technology such as WebGL. Shortly afterward, Autodesk, who now owned Scaleform, also discontinued its sale. This caused headaches for many game studios who now had years worth of development in a technology that was dead.

To fill the vacuum left by Scaleform and Flash, Coherent Labs entered the fray with Coherent GT. Coherent GT was based on WebKit and it allowed developers to use well-known web technology (HTML, CSS and JS) to build in-game UIs. Several studios, including Wargaming, were already using Chromium Embedded Framework (CEF) to render entire webpages in-game. Coherent GT took this a step further by integrating directly with the game engine and allowing it to render web elements onto a 3D scene.

I heard rumors within the company that Coherent GT's performance was not so great. But Coherent Labs kept toiling away and eventually created a successor called Coherent Gameface which had a custom browser engine that was more performant. The World of Tanks teams had recently picked up Gameface and I was going to be using it to build in-game UIs.

Web UI vs game UI

It didn't take me long at Wargaming to realize that game UIs are very different from the web UIs that I had been working on. Generally, web UIs are static with few animations and graphics. Minimalistic design has seen a boom on the web recently and it seems like designers are competing to put as little as they can on a page. Web UIs evolved from text documents since they were the original form of the web. There was an era when web design tried to break free of these roots but we have now settled on a comfortable norm with headers, navbars, footers and bodies with a few images.

Game UIs are a world apart from this norm. Many games have a distinct look and feel and they use a lot of graphical assets and animation to achieve a specific vibe. They are also extremely dynamic, updating dozens of times every second to reflect the current state of the game.

Screenshot of Microsoft Flight Simulator
Microsoft Flight Simulator (Uses Gameface for UI)

Screenshot of Minecraft
Minecraft (Uses Gameface for UI)

Building Game UIs using Gameface

I worked on several projects during my time in Wargaming Prague. But the one that I think about the most is the first project I worked on.

I remember thinking that it was simple. When you sign into World of Tanks, you land on the "hangar" screen where you can select and customize the tank that you will go into battle with. The team had recently implemented a daily missions mechanic where players could complete a set of missions every day to earn extra rewards. These missions were shown in a small "widget" on the bottom left of the hangar screen.

Screenshot of the daily quest widget in the hangar screen on World of Tanks PC
Daily quest widget on the Hangar screen

Apparently, this widget didn't work very well and my task was to improve it. Since it was only a list of three elements, I thought this would be a straightforward task. I was wrong.

The Gameface codebase was surprisingly similar to a web app codebase with Webpack set up to process the TSX files using Typescript and the SASS files using PostCSS. The only difference was that each screen and widget was bundled as a standalone web app since each was shown by a separate instance of Gameface called a View. Gameface had data bindings which allowed the engine to communicate with the code that was running inside a View. This was what we used to get data and send events back to the engine.

// Gameface data bindings exposed the data as globals in JS
// The values would be set on the CPP side and directly read from the globals on the JS side
tank.name
tank.hitPoints

Like a web browser, Gameface also has dev tools to help with development. A few years ago at WebExpo, I learned that dev tools in most web browsers were also web apps. Gameface made use of this and provided a localhost URL that served an instance of the Chrome dev tools which was tied to the Gameface View that was being shown.

Screenshot of the chrome dev tools inspecting a Gameface view's text
Chrome dev tools for Gameface

I wrapped my head around all of this quite easily. But what made the daily quest widget complicated was its animations. There was a multi-stage, multi-element entrance animation,

Recording that shows the daily quest widget's entrance animation

a separate variant for small screens,

Recording that shows the daily quest widget's entrance animation on small screens

and another variant when the bonus mission is revealed after the first three missions were completed.

Recording that shows the daily quest widget's bonus mission entrance animation

Getting these animations to behave as they should was a nightmare. I reworked the widget and got it to behave most of the time but I was not happy with how it turned out. React is not great for managing animations, especially when a sequence of them has to run. Implementing the multi-element animation using components that emitted events to other components using lifecycle methods led to components that easily borked themselves.

I kept thinking about ways to improve this. I tried using React transition group to improve the exit animations but I found that it didn't work in Gameface. This turned out to be a recurring problem. To improve performance, Coherent Labs had made several tradeoffs in the custom browser engine that powered Gameface. One of these tradeoffs was that Gameface only supported a subset of the HTML and CSS spec. The other was that DOM API behaved differently than it did in a browser. These tradeoffs led to head-scratching moments where things just didn't work as they should.

Eventually, I thought about using state machines to manage the animation state. I looked into XState and came up with a small proof of concept. But I didn't find the time to implement it during my time at Wargaming. That feature was done and dusted and there were always other things for me to work on. Perhaps this is why I still think about it. It feels silly to admit that the most complicated React component I have ever written is a small widget. But that widget showed me React's limits and pushed me to find ways to overcome them. I wish I could have seen whether it worked though.

Leaving the world of Game UI

Talking about my work as a game UI dev was fun. Many developers in the community didn't know that web technology was being used for PC game UIs so I often got confused looks and follow-up questions when I talked about what I did. But over time, I felt like I was getting distant from the frontend community. Most things that the community was excited about could not be applied to Gameface's custom browser engine and the custom development we had around it to integrate it into the World of Tanks PC client. New browser features that had gained decent browser support were nowhere in sight on Gameface. The obsession and improvements around page loading times were irrelevant to us as we loaded all the assets directly from the disk. New Javascript library? Well, will it work with Gameface's quirks?

The sense of secrecy in the gaming industry also caught me off guard. When I attended a gaming conference, I was surprised by how secretive everyone was about their work. It felt very different from the frontend conferences that I had been to where struggles and solutions were openly shared. At the gaming conference, it felt like several tribes had come together to size each other up. The secrecy is partly due to the studios wanting to protect the surprises they have in store for their players. The rest was due to the culture of proprietary software and strict intellectual property protection. Closed source was the norm and a closed community was the result.

Due to all of this, I started missing the web. I also wanted to try building something of my own. So at the end of 2022, I left Wargaming Prague to do just that.

Conclusion

I wanted to write this post to show how React has secretly found its way into the games that we play. If you build on the web and you would like a change of scenery, I hope that I have shown you that game development is not far from your reach. (Wargaming Prague is often on the lookout for more game UI developers). As for me, the web is the place where I will be.

Prabashwara Seneviratne (bash)

Written by

Prabashwara Seneviratne (bash)

Lead frontend developer

Similar Posts

It takes time
8 years of frontend