Creating a browser-ready first-person shooter MMO in Unity presents massive gaming opportunity but also a set of unique client-server challenges. Join the developers from Aquiris Game Experience and Electrotank as they discuss the hands-on lessons they learned in creating an upcoming free-to-play FPS MMO for PC/Mac and the browser.
31. 09/29/11 Account Avatar Loadouts Loadout Items Game Items Classes Aquiris Game Studio | Amilton Diesel, Maurício Longoni, Raphael Baldi
32.
33.
34. Networking Topology 09/29/11 Acount Server Game Node Game Node Game Node Client Client Client Aquiris Game Studio | Amilton Diesel, Maurício Longoni, Raphael Baldi
Hi everybody, my name is Amilton, I'm Technical Artist and I planned the visual features. We always want the game look beautiful, doesn’t matter the platform or genre. In Critical Mass we could improve lots of art standards previously stablished by Bootcamp. There were three main concerns when we started to develop the graphics. The first one is : considering Critical Mass a huge project, one of the most challenging parts was create an artwork compatible to its complex structure. How to organize everything in order to work with lots of different pieces, scenes and network limitations. The second is : how to develop premium graphics, that could be compared to big titles in the market and have a lightwheight performance at the same time. Or at least, give players a good range of parameters to tweak quality settings. And third , and the most challenging one. How to deliver everything in very small packages. Able to load from a browser in acceptable times. Well, that's something we're going to talk probably next year, because honestly, we didn`t go through that yet. Yes, the standalone versions come first in this case. And we're not going further in concept art because of course, we have a limited time so...
That's one of the big questions when doing games. Large spaces and unique artwork are quite opposite. The perfect balance between them will give you the correct real world feeling, and optimization. Our assets, weapons, items and character artwork doesn't have a special feature to solve that. Because their function is basically to fulfil the unique artwork side. For the large spaces we used a very common concept in FPS games, which is the basemesh modelling.
The BSP is responsible to give any space we want in a level. All the props and unique artowrk will be connected to the BSP somehow, giving the balance we need. It also reproduces the main idea behind a level design. This single piece has a different modelling and texturing technique. And is designed by two different professionals, a level designer (who plan spaces thinking in gameplay only) and an environment designer (who create the visuals, respecting all gameplay features previously created by the level designer), both need to see the big picture at this moment.
It was important to support from the very low end to high end machines. And the average could experience smooth graphics and nice frames per second at the same time. So we created our own paramerts to fit the game and 5 presets. On the first time you enter the game, the best preset will be set, considering your video card memory and shader model. After that you are able to change presets, create custom configurations and save how many you want.
Hi, I’m Raphael, Lead Programmer at Aquiris and one of the main developers on the game Critical Mass. As I don’t have much time I’ll talk briefly about the main topics on developing a MMO FPS. I believe the main challenges you’ll face during the development of such a huge game are related to asset control and networking, but also to game design tools and user data. So I’ll focus on these topics. If you have any questions, I’ll be glad to answer them at the end of the talk and when I’m available during the conference.
First I’ll talk on how we’ve solved the Asset pipeline issue from a tech point of view as Amilton had explained it from art side. As we have a large amount of weapons, items and maps we needed a way to automate the import and build process. We also needed ways to decrease game’s memory footprint.
When we started the development of this title we noticed that we were experiencing many bugs related to things not being properly configured. After some meetings with the art guys we planned a way to have assets automatically imported and configured inside Unity. We, as Amilton told you, developed a directory structure to be followed by the entire team. With this directory setup in mind we developed tools to handle the asset import pipeline. Unity provides ways for us to handle Asset pre processing and post processing. This way we were able to create prefabs and to setup almost everything with reduced amount of bugs. We are not using the fully automated process anymore as it was becoming harder to detect assets that needed to be reimported. Developers can still use it by manually selecting weapons and items that need to have it’s structures rebuilt. This way we still have the ability to setup weapons and items automatically but also have the human intelligence to detect when and what to import.
Here is an example of the import system interacting with weapons. As we can see, designers and developers still have to place a lot of stuff manually, but as the system creates prefabs, materials and scriptable objects we made the configuration process rock solid. Another thing that deserves attention is that we are using Unity’s animation importer, that’s why you’ll see animations named as “object at animation”. This way animation clips will get properly named.
As you may know, Unity has a great feature called Asset Bundle. It is a structure that can contain portions of your projects or asset collections, being them GameObjects, scenes and almost anything you want. We’ve used them extensively during the development of this game. At first we believed that the creation of these asset bundles for weapons and items should be done during game build. After some time it started to make the build take hours instead of minutes and its really hard to test something when you spend so many time building. We decided to make some custom tools so we’re now able to build just the portions we want, reducing the overall build time and parallelizing the build of asset bundles. We can have multiple machines, each building some items, weapons and maps. In our roadmap there is also a tool for automatically building the project and assets by using the available command line tools in Unity. This way we’ll be able to schedule builds that will happen with no human interaction.
And here you can see the screen where we can select what will get built. We made it simple so anyone on the team is able to use the builder.
One of the biggest issues we experienced during the development of our FPS game is related to memory control and optimization. By using Asset Bundles we have a more accurate control over what is loaded, what is not loaded and methods to Load and Unload stuff anytime we want. We’ve built some controllers from where any code in the game can ask for assets to be loaded and unloaded, centralizing operations and making it easier to debug. For maps we have a custom loader that will also unload the related asset bundle as soon as the player goes back to title menu.
To make it easier to understand I’ve compiled an overview of the system. Item controller also has an internal cache system where it keeps assets that have been requested recently. After the assets have been used, the game lets ItemController acknowledge this and the AssetBundle can be completely unloaded from memory. Next time we need it again, it must be loaded from disk first.
As we’re making a FPS game we have a bunch of variables that need to be balanced by our handsome Game Designers. At first with thought of using XML files to let Game Designers setup weapons, for example. Using external files would increase the amount of code using exclusively to control these files. Then we decided to use Unity’s built in Scriptable Objects. These objects acts almost like prefabs for custom classes and they get saved when modified during Play mode, wich has been of great use for tweaking weapon balancing for our game. We’re using Scriptable Objects to setup weapons functionality and specify items.
Each weapon has a lot of configuration files, each related to one of its behaviors. Here you can see the Scriptable Objects related to the M16. Game Designers have a bunch of parameters to setup, but also a great flexibility to make almost any kind of real world weapon. If we were using XML files you can imagine the amount of work for serializing and deserializing data.
Levels are configured with Game Objects placed on each map. After Game Designers finish their job the system creates an XML file that is distributed within server’s files.
Here you can see the generated XML file for all available maps. As I’ll tell you next, the only valid map setup resides on server and Unity is just used to make the configuration process easier. During play time server sends back to clients the correct configuration to be used.
When playing an FPS such as ours users expect the game to track their kills for each game session and allow them to level up progressively from one match to another. In our case each user has an account which is used to control stuff not related to the gameplay, like username, password, bans, and every other user related statistic. Each account also has an Avatar associated with it. We had two options available: allow users to have more than one avatar, each individually configured. Or give him a single avatar and create loadouts. Loadouts are presets of avatar configuration and we allow an user to have 5 customized loadouts. The main issue using avatars is controlling statistics. As our game has 5 classes and we’d like to keep track of user progress for each of these classes, it was better to keep them centralized in just one data structure: the avatar. In order to make it simple for database design, weapons, items and all other in game stuff has been converted into “Loadout Items”. Those loadout items belong to a single avatar and contains information about the item they are related to, be it a weapon or a helmet, for example, as well as statistics about the player's usage on that item.
Here you have an overview on what the game data relationships looks like. Later on Jonathan will explain you how EUP was able to help us improving our initial design and giving us tools to control all this data.
Now I’ll give you an overview on our network decisions. As it’s a huge game I won’t be able to go deeply into network development. Fell free to join me during the conference to know more. Jonathan, from Electrotank, will tell you how their solutions were able to solve our design goals on the servers side.
We were planning to develop a pure peer-to-peer game at the beginning. We found that it would take too much time to understand how this kind of system works. So we’ve fallen back to the traditional client-server architecture, but then a new problem arrised: we wanted to have up to a hundred matches running on a single server instance, with almost two thousand players connected as well as having a central Account server for each region where the game is going to be published. You can imagine the amount of data being transmitted, and the processor power needed by server machines. One of the solutions was to have almost everything computed on the clients with the server still computing everything too, except for physics, so it has the “real” game state. This way we were able to reduce the amount of data being transmitted even if the server still needs to correct players from time to time. We are also using UDP connections to send back and forth player state updates. Those are related to player’s position and animations. For all other crucial data we are using TCP connections. We also needed a server solution capable of running on Linux, to reduce costs. As you can see, we gave Electrotank folks a lot of trouble!
The final network topology we’ve planned looks like this. Thanks to EUP and ElectroServer we were able to achieve what we wanted! This schema describes what is going to be deployed on each region where the game is going to be published.
Channels are a way to split users into a server reducing traffic originated on services such chat, room list updates and user list updates. Each channel can have multiple rooms, created by users, where the matches occurs. They can be password protected an hold all the information about a specific game. Having this kind of subdivision we were able to optimize communications and data flow: you just receive updates for the room you are in and for the channel you are in.
Ending our talk on client development, I want to give you an overview on how the game interacts with server. We’ve created a transparent network layer that is capable of handling connections, network errors, and translate data from server to client and vice-versa. This way game developers don’t need to know how things are working. Every time server sends a message it is propagated to game code by using .Net Events. When the game wants to send something to the server it just raises a Network Event. We’ve based our development on Unity’s built in Network features. Finally, we’ve used ESObjects, available as part of ElectroServer API, to transmit data, even across game features. As you’ll see, Electrotank has done a lot of work to reduce ours, specially to take out from our hands the boring job of serializing and deserializing data.
By the end of the development cycle it’s time to integrate the game within the existing Publisher tools, like Accounts, stores, log systems, payment and others. One thing to keep in mind is that you shouldn’t make your game dependent on external system architectures but must be able to communicate with them. What I mean is that your data structures must be related to your needs. In our case, we developed custom tables and transactions to handle operations and communications with publisher’s system. If their system changes we just have to code the interface again and not the entire game. Now I wanna call Jonathan, from Electrotank, to tell you how they helped us with such great tools as ElectroServer and EUP. Thanks
Just a recap of the previous slide, filling in EUP and the ES5 Node roles
Flexible scalability - Ramp up more nodes when you need them, turn them off when you don’t. Save money
Nodes are allowed to dynamically register with EUP. Nodes can be shutdown when no longer needed, may map to a physical or virtual server. Nodes are the ‘host’ to the match, and have authority over most of the high-message rate action and positions. They determine ‘kills’. EUP handles persistence of EVERYTHING.
As your team size increases, being able to produce reliable builds becomes more difficult and more critical. This can be compounded if your team is distributed across many timezones.
This forces you to start thinking about all the issues that surround deployment of content.
The larger the codebase, the more difficult it will be to comprehend. Reduce or eliminate code where you can.
Protocol generation is a win/win. You avoid one of the most tedious and error prone parts of network programming. Automation lets you take advantage of protocol efficiency improvements globally with low/no refactoring cost. Developers get strongly typed messages. Avoids errors, confusion when dealing with a large game, 100’s of message types.
“ Tools will make or break an MMO” quote from Christopher Dyl, CTO Turbine. At least, this is how I remember it.