Mastodon Icon GitHub Icon LinkedIn Icon RSS Icon

Global Game Jam 2015 Postmortem

First of all, some time ago I stated that I would like to start writing more. Unfortunately, a combination of personal issues, flu and other psychological breaks did not allow me to respect this promise. But I’ll be back soon. I swear.

Second, it is now time to talk about the game we developed for the Global Game Jam 2015 (and obviously valid as a January entry for my One Game A Month challenge!) I’m very happy with this game also if it is not a real “game” because (little spoiler) it is an online game who require a big amount of users to be interesting. I’ll never have so many users connected at the same time, so it is useless in practice. The good thing is that it was a big technical challenge and to be able to complete everything in less than 30 hours was really exciting. But first things first.

The Theme

This year theme for the Global Game Jam is just a question: “What do we do now?”. As usual, the GGJ’s theme is very open and allow any possible interpretation. So, with my friend, my sketchbook and a bag of chips we started our brainstorming. The idea comes to my mind almost instantaneously in a stream of consciousness that I’ll try to report now. That “we” in the question have to be the players. “We” is plural. “We” is a lot. A game in which a lot of people can play the same game. Online. MMO. No communication. Twitch Plays Pokemon. And that’s it.

The Game

So, at the end, the game can be summarized by the following phrase: an online game in which multiple players have to cooperate to create a rich colony on a distant planet. The game is a turn-based simulation. At each turn every connected player can submit a command to one (or more) character in  the game. At the end of the turn, the server randomly pick an action for each agent among the provided one and execute it. It is a damn sample concept. However, even if we were very excited about challenging ourselves into writing an online game in two days , I already knew the big problem of the concept. But we will talk of this later.

The Team

This time the team was made by only two persons: me and my fellow Maurilio. No artists at all. Unfortunately our experience with the artists is very bad. Mostly for our lack of experience I suppose, but the fact remains that with an artist on board we usually slow down a lot and this time we wanted a “vacation” from these kind of problem. I don’t know why. Any suggestion is very appreciated.

Nevertheless, we managed to achieve almost anything we had in mind.

The development

Here we are at the interesting part: the development! The only advantage in developing a server-client type of game for this kind of events is that we can heavily parallelize the work among me and my friend. In fact, once agreed on the interface, we can work by ourselves almost completely. The problem is that I don’t know almost anything on the client side of the development while I know everything on the server side! So, if you are interested in how to use Unity for this kind of stuff, I’m sorry, I’m not able to talk on that for now :D. On the other hand, I hope you are interested in how I used Node.js for writing a backend server for the game! :)

The technology: Node.js

At the beginning of the jam we faced the first big problem: deciding the technology and the architecture that we would use in the game. There were these points:

  • The technology must  be easy to use. After all, we had only 48 hours.
  • The architecture must be very simple. The game is simple: the server registers each action, elaborate the next state, and return the next state when there is the next turn.
  • Security, performance, scalability was not mandatory. It is a game jam game, not a production game. And this is more important if we look at the first point of this bullet list.

The decision was to use **Node.js **also if **we didn’t have any previous knowledge **and experience with it! In fact it is kind of amazing (and a good point for Node.js in general) that we was able to build a dummy test server for the game in 20 minutes.

The architecture

The architecture used for the server is the same of a traditional web server: a stateless server that receive requests and give answers. This obviously has its drawbacks:

  • It is not easy to track the player activity. The only thing it is possible to do is to give a token to the player that it have to use in order to give commands other than “login”.
  • It is not possible for the server to notify something to the client. The server is always a passive element, the client game has the responsibility to poll the server in search of notification or updates in the world state.

