GUI in the game World of Tanks. Part one: evolution of game interfaces
Today we will give an excursion into the history of the development of Graphical User Interface (GUI) in the game World of Tanks.
The game went a long way to success, and its GUI changed and was completely redone several times in pursuit of the increasing demands of an army of tankers, which was growing steadily.
Having worked in the GUI Programming department for two and a half years, I got an idea of how the interface itself developed in technological terms and how the approaches and processes changed, this development accompanied.
First Steps: Using BigWorld Tools
It all started with the fact that in December 2008 the idea of the project was born. Everyone who played tanks, I think, know that the initial idea was to make a game about elves and orcs, but when we thought it over carefully, we decided to stop on tanks (see the main photo).
The game began to be made on the BigWorld engine, which provided its own set of tools for creating a GUI. We took the path of least resistance and made the first interfaces on the BigWorld GUI.
How it worked in terms of technical implementation:
- XML declaratively described the structure and visual part of the GUI;
- general layout for a large view - styles of the view itself and a set of the main blocks that made it up, described in XML;
- each of the blocks is described in separate XML indicating the styles and components used. For components, their settings were specified (naming, localization messages, style links);
- styles were described in separate XML files, where sizes, positions, textures, fonts, colors, z-order were set and God knows what else;
- when the client starts, all these XML files were loaded in Python and parsed, after which the process of creating interfaces, their initialization and connection to the game logic began.
Here is an example torn from the bowels of an SVN project:
hangar.xml - description of UI blocks in the hangar:
account_info components/account ... fitting components/fitting
account.xml - description of the block with account information:
account_name ElideRight #tips:hangar/account_name ... account_exp #menu:hangar/account_info/experience #tips:hangar/account_exp
styles / common.xml - style description for common components:
styles / hangar.xml - description of the styles for the components in the hangar:
Everything seems to be very structured and understandable. But, as it turned out, this approach had several disadvantages:
- work with multilevel XML is difficult to understand and led to a large number of errors that are difficult to localize and fix (for example, typos in the naming of components and paths to textures, violation of the structure of the XML document);
- lack of a visual development environment. The only way to get a visual result is to launch the game client and recreate the necessary environment to view the desired interface. Imagining how all this would look by looking at XML was simply unrealistic;
- poor performance when processing user input (this was especially noticeable in the chat);
- a small set of components from the box and the difficulty of adding new components;
- high involvement of programmers in the process of creating and making changes (even minimal) to the GUI;
- lack of an animation tool.
All these minuses led to the creation of interfaces in the style of Programmer Art. According to a schematic sketch, programmers did layout in XML, and only then did the artists create the necessary textures and pass everything back to the programmers for final setup and peeling. Here is an example of such an interface (in the photo - the workplace of the project manager Alexander Shilyaev with a tank client launched at the stage of a closed alpha test):
One of the first versions of the combat interface:
And a slightly later version:
Very quickly it became clear that this approach was a dead end . An analysis of the middleware market was conducted. As it turned out, the mainstream in GUI development at that time was a solution from Scaleform: almost all AAA projects used it in development, and the results looked very attractive.
Prerelease period: transition to Scaleform
Scaleform suggested using Flash for GUI development. In fact, the solution consisted of three parts:
- custom implementation of Flash Player, which could be embedded in the game client;
- a set of tools for exporting SWF to a specialized format;
- CLIK component libraries - a set of standard UI components and classes that accelerated development.
In autumn 2009, a license was purchased, and a new stage in the development of GUI in the project began. At first, everything looked promising: the Flash development process was worked out for years, and there were a lot of developers who knew and loved this process. However, it turned out that the situation on the labor market in Belarus at that time was such that most Flash developers were already sitting on interesting and “fat” projects, and it was difficult to quickly find and attract quality personnel.
For this reason, the entire GUI department began to learn Flash urgently (before that they did php, Java and were engaged in web development). We studied and started working on ActionScript 2, since Scaleform at that time did not yet support ActionScript 3. Here's what happened at first:
For six months, the entire hangar interface has been redone on Flash. As I already wrote, the Flash development pipeline is a proven and logical process. Designers create sketches, and programmers embody them in the game.
In February 2010, a closed beta testing of the project with an already updated hangar began. But the battle interface was still in Python:
In the spring of 2010, it was his turn to switch to Scaleform. When this happened, the gaming community was divided into two camps. Some liked everything (or they just did not notice much difference) - and they silently continued to cheerfully chop into tanks. The rest began to lay mountains of bricks at the address of the "bloody potato", saying that the new sights and interface elements do not correspond to the setting, that there is a lack of torn metal, bolts and rivets, that the sights should be historic, and not like space controls by ship.
One of the working sketches of the new combat interface:
Implementation of the combat interface on Scaleform:
But over time, the dissatisfaction has passed, as the new interfaces have brought a lot of new to the gameplay. The game has become more dynamic, intuitive and informative.
In addition, the use of Scaleform has opened up possibilities for customizing interfaces. Any student who knows how to work minimally with Flash could decompile SWF from the distribution of the game and change everything at their discretion - from the images and fonts used, to the logic of the code. Mods appeared that replaced the sights with historical ones, the “doll” of the tank with a more brutal or, conversely, minimalistic one. You could find mods for any part of the interface in battle. There were also mods for the hangar: watches, calculators, a multi-level carousel, etc.
Wargaming management has changed its attitude towards mods several times. At first, since these were isolated cases, they were simply ignored. With time and an increase in their number and popularity, they began to look closely and realized that some of the mods could give a gaming advantage to the player using them. Development began to lead on the principle of "client in the hands of the enemy." This, of course, does not mean that the players are our enemies. Our task was to maximize the safety of players from other people's attempts to gain a gaming advantage.
The situation on the mod market began to be carefully monitored. Now, in the event of detection of dangerous or modifying the game balance of the mods, we quickly respond and close the possibility of their use, changing the logic of the client. Over the past few years, making honest mods has been supported. In fact, this is user generated content - players make these mods for themselves and other players, which adds value to our product.
But back to the story. Working with Scaleform greatly refreshed the GUI and gave impetus to its development in the project. The functionality grew and became more complicated during the passage of the closed and open beta and the release of the project in release in August 2010. New features were added, existing ones were improved and twisted. The design has changed, different approaches to the presentation of information in the game and the organization of interaction with the player have been tried.
Technique filter implementation options:
Post-release: growth problems and solutions
With an increase in the number of code and assets, various jambs began to creep out.
Marketing Scaleform overtook the actual development of the product and, as it turned out, many of the declared features either didn’t work as they wanted, or they hit hard in performance, or were in their infancy. A lot of work has been done to improve the performance of the Scaleform player, both on our part and on the part of the technology developers.
The increased amount of code led to an interesting special effect. Each view (or window) lay in its FLA, contained its assets and code, and was compiled into a separate SWF file. There were a lot of such SWFs, and at runtime they were uploaded to the client to display the desired window or control, and, typically, the load order could change depending on what the user was doing in the game.
The problem was that if the code used in several SWFs changed, and after the changes, not all of these SWFs were reassembled, then the following could happen on runtime. The first one loaded SWF with outdated code, and at best everything worked as before, and at worst, the client crashed. It was difficult to understand what exactly leads to such results. We had to come up with tools and techniques that allowed us to track what we needed to rebuild after the changes.
There was also a problem with the quality and consistency of the code and the use of various patterns and programming styles. This happened because Flash development in the project was started by people who were not professional Flash developers. They taught Flash “in battle”, and each had their own background (C ++, php, Java). It turned out that when working in different parts of the project, it was necessary to switch from one approach to another.
Another pain was the interaction of Flash with Python. It was possible to transfer data in any direction only in the form of primitive types, which, of course, did not satisfy our needs. There were two solutions: use JSON or decompose all complex types into long arrays at one end and collect objects from the other arrays at the other.
The first approach worked well when the objects were small. But with an increase in the size of objects, the volumes of the resulting lines grew, and this affected the speed of code execution - it fell. The second approach worked quickly, but was difficult to understand when reading the code and required titanic efforts to implement changes in the data structure.
By the time all these problems started to slow down development, Scaleform had already brought ActionScript 3 support to an acceptable level. A plan was ripening for us to transfer the hangar interfaces to a new version of the language and at the same time to restructure the project and create our own framework, which allows us to quickly and according to certain rules add new functionality to the project.
Work on preparing the transition to ActionScript 3 began in late 2012. How we solved the problems facing us, and what tasks we set.
Problem: Problems with different versions of code in different SWFs.
Solution: all application code is compiled into one SWF file, which is loaded when the application starts.
Problem: Communication Flash <-> Python.
Decision:Switch to using the Direct Access API. This mechanism allows you to transfer complex data objects using automatic serialization / deserialization of them at the level of C ++. Also, the use of this approach increases productivity due to the fact that links to Flash objects can be transferred to Python and manipulated directly in Python, instead of searching for the desired object in Flash along the full path to it whenever data is needed.
Problem: standardization and unification of code.
Solution: we implemented a service infrastructure and defined sets of interfaces and base classes, implementing which new functionality is added to the project.
Problem: automation of assembly and adding new functionality to the project.
Decision:for assembly we use Maven. The project was restructured and divided into more logical subprojects and subsystems. To automate the addition of new functionality, we used YAML as a language for describing the Flash and Python interaction interfaces. Based on YAML, the code is automatically generated during assembly and the necessary entities are created - both in Flash and in Python. All that remains to be done is to write the code and determine the entry point to launch the new functionality.
So, in September 2013 with the release of version 8.8, the lobby of the game was completely redone for ActionScript 3.
That's all for today. Read more about the project structure and future plans in the next article.