The story of the non deterministic Replay

September 26th, 2016

This is the story of how I discovered my simplified replay system wasn’t so deterministic as I believed because I had an ugly bug, but read the post if you want to know where exactly.

While integrating the lockstep engine on the game I am working on, I decided to do something to save and load replays to be able to easily reproduce some bugs I was experimenting. After I had that done and working, it was pretty awesome to see I can replay the same game multiple times (food for another blog post by the way), however, I thought it could be fun and easy to play them faster, why not.

Since I have a fixed time step logic, it should should be pretty straightforward, simply use a multiplied time and then the fixed timestep logic would do all the work and the game logic shouldn't notice the change. I decided to give it a try and it worked…. almost, when playing the replays at higher speeds I noticed some visual differences but I wasn’t totally sure (it could be interpolation code).

To verify, I went back to the test project, where I had the moving box, and test it there, but I needed some way to be sure. Since I have already a way to calculate checksums of the game state, I used that to verify the game states when playing replays at different speeds (from 2x to 16x).

It failed, even though it only failed to validate some frames, following frames were not necessarily invalid (this is something important to consider).

invalid-state Image 1: It shows one of the best tools in the world to check game states when replaying a game.

So, I was right, I saw some differences, I could be sure that something was happening. The thing was, with only the checksums I couldn't know what the real difference was. Next step, making something to detect it.

In order to do that, I had to change to start saving (at least for debug) the game state, not only the checksum, and to check differences between stored game states in the replay and the current game state (when replaying the game) when checksum validation fails. It worked too, now I have the exact place where the differences are.

invalidstate_realdiff

Image 2: It shows why serializing all the game state in one string is the best thing to do in your life.

After testing it a bit, I noticed another curious thing, the game validation wasn’t always failing given the same replay and the same speed. That gave me a hint that the problem was probably not related with the game code itself (the moving box).

So, if I played the replay at 1x, it was validated properly. If I played the replay at 8x, it failed, most of the time, but not always. So, it seems there is something related with speed I don’t understand yet.

I decided to test the same replay but with Unity timescale modified, my first test was using 1x for replay but 5x for the timescale, validation failed, then the opposite, 10x for replay but 0.1x for timescale, and it worked well. So the problem seems to be related with my accumulator logic inside the fixed timestep logic?

Some test cycles later, it turns out that, it was indeed a bug in one of the core classes of the engine!

The problem was on my class LockstepFixedUpdate, the first version was overriding the Update() method and performing lockstep logic, it worked ok if only at most one fixed update is processed, but in the case a big delta time arrives, it only process lockstep logic once for the first fixed update and never again.

That means that, in case replay commands were to be processed in frame 3, we are in frame 1 and a big dt of 10 frames arrives, then lockstep logic checks only in frame one and never again until all 10 frames were processed. This bug even bypass the lockstep!

Since I made a test to replicate the bug, it was really easy to fix it, I changed to process the lockstep logic with each fixed step updates and it works fine now, I have high speed replays!! YEAH!!

Conclusion

In the process of finding this bug I started to expand the engine support and create better tools, this is really important if I want to build something solid over it.

The only way to detect issues as soon as possible is to iterate over the engine as soon as possible and to do that, use cases are needed and games provide the best use cases. In my case, I am using not only the game I am trying to make but also other similar games as references when deciding what I want and how I want to test it, for example, having replays, being able to play the replay at different speeds, being able to save the replays, etc. Also, being able to replicate a bug in a small test case where you can iterate quickly to fix it is super useful.

Detecting (and having) problems like this in a small and simple game gives the idea of the complexity of a medium to big game, all the variables and the difficulties, it is not something to underestimate, so when developers say they couldn't add multiplayer features to their game because it was really hard to do it, it is not a lie.

I love all of this stuff, even though I understand it is not an easy path.

To complete this post, here is a video showing a prototype of how I load and play a replay which was created by playing with two players in LAN, one was my computer and the other was my phone:

The quote of the day is 'Fail as much as possible, as soon as possible to avoid failing when it is too late'.

Hope you enjoyed the journey.

VN:F [1.9.22_1171]
Rating: 0.0/5 (0 votes cast)

What to consider as game state when validating a simulated synchronization.

September 19th, 2016

One really important thing when performing a synchronized simulation is having a way to check if all clients have the same simulation state. In order to do that, it must be clear which parts of the game state are important for the synchronized simulation and which parts aren’t. Obviously, this depends a lot on the game.

The idea of this blog post is to talk briefly about what is normally an important value for a game, and what isn't.

What is not important for the game state

