uGameDB Overview

uGameDB is a complete database solution for the Unity game engine especially tailored for networked games. It consists of the uGameDB client which is tightly integrated with Unity for unmatched ease of use, and the Riak back-end database which adds an entirely new level of scalability.

Scalability and ease of use are central to game developers and Riak provides the scalability to extreme levels while the uGameDB API provides ease of use. MuchDifferent's choice of developing on top of Riak as the uGameDB back-end was made after a thorough evaluation of many similar products. We found the Riak team to have the best combination of passion and industry background and since Riak is based on Erlang, we felt very comfortable with assessing and working with the code since we have used the same platform for many of our own scalable, concurrent and reliable server products. As a game developer however, you do not need to know Erlang or go into depth of how Riak works to use uGameDB to its full potential. The uGameDB client does all this dirty-work for you.

The back-end database can be shared by any number of game servers and can also be used by the uLobby system, or any other entity that needs to read, or write, persistent game data.

Reliable and scalable

Networked games often have many game servers that run for long times and need access to persistent data. If the database becomes unavailable it is likely that the game becomes unplayable. This can be very costly for a long-running online game, and severely hurt its reputation.

The Riak back-end database is a distributed database solution that focuses on reliability and scalability. Instead of using a single database server, any number of Riak nodes work together to form a Riak cluster that shares the responsibility for the data. If one node crashes or becomes unavailable, the cluster will keep serving data. New nodes can be added to the cluster to increase capacity, without having to stop it for maintenance. Data is automatically replicated and balanced over the nodes for the best performance.

Like any distributed database, Riak and uGameDB deal with transactions and consistency in a different way than traditional SQL databases do. Because of this, you need to program your database reads and writes in a way that handle situations where the data is not perfectly consistent. Doing this right allows great scalability. There are several practices that help you handle these situations and we will help you with writing well-designed code and to design good data models. Please be aware that the uGameDB API will never add transaction locks or enforce consistent data models to Riak.

Simple data layout

In the Riak database, data is stored as key/value pairs and organized into buckets. A bucket behaves as a named container for any number of key-value pairs. A bucket can be seen as a namespace for avoiding that keys clash with each other. Keys are of string type and values can be of any data type.

Query operations are performed via Riak’s powerful MapReduce system and is specified as JavaScript code. Queries can be performed on both keys and values, and result in a list of desired data entries. This enables the programmer to make queries such as "List all swords at this merchant that cost less than 5000 gold" or "List all players with a PVP level no more than five from the player's own level".

Integrated in Unity

The uGameDB client provides a very easy-to-use interface for making requests to the database, and uses Unity coroutines to make the handling of parallel requests with a minimal amount of code. This means that the game server’s database code becomes simpler to write and maintain, with less risk for bugs.

When a request is sent through the uGameDB client, some time will naturally pass before the response comes back. By harnessing the power of Unity’s coroutine functionality, uGameDB lets game developers write their database interactions in a fluent manner, which keeps the logical interaction sequence together. By communicating with Riak from a coroutine you can easily write request in sequence or in parallel, wait for the response of one request before sending the next, and manipulate the request as it is in transit, all within the scope of one coroutine method. You can even combine or replace the coroutine pattern with conventional callbacks. In addition to coroutines, the traditional callback pattern is also fully supported.

Flexible

Any data type can be serialized and stored by uGameDB. Whole classes and nested types can be serialized automatically without any extra code, either as JSON data or as tightly packed binary data. When working with large complex classes, game developers may not want to store them as a whole. uGameDB makes it easy to define your own custom serialization for a type, only including the members that actually need to be stored.