However, this architecture has proven itself as strong and easy enough to be implemented in two days without any serious problem (at least for this simple test game). But let’s see the main loop of the server!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
(function main() {
  // Initialize the game
  var theGame = game.CreateGame(Config);

  // Direct Access to TheWorld! [TODO: Remove?]
  var theWorld = theGame.theWorld;

  // Start the game Main Loop.
  var timeout = setInterval(theGame.computeNextState, Config.updateInterval*1000);

  http.createServer(function (req, res) {
    res.writeHead(200, {"Content-Type": "text/html"});
    switch (url.parse(req.url).pathname) {
      case "/action":
        chAction(req, theGame);
        res.write("done");
        break;
      case "/login":
        res.write(chLogin(req));
        break;
      case "/userlist":
        res.write(JSON.stringify({users: users.usersList}));
        break;
      case "/state":
        res.write(chState(theWorld));
        break;
      case "/actions":
        res.write(JSON.stringify({actions: actions}));
        break;
      // A lot of other boring calls...
      default:
        res.write("Error");
    }
    res.end();

  }).listen(Config.port);

  console.log("Server listening on port " + Config.port);
})();

The server main function is quite standard as a Node.js web service. First, there are the initialization for a class (a kind of) which manages the game. It is the core for the logic part of the game server, and we will talk about it afterwards. Then I get from the game instance a reference to the world class (who handle the evolution of the game step by step).  At line 9, we setup the evolution step: we decide that the function computeNextState have to be called every Config.updateInterval seconds.

Then the web service loop start. As I said before, this is a quite standard pattern. You find this on the very first page of the official Node.js page! In short: 1) we create an http server, 2) we pass to the server the callback function that will be used to parse the incoming http requests, 3) the function parse the url of the request and calls the right function and, finally, 4) the server write the return value into the response. All the data between server and client is serialized in JSON (in Unity we used SimpleJSON to handle JSON data).

Then there is the Game module. This class is definitely horrendous, I’m sorry, I had very little time to write a supermodular and optimized code. :) However, the class responsibility are listed below:

  • pickActionForAgents  - When the turn is completed, the game class have to pick an action for each  agent in game. This function is quite simple, first it filter the action pool for the desired agent, then randomly pick an action. This mean that every action has a chance to be selected and that the probability is proportional to the user that have chosen that action.
  • proposeAction - This is the function that is called when an unser want to propose an action to the server. It simply performs some checks (if the user and the action exist and if the action is not duplicated, i.e., there is the same action from the same user) and then add the action to the pool.
  • computeNextState - This is the core of the game class. It performs all the ritual for advancing to the next turn. It picks an action, apply the actions in the world and then ask the world to “evolve” (that is, to perform all the default calculation of the game such as movement of the NPCs, decrease the food amount to feed the agents, and so on).

Then there are a bunch of boring auxiliary functions. I’ll spare you those.

Finally there are the mighty module of doom: the world. Following the link you will find the full source code on GitHub. This class is my masterpiece of bad programming, a lot of the code was written and adjusted in the last 6 hours, when my concentration and energy was at the very minimum. :P This class handle the world representation (it is just a big matrix of numbers) and the position of all the dynamic stuff such as trees, houses, goats, agents and so on. In this class there is also the description (and implementation) of every allowed action (walk, collect, build, …) and the overall evolution of the world after each turn. It is very difficult to understand anything in the actual state, but fortunately it only does simple things.

The Experience

From a project management point of view, this time the jam went smooth as silk. We eat, we sleep, we had fun and there was no arguing or broken friendship at the end. We ended quite well a couple of hours in advance. I was tired as hell, but this time, I have to say that I have not realized that until the end of the jam. Then the sleepiness comes. And nobody can escape to the afterjam slumber.

My opinion

At the end, I was satisfied of the results. The game was completed (in its jam-size number of features) but, most of all, I’m happy with the experimentation with the server-client stuff. As I said in a previous post, I want to use my monthly game experience to learn something, and with this game, I definitely learned something that could be useful in the future.

However, there are a lot of problem. First, the graphic is nice but, not so much. For instance, there are no animations (we had no time) and some other elements lack of variety. Then there is the problem that the game is unplayable without a good number of players. Whitout players, it is like playing a shitty version of Terraria with a 5-10 second lag for each move, is not fun at all!

Anyway, the jam is over and it is time to think at the February game! I already have an idea, this should be quite fun and I’d like to experiment with some shader. Let’s see. :)

Well? where is the game?

As usual, the game is completely and freely available on the jam site (with a majestic photo of me with the Holy Goat Sceptre). The source code for the backend is available on GitHub. Maybe I can fix a bit the code in the following days, adding comments and avoiding a ton of duplicate code and function calls.

comments powered by Disqus