Let's talk first about what is not important for your game. Even though it depends on the game, there are some common things that shouldn’t be considered as part of the important game state.

These things are normally all the stuff that doesn’t affect the game outcome, in other words, all the stuff that could be removed from the game and the game will be the same. For example, the smoke particles coming out from a bonfire, or even the current playtime of fire sound effect.

Also, things that could be derived from important gamestate even though they could affect the outcome in some way. For example, the units health bar current fill percentage could be derived from the unit health, that value could be used by the game logic but since it is directly derived from other values, it is not considered important.

What is important for the game state

All the things that could affect directly the game outcome are important for the game state. If you have a way to restore the game from a saved state, you have to be able to finish the game the same way each time you restore it.

For example, in a game like Doom, if you save and load you have to have the same health, armor, weapons and ammo, you should be in the same world position you were and enemies too, with same health, etc.

In Starcraft, what is important is your current vespene gas and your minerals since that decide what you can build or not, your current units with their health, your structures and their queued orders, the revealed map, etc. Things that are not so important include the blood in the ground when your units die (if you are playing Terran of course), your current units selection, the exact frame of a unit animation (unless the game depends on that to fire a skill).

If you are just saving the game state to be restored locally, you may want to store more stuff that you need since that shouldn’t matter. However, in the case of checking state synchronization between machines, having stuff that could differ and doesn’t affect the game outcome is not a good thing to have since you are not only wasting bandwidth but also risking the synchronization check.

Next time

Currently I am working on a way to represent the game state of a game I am working on and I want to have both features, a way to check synchronization between machines as well as having a way to save and restore the game state. I hope to talk about the benefits and problems of those features in the next posts, as well as having a more detailed information on the concepts of this blog post too.

Even though this blog post was a bit basic, I hope you liked it. I just wanted to talk a bit about the challenges I am dealing with right now.

VN:F [1.9.22_1171]
Rating: 5.0/5 (1 vote cast)

Understanding Unity Networking (Unet)

September 12th, 2016

The objective of this blog post is to give you a first look at Unity Networking (Unet) based on my experience with it, and from my point of view.

Introduction

Unet is the Unity client/server architecture solution for networking, which provides the developer a wide range of options from high level logic like automatically synchronizing game objects state to low level like directly sending bytes through a network connection.

To have a quick understanding of how it normally works, here is a quick example. Imagine there are 3 machines connected, one server and two clients. Each machine is running the same game, that means the same code and the same Scene with same GameObjects. The code has a way to know if it is on a server or a client, and if has authority or not, and take action according to that. For example, for non player objects the server is the one with the authority and for player objects only one client has authority. Since it is a client/server architecture actions are processed on the server and then synchronized back to the clients.

note: I wrote normally because it is not always the case, you can have have objects created only on some clients, or on the server, etc.

Unet

The idea here is to give you a quick look of what I explored so far.

The NetworkManager is Unet point of entrance. It is the way to host or join a game. It is responsible for creating the player object for each client, etc. As a Unity behaviour, it allows configuring the player prefab, start positions, different scenes for being offline or online, or even advanced stuff like configuring connection timeouts, etc.

unity-networkmanager

All Unet network objects must have a NetworkIdentity behaviour, this is the way to identify an object is the same in different machines, used for synchronzation for example.

The NetworkBehaviour is the base class for behaviours that want to know about networking. Subclasses of this class can override easy methods to be aware of networking events, automatically synchronize fields, invoke methods on the server or on the clients, and to know current code has authority over the object or not (since normally all objects are created in each machine). Here is a code sample containing some of these concepts:

 public class NetworkExampleClass : NetworkBehaviour
 {
     [SyncVar]
     public int health;
 
     int maxHealth = 100;
 
     public Color myColor;
 
     public GameObject bombPrefab;
 
     public void Start()
     {
         if (isLocalPlayer) {
             myColor = Color.blue;
         } else {
             myColor = Color.red;
         }
     
         if (isServer) {
             Debug.Log ("Object started on server");
         }
     }
 
     // only want to process this Unity callback on clients (avoid server update)
     [ClientCallback]
     public void Update()
     {
         // don't want to process on the client that is not the object owner, this works only
         // for the player object I believe.
         if (!isLocalPlayer)
             return;
 
         if (Input.GetMouseButtonUp (0)) {
             CmdTakePotion(10);
         }
 
         if (Input.GetMouseButtonUp (1)) {
             CmdSpawnBomb(UnityEngine.Random.insideUnitCircle * 100);
         }
     }
 
     // send command to server to perform authoritative logic
     [Command]
     public void CmdTakePotion(int hitpoints)
     {
         health += hitpoints;
         if (health > maxHealth)
             health = maxHealth;
         RpcShowPotionFeedback (hitpoints);
     }
 
     // send command to clients to perform visual logic
     [ClientRpc]
     public void RpcShowPotionFeedback(int hitpoints)
     {
         CreatePotionFeedback ();
     }
 
     public void CreatePotionFeedback(int hitpoints)
     {
         // TODO: create visual feedback for taking a potion
     }
 
     [Command]
     public void CmdSpawnBomb(Vector2 position)
     {
         GameObject bombObject = GameObject.Instantiate (bombPrefab);
         bombObject.transform.position = position;
 
         // this spawns the object on all clients and syncrhonizes them with server object (identity, etc)
         NetworkServer.Spawn (bombObject);
     }
 
 }

(note: this code may not compile, it wasn't tested)

And here is a quick explanation of the example concepts:

  • isServer: this property lets you know if you are on the server or not.
  • hasAuthority: this property lets you know if you have authority over the game object or not.
  • isLocalPlayer: this property tells you if the gameobject represents the player on the local machine, to avoid for example moving another players gameobjects when processing the input.
  • [SyncVar]: this field annotation it is a way to specify you need a field to be synchronized over the same game object running in each machine (the object identified by the same network id). For example, the health was decreased from 10 to 5 in the server, then all clients must show the change in the health bar.
  • [Command]: this method annotation it is used on methods that want to be invoked from a client to run in the server, their names must start with Cmd prefix. For example, if you want to do damage over a unit you send that to the server since the server is the authority here.
  • [ClientRpc]: this method annotation it is used on methods that want to be invoked from a server to run in all clients, their names must start with Rpc prefix. For example, the server detected some unit died (after it received damage), then it invokes a RpcUnitDeath(), so each client show the unit death animation.
  • Other methods annotations like [ClientCallback] and [ServerCallback] are an easier way to not having to check isServer property in the code, it is used for Unity automatic gameobject callbacks like Update or Start methods.
  • NetworkServer.Spawn(): it is the way to synchronize server creation of objects on clients, that means creating a game object on each client with the same network id.

For automatically synchronizing state there are already some behaviours like the NetworkTransform. These behaviours not only provide an automatic way to synchronize a GameObject common state but, in some cases, also a way to configure interpolation strategies. Here is a picture showing the NetworkTransform configuration:

unity-networktransform

Note: in my tests I couldn’t find a way to make the transform interpolation to look smooth. Even looking at other developers examples, they normally create their own interpolation code to fix that.

Here is a video showing a quick example I did using Unet, there are two clients, the left one is also the server. Each player can control one hexagon by clicking where to move it, the movement logic is performed in each client machine and automatically synchronized using a NetworkTransform.

Conclusion

The Unet high level concepts are a way to get, as fast as possible, a multiplayer game working, and depending the kind of game you are making, it may fit perfectly your needs. The low level access may give you a real control of what is happening behind the scenes in case you need to optimize your game networking usage.

As a developer, being flexible to use from high to low level stuff is always an advantage, and that is a really good point of Unet. Also, even though it wasn’t so easy to understand for me in my first tests, I believe the HLAPI is not hard to use and gives a good start point, and, like other Unity stuff, it is really good for quick prototyping.

Another really good point is that it is open source which means I can take a look at implementation details if I want, or understand how something work behind the scenes, or even propose bug fixes.

The bad part is that the documentation is not good, but that happens for all the Unity stuff, when you need to understand something in detail the documentation says nothing or it is even wrong. Also, the first Unet tutorial results wasn’t what I expected, the movement was really choppy and it didn’t work so well (I believe they updated it, I tried the one for Unity 5.3.x), that was something that made me think about Unet not being the solution I wanted for my games, but in the end it was just a really bad example of Unet features.

Also, if you are making an action game, I don't know if Unet provides good support for client side prediction, server reconciliation or lag compensation but it shouldn't be a problem to implement what you need over Unet since it is very flexible.

Right now I am following another aproach of using low level send messages API since for my game I am trying to reduce the bandwidth cost by sending only player actioons and performing a synchornized simulation, something I will try to write about in a future blog post.

References

Some references in no specific order.

Tutorial videos for making a survival cooperative game

Unet overview

Unity forums - Multiplayer networking

Unity forums - Collection of multiplayer samples

Unity networking source code at Bitbucket

A simple implementation of authoritative movement on top of unet

VN:F [1.9.22_1171]
Rating: 0.0/5 (0 votes cast)

A basic analysis of Clash Royale multiplayer solution

September 5th, 2016

The idea of this post is to analyze in a superficial way the multiplayer solution behind Clash Royale. Before starting the analysis, you must know that I don’t have previous experience making multiplayer games, I am just learning, and all the analysis done here is just a theory.

So, you surely know about Clash Royale but in case you don’t, it is an online multiplayer 1v1 RTS game where the first player to destroy the other’s towers win. To do so, they play cards which transforms into units that advance and attack enemy towers, structures that spawn units or attack enemy units or special powers which can be used to perform damage, among other things. Cards cost energy that regenerates over time (to a maximum). I recommend it since it is a great game, and it is really really polished in every detail (including multiplayer).

Here is a video explaining and showing the game:

Analysis

Since the game is very competitive, they probably have an authoritative server to validate player actions to avoid cheating. For example, a Player could say “I played card X” to the server, the server has to validate the player had that card in hand to use it, and enough energy.

In each game there could be several units at the same time (like 30 units in the worst case), also, there are tons of games being played at the same time. In order to make the game run over mobile networks and to support all those games, with all those units at the same time, they have to reduce the bandwidth to the minimum.

One strategy could be to compress the data sent, other could be to send data not so frequent and to interpolate to be as smooth as possible. However, considering that each unit has a position, looking direction, target, health, animation frame, among other stuff, that could still be a lot of data. I am guessing here that they follow another approach like a synchronized simulation of the game in each client and, since it is not so CPU heavy, every mobile device nowadays (game was released March 2016) shouldn't have problems running the game logic.

Another thing that made me think about synchronized simulation was that every player action is not performed instantly, it has a small delay or a cast time. That could be a design choice but I believe it considers the fact that actions must be synchronized between players and having a delay allows them to do that.

If they are simulating in the client, they have to control the simulation to be deterministic or they must have some way to fix the game state if it was desynchronized at some point.

If I remember correctly, they follow an approach that the game never stops, players could be disconnected for a while and then reconnect and continue playing, they just lose part of the game (couldn’t perform actions). That could be used also for player desynchronization. Don’t know the resynchronization strategy but maybe the server sends game state snapshot and the player continues from there.

They even have game replays, so I am guessing that simulating the game in each device could help in reducing the cost of watching a replay even though they could replay it in a server if they want since they probably have tons of servers :).

Conclusion

My guess is that the game has a client/server architecture where both the server and the client simulate the game synchronously. The server is in charge of validating player actions and responsible of deciding the real game state in case of desynchronization.

As I said at the beginning of the blog post, this is a superficial analysis based on my current knowledge. If I wanted to perform a deeper analysis I could have follow another approach like doing some reverse engineering over the game connections to validate some of my guesses but that wasn't the blog post purpose.

And here is a really fun video of the game to finish the post:

VN:F [1.9.22_1171]
Rating: 5.0/5 (1 vote cast)

Lockstep multiplayer first steps

August 30th, 2016

In this Gamasutra article, Tundra developers explain their approach to minimize problems when developing a lockstep multiplayer platform used for their game Rapture - World Conquest. Based on that, my first approach was to create and understand a deterministic lockstep logic without even considering networking yet, to focus on one problem at a time.

My objective is to have a reproducible game that given the start state and all the players actions during time, the game can be played again and the final state will be the same.

Lockstep logic

The first step was start by creating a logic to encapsulate the fixed game state for physics and game logic, and a lockstep to perform player actions. As I started without considering networking yet, all the player actions are directly enqueued locally by the user input or by a saved replay.

A lockstep logic means that there are some conditions that, if not met, the game should pause the simulation and wait for them. In the case of multiplayer games this is when the game have to wait for other players actions that didn't arrive in time (and where the waiting for other players dialog is shown in some games).

My code looks something like this pseudo code:

update(dt) {
    if (lockstepLogic.IsLockstepTurn()) {
        if (!lockstepLogic.IsReady())
            return;
        lockstepLogic.Process();
    }
    // normal accumulator logic for the fixed gamestep
}

Since I create all player actions locally, the lockstep never happens right now but it is a good practice to simulate and test it anyways.

Testing it

My first prototype using this logic is a box that moves over the screen. When the right mouse button is pressed, the game enqueues a player action to move the box to the specified position, then when the lockstep logic is processed the box receives the command and start moving to that position.

Interpolation

The moving logic was pretty simple, based on start and destination positions and a speed, the box moves itself to the destination in a straight line. Since that logic is performed in each fixed gamestep, the player see the box jumping between positions, it works but it doesn't look so good. To improve that and make the movement smoother I created a simple interpolation code.

Interpolation depends a lot on what you are trying to interpolate, in some cases could be a simple as the code I used there but there are other cases like the bouncing ball which need more data to create a better interpolation.

Note: adding interpolation means we have now a delay of one fixed gamestep between the box position being rendered and the real position in the game since we are using previous and current positions info for the interpolation.

My first replays

By recording all the player actions with the fixed gamestep frame they were executed, I created a basic way to replay the "game" by just reseting the game state to the initial state and start enqueing all the recorded actions in each corresponding frame.

Here is a video of the progress so far:

Yeah, I know, it's not a great thing, but at least I am starting to understand some of the challenges of making multiplayer games.

Validating simulation

To validate the game is always performing the same simulation given the same input, I added a checksum calculation based on the game state (for now just the moving box state) which is saved from time to time to use later as validation when simulating the game again. The idea was to start defining an API to get the important game state to consider when validating the simulation, and also to start testing game state validation. The code looks like this:

update(frame) {
    if (IsChecksumFrame(frame)) {
        if (recording) {
            checksumRecorder.RecordState(frame, CalculateChecksum());
        } else {
            if (!checksumValidator.IsValid(frame, 
                   checksumRecorder.SavedChecksums, CalculateChecksum())) {
               throw Exception("current game state is not valid!");
            }
        }
    }
}

In my first tests I wasn't reseting the game to the initial state properly so my game was producing different checksums when reproducing the saved player actions, checksums validation started to work after that was fixed.

How am I calculating the Checksum? Right now I am not sure exactly what algorithm to use nor which game state should I consider for the checksum, so what I did was to encapsulate that in some interfaces and implemented a basic way to get both. For the checksum I am using a simple MD5 over a string, and for the game state, well..., a string with all important values concatenated (the moving box position, destination, if it is moving or not, etc).

string CalculateChecksum() {
    string gameStateValue = game.GetGameState();
    return MD5.CalculateHash(gameStateValue);
}

string GetGameState() {
    string gameState = "";
    foreach (object in gameObjects)
        gameState += object.GetGameState();
    return gameState;
}

For a future implementation what I know is that the game state should be composed with important values that can affect the simulation, so I shouldn't care about about audiovisual stuff like particles, effects and sounds.

Also, the game state concept could be used to reset to the initial game state or even for saved game states (to easily replicate some bug for example), and finally, it could be used to synchronize and validate state if for some reason I end up using a client/server architecture.

Next frontier: Determinism?

For now I didn't explore determinism realm because the solution really depends on the game logic but at the same time I must have it clear before starting the game code. One of the next steps is probably start testing with fixed point math, not sure yet, the idea is try to follow an approach similar to the gamasutra article's of reducing non determinism problem to the minimum before going multiplayer.

If you want to take a look all the code used for this blog post, here is the link.

Other links

Example of a dynamic lockstep implementation for Unity

Lockstep Framework for Unity

Reddit post about that Lockstep Framework

Another framework named lockstep.io

 

VN:F [1.9.22_1171]
Rating: 5.0/5 (2 votes cast)

Exploring Remote Multiplayer

August 26th, 2016

Some time ago I’ve started to prototype a multiplayer game, it is some kind of super simplified RTS game for mobile devices where macro decisions are encapsulated into one action through a button.

First versions were prototyped in a multiplayer hot seat fashion by using only one device (a tablet or a phone), that allowed me to quickly iterate between different ideas and find fun as soon as possible. That was a successful approach since the idea of the game proved that it was indeed fun to play with friends, so the next step was to go remote multiplayer with two or more devices.

Since networking is a whole new world for me, I started by reading lots of different articles about making multiplayer games.

The first thing to know is that the common solutions around depend on each kind of game, and knowing that beforehand helps you deciding the best solution for your game, and how your game must be adapted to support it.

In my case, I am developing a really simplified version of a RTS game for mobile, similar to Clash Royale. It is a 1v1 game where each player controls multiple units by giving high level orders like “everyone attack!” or “build new supply depot”.

The common networking approach for this kind of games, where synchronizing the whole world is a bit heavy given there are tons of units, is to do a synchronized simulation where only the main actions are transmitted (to save bandwidth) and each machine/device perform the same simulation. This implies the game should be deterministic in order to avoid desynchronization between players, so given one start state of the game and a list of actions over time, the final state should be always the same.

Making a game deterministic is a really hard problem, but it also has its rewards, like being able to replay the game given the actions of each player over time. This is a great debug tool for developers and at the same time a great freature for players since it is used to see other strategies or to share a great victory with your friends, everything with almost no storage cost.

The idea is to start writing my findings in the remote multiplayer journey to share all the lessons learned.

References

These are some of the articles I read:

What every programmer needs to know about game networking

1500 Archers on a 28.8: Network Programming in Age of Empires and Beyond

Fast-Paced Multiplayer

Why adding multiplayer makes game coding twice as much work

Core network structures for games

Making Fast-Paced Multiplayer Networked Games is Hard

How to create an online multiplayer game with Unity

Networking in Unity

Creating a Cross-Platform Multiplayer Game in Unity

Understanding Fighting Game Networking

Desyncs and FPU synchronization

Cross platform RTS synchronization and floating point indeterminism

Minimizing the Pain of Lockstep Multiplayer

The Tech of Planetary Annihilation: ChronoCam

Synchronous RTS Engines and a Tale of Desyncs

Don’t Store That in a Float

 

VN:F [1.9.22_1171]
Rating: 0.0/5 (0 votes cast)

How Google Play Game Services softly killed Vampire Runner

February 18th, 2015

We want to talk a bit about how we migrated from our custom highscores system to use Google Play Game Services (GPGS) Leaderboards for Vampire Runner and the consequences of that change.

Before GPGS was released, we worked on our custom solution for highscores for Vampire Runner. That solution consisted in having scores for multiple time intervals (daily, weekly, monthly and all times scores) and letting guest users play and make scores without the need to log in. You could play the game, make scores and then, if you thought your scores were good, link those scores with your name, really simple and easy, it worked fine.

That custom solution was running on an amazon server and costed about 15 USD/month and since the game was making around that money with the ads, we thought it was acceptable.

A while after GPGS was released, we thought, why maintain and pay money for our own server when we can use GPGS instead? It was very logic, they have some of the features we had on our system and everybody was starting to use it. Also, we trust Google, so we changed Vampire Runner to use GPGS.

However, some time after we changed Vampire Runner, we started to see an important decrease in the number of people playing the game. The problem was something we were aware of but we thought it wouldn't be so significant. We had a lot of players that didn't have a Google account or even Google Play (they probably downloaded the game from other store), and they couldn't log in to compete with other players so the game was less interesting for them since part of our game is based on that, competing to be better than other players.

The truth is the game is not a good game by itself and the main thing that kept our players was being able to compete with others (for a while at least), now that we are forcing them to log in they feel it isn't worth it so they just go away or they play without logging in, hence without making scores.

Conclusion

We don't think Google Play Game Services is the bad guy here but it is not good if you want to capture users from outside Google, same example would apply if we had forced Facebook or Twitter accounts. So if you have a game where you need players to catch other players, consider that. Of course, if you have a great game maybe with only Facebook, Google or Twitter you could keep your game alive but if you consider the three of them, you will get more players. In our case, we had all the world and then we restricted our game to only G+ accounts and that is why we lost players.

That was part of the story of the dying Vampire Runner, hope you like it.

VN:F [1.9.22_1171]
Rating: 5.0/5 (6 votes cast)

Did you miss us?

December 4th, 2014

Hi guys, long time no see.

It's been a while since we came here and write, and we want to share why.

What happened

By the end of 2012, after we finished Clash of the Olympians to Android and iOS working hand in hand with Ironhide Game Studio, we had no ideas to work on. We weren't really excited in working by ourselves anymore because we didn't feel we could create something of the quality of Clash. Also, we really enjoyed working with Ironhide's team. In addition, Ironhide was looking for programmers and they told us they enjoyed working with us as well, so they offered us a job and we couldn't refuse (and we are still glad we did not).

Working at Ironhide

Two words: Indescribable awesomeness.

We are part of an excellent and diverse team composed by artists, developers, game designers and more. The workplace is comfy and the game development workflow is pretty dynamic. We can participate in a lot of game decisions and that rocks!

Working really close with artists allowed us to validate how much we needed one at Gemserk to define ideas and visualize, in an easy way, how our games should look like. It also works as motivation since you really want to see that art in the game.

Game design was another flaw at Gemserk, and we now see and understand it much better.

We learn new stuff each day and we also collaborate and share our knowledge to make the game and the team better. And at the end of the day, that feels really good. We hope it lasts long.

What about Gemserk

As company, Gemserk is kinda dead. We never reached what we wanted with our creations, and in those terms, we weren't successful. However, we don't see Gemserk as a failure either since we accomplished a lot in terms of technical knowledge and relationship with other game developers and tool makers and we are really happy with that.

We have no plans to work on anything Gemserk related for now but we believe we still have some stuff to share.

Thanks for reading our blog and hope we could still write interesting posts in the future.

The Gemserk team.

VN:F [1.9.22_1171]
Rating: 4.3/5 (7 votes cast)

Our solution to handle multiple screen sizes in Android – Part three

September 12th, 2013

In the previous posts of this series we talked about our solution to handle multiple screen sizes for game menus, in particular we showed the main menu of the game Clash of the Olympians. In this post we are going to talk about what we did inside the game itself. As a side note, the solution we used here is simple and specific for this game, hope it could help as example but don't expect a silver bullet.

Scaling to match the physics world

As we use Box2D in Clash of the Olympians, the first step was to use a proper scale between Box2D bodies and our assets. The basic approach was to consider that 1m (meter in MKS system) was 32px, so in our target resolution of 800x480 could show 25m x 15m. We picked that scale because it gives pretty numbers both in terms of the game area and in terms of our assets, for example, a character of 64px of height is 2m tall. In particular, Achilles has a height of approx 60px which is equivalent to 1.875m using our scale, that sounds pretty reasonable for that character.

clashoftheolympians-800x480
The image shows the relation between screen size in pixels (800x480 in this case) and the game world in meters.

Defining a virtual area to show

We previously said that we could show 25m x 15m, in fact, the height is not so important in Clash of the Olympians since the game mainly depends in the horizontal distance. So, if we had an imaginary with a resolution of 800x400 (really wide, an aspect ratio of 2) we would show in that case 12.5m of height, we could assume that if we show at least that height the game balance would be not affected at all (enemies are never spawned too high). However, in terms of horizontal distance we want to show always the same area across all devices to avoid changing the game balance (for example, if you could see less area you couldn't react in the proper time to some waves), that is why we decided to show always 25m in terms of width.

clashoftheolympians-800x600

The image shows how we still show the same game world width of 25m on a 800x600 device.

Scaling the world back to match the screen size

Finally, in order to show this virtual area of 25m x H (with H >= 12.5m), we have to calculate the proper scale to set our game camera in each device. For example, in the case of having a Nexus 7 (1280x720 resolution device) the scale to show 25m of horizontal size is 51.2x since we know that 1280 / scale = 25, then 1280 / 25 = 51.2. In the case of a Samsung Galaxy Y (480x320 resolution device) the scale would be 19.2x since 480 / 25 = 19.2. Translating this inside the game would be something as easy as:

camera.scale = screen.width / 25

Final thoughts

This is not a general solution, it depends a lot in the game we were making and the things we could assume like the game height doesn't matter.

Even though the solution is specific and not so cool as the previous posts, we hope it could be of help when making your own game.

VN:F [1.9.22_1171]
Rating: 4.3/5 (18 votes cast)

Our resources manager and how it helped in localizing Clash of the Olympians

May 1st, 2013

In this post we want to share how our resources manager implementation helped us when we had to localize Clash of the Olympians.

Our resources manager

Some time ago we started a small java project named jresourcesmanager (yeah, the most creative name in the world) which provides a simple abstraction of what a resource is and how it is loaded. It consists in some basic concepts named Resource, DataLoader and ResourceManager.

Resource

Is the concept of an application resource/asset, and provides an API to know if the resource is loaded or not and to load and unload it. Here is the code:

public class Resource<T> {

	T data = null;

	DataLoader<T> dataLoader;

	protected Resource(DataLoader<T> dataLoader) {
		this(dataLoader, true);
	}

	protected Resource(DataLoader<T> dataLoader, boolean deferred) {
		this.dataLoader = dataLoader;
		if (!deferred)
			reload();
	}

	/**
	 * Returns the data stored by the Resource.
	 */
	public T get() {
		if (!isLoaded())
			load();
		return data;
	}
	
	public void set(T data) {
		this.data = data;
	}

	public DataLoader<T> getDataLoader() {
		return dataLoader;
	}
	
	public void setDataLoader(DataLoader<T> dataLoader) {
		unload();
		this.dataLoader = dataLoader;
	}

	/**
	 * Reloads the internal data by calling unload and load().
	 */
	public void reload() {
		unload();
		load();
	}

	/**
	 * Loads the data if it wasn't loaded yet, it does nothing otherwise.
	 */
	public void load() {
		if (!isLoaded())
			data = dataLoader.load();
	}

	/**
	 * Unloads the data by calling the DataLoader.unload(t) method.
	 */
	public void unload() {
		if (isLoaded()) {
			dataLoader.unload(data);
			data = null;
		}
	}

	/**
	 * Returns true if the data is loaded, false otherwise.
	 */
	public boolean isLoaded() {
		return data != null;
	}

	public Resource<T> clone() {
		return new Resource<T>(dataLoader);
	}

}

DataLoader

Provides an API to define a way to load and unload a Resource, here is the code:

public abstract class DataLoader<T> {

	/**
	 * Implements how to load the data.
	 */
	public abstract T load();

	/**
	 * Implements how to unload the data, if it is nod automatic and you need to unload stuff by hand.
	 */
	public void unload(T t) {

	}

	/**
	 * Provides a way to return custom information about the data loader.
	 * 
	 * @return An object with the custom information.
	 */
	public Object getMetaData() {
		return null;
	}

}

ResourceManager

It is just a map with all the resources identified by a key, which can be a String for example, and an API to store and get resources to and from, respectively.

That is our resources management code, it is really simple and fulfilled our needs in assets loading/unloading for Vampire Runner and Clash of the Olympians.

The interesting part of this library is that it allows you to store whatever you want to consider as a resource/asset, and that feature is what we used in order to solve the localization issue.

Declaring resources

Another important pillar is how we declare resources in an easy way through the code, and that is by using some builders that simplified the resource declaration. As we were using LibGDX library, we created a resource builder for LibGDX assets and more. This resource builder allowed us to do stuff like this:

splitLoadingTextureAtlas("MainTextureAtlas", "data/images/screens/mainmenu/pack");
resource("MainBackgroundTop", sprite2().textureAtlas("MainTextureAtlas", "mainmenu-bg", 1).center(0.5f, 0.5f).trySpriteAtlas());

That declares a texture atlas with the name of MainTextureAtlas and then a resource which is a sprite with the name of MainBackgroundTop from a texture atlas resource identified by the previous name. Also, allow us to do stuff like declare that the sprite is centered in the middle (the anchor point) and more.

This code is not important, just an example of some of our builders.

Declaring localized resources

As we have the power to create complex resource builders and we needed a simple way to switch between assets given the language selected, we created a resource builder which allowed us to declare different resources, depending the current locale, using the same identifier. So, for example, we can do something like this:

resource("CreditsButton", new MultilanguageResourceBuilder<Sprite>() //
	.defaultLocale(new Locale("en")) //
	.resource(new Locale("en"), sprite2().textureAtlas(TextureAtlases.MeinMenu, "mainmenu-but-credits-en", 1).trySpriteAtlas()) //
	.resource(new Locale("es"), sprite2().textureAtlas(TextureAtlases.MeinMenu, "mainmenu-but-credits-es", 1).trySpriteAtlas()) //
			);

That declares a resource named CreditsButton which returns a sprite with index 1 and name “mainmenu-but-credits-en” from a texture atlas in case the locale is English and a sprite with index 1 and name “mainmenu-but-credits-es” in case the locale is Spanish. It also declares that the default locale (in case a resource for the current locale wasn’t found) is English.

This resource builder was very handy because it allowed us to declare any type of resource for different locales, and from the application side it was transparent, we just ask for the resource CreditsButton.

In case you are interested, the code of the MultilanguageResoruceBuilder is:

public class MultilanguageResourceBuilder<T> implements ResourceBuilder<T> {

	private Map<Locale, ResourceBuilder<T>> resourceBuilders = new HashMap<Locale, ResourceBuilder<T>>();
	private Locale defaultLocale;

	@Override
	public boolean isVolatile() {
		if (defaultLocale == null)
			throw new IllegalStateException("Multilanguage resource builder needs a default locale");
		ResourceBuilder<T> resourceBuilder = resourceBuilders.get(defaultLocale);
		if (resourceBuilder == null)
			throw new IllegalStateException("Multilanguage resource builder needs a default resource builder");
		return resourceBuilder.isVolatile();
	}

	public MultilanguageResourceBuilder<T> defaultLocale(Locale locale) {
		this.defaultLocale = locale;
		return this;
	}

	public MultilanguageResourceBuilder<T> resource(Locale locale, ResourceBuilder<T> resourceBuilder) {
		resourceBuilders.put(locale, resourceBuilder);
		return this;
	}

	@Override
	public T build() {
		Locale locale = Locale.getDefault();

		if (defaultLocale == null)
			throw new IllegalStateException("Multilanguage resource builder needs a default locale");

		if (!resourceBuilders.containsKey(locale))
			locale = defaultLocale;

		ResourceBuilder<T> resourceBuilder = resourceBuilders.get(locale);

		if (resourceBuilder == null)
			throw new IllegalStateException("Multilanguage resource builder needs a default resource builder");

		return resourceBuilder.build();
	}

}

Conclusion

That was the way we used to support multiple languages in a transparent way for the application, we just need to change the current locale and reload the assets.

Hope this blog post idea helps you in case you are about to support multiple languages in your game, and see you next time.

VN:F [1.9.22_1171]
Rating: 3.9/5 (14 votes cast)