Click here to Skip to main content
15,119,363 members
Articles / Programming Languages / Javascript
Posted 22 Dec 2013

Tagged as


12 bookmarked

Pixelreka! - Real Time Game with TogetherJS JavaScript Library

Rate me:
Please Sign up or sign in to vote.
5.00/5 (10 votes)
22 Dec 2013CPOL8 min read
Build a collaborative game (or any other app) with Mozilla's Real Time Collaboration Library

Image 1


A few months ago, Mozilla Foundation released TogetherJS, a powerful collaboration tool: a JavaScript library which, once added to your website, could establish connections between users in real time.

Although the technology is not new (just to name a few, since few years ago we have Web Sockets for full-duplex communication channels and SignalR.Net which also works when web sockets are not available), TogetherJS provides a rich set of out-of-the-box features for real-time collaboration, such as the standardized dialogs, the ability to change your name and avatar and also a built-in chat. So, Immediately I recognized the potential of such library and that's how the Pixelreka game was conceived.

System Requirements

Since this project relies solely on JavaScript, there will be no need for compiling code. If you want to modify and test it, then any good code editor will be enough, such as Notepad++, Sublime Text or even Visual Studio Express 2012 for Web.


Getting started with TogetherJS is as easy as including the following script tag in your HTML page:

<script src=""></script>

Can it be that simple? Yes, it can. And you can put the above tag anywhere in your HTML.

Image 2

The centerpiece of TogetherJS is the hub. Using WebSocket protocol, the hub is a server to which the clients are connected, and which receives and broadcasts messages coming from/delivered to the clients connected in the same session. In doing so, the messages are preserved and redistributed exactly as they arrive.

TogetherJS works by redistributing messages passed by the browsers participating in the same session through the hub. TogetherJS doesn't require clients to stay in the exactly same page, but since Pixelreka is a single-page application, you might think otherwise.

Image 3

Once the connection is established between the client browsers and the hub, some out-of-the-box real-time features are automatically put to action. For example, whenever one of the client participants move the browser, a message is sent via websockets to the hub, which in turn broadcasts that message untouched to the other client participants.

Image 4

Now that we managed to reference the TogetherJS JavaScript library in our code, it is required that each client agrees with the connection. It could be done automatically by our application and transparent to the user, but instead we create a button inviting the user to join the game.

<input type="button" class="start-togetherjs btn btn-large btn-success" onclick="initializeTogetherJS(); return false;"
style="display: none;" value="Start Pixelreka!" />
function initializeTogetherJS() {

Image 5

When the user starts Pixelreka, he or she enters the single page application, showing the central panel containg the big-sized pixel drawing board, along with the color palette at the left, the challenge word in the bottom, and a "shuffle" button. In this pixel drawing board he or she will have to (guess what?) draw some picture representing the challenge word, so that other participants will have to guess it correctly. The suffle button if for when the player finds it very difficult to draw or doesn't know the meaning of the word, so another challenge word can be immediately picked up.

Image 6

You can see that the above picture shows a panel at the right edge, and that is automatically provided by TogetherJS for your page. It has four buttons and they are detailed as follows:

  • This is you: this is where you configure your name, avatar (i.e. your photo), provide feedback to Mozilla foundation and exit the TogetherJS session.
  • Invite a friend: once pushed, this button will display a tray with a url that you would like to send to a friend so that you both could play together.
  • Audio Chat: use microphone/speakers to communicate with other session participants through the Web RTC technology. Web RTC is a nice feature, but only implemented by Chrome and Firefox (no Internet Explorer support so far).
  • Chat: a regular and simple text chat.

Image 7

Updating an avatar is quite easy. Just chose a file in your local file system and you're done.

Image 8

Inviting a friend for your session requires you only a copy-and-paste of the url provided by TogetherJS. See how the session identity is embedded at the end of the url.

Image 9

When your friend receives the url of the game session, he or she will immediately see the game board with your avatar, and will be asked to join the ongoing session.

Image 10

Configuring Communication

It's a relief to know that TogetherJS will help you us with all the infrastructure needed for communication. All we have to do is configure exactly what messages are to be passed between the session participants and what functions are to be invoked when receiving such messages.



application is quite simple, and we rely on only three kinds of messages:

  1. editor-started: this message is triggered when a new "editor" starts drawing. This means that the participants receiving the message are those ones who have to guess the drawing correctly. The message has the following components:
    • userId, userIdentityId: the editor's IDs generated by TogetherJS infrastructure.
    • avatar: the image URL of the editor user.
    • name: the editor's name.
    • category: the category of the word the editor must draw.
  2. pixel-set: this message is sent everytime the editor changes a pixel color in the drawing canvas. Every session includes a lot of drawing, so this message is expected to be broadcast many, many times. This is where people participating in the game start guessing.
    • pixelId: the pixel id, varying from 0 to 255. This pixel refers to the bitmap position in the pixelated drawing canvas.
    • colorIndex: the color index, defined by the drawing color palette.
  3. new-guess: as the drawing becomes more complete and clear, the participants will start guessing, and this message is sent with the following parameters:
      userId: the id of the user making the guess.
      guess: the word being guessed.

It should be noticed that the above list refers only to the custom communication that we have to set up for our application to work correctly. At th same time there are many more messages coming and going between participants via the Together JS hub, such as mouse movements, clicks, text box changes, but these ones are provided out-of-the-box and automatically by the TogetherJS library so that we don't have to worry about them.

The following code shows how to set up these messages:

setupCommunication: function () {
    var self = this;
    TogetherJS.hub.on("editor-started", function (msg) {
        if (self.currentPlayerIdentityId() != msg.userIdentityId) {
            var guessUser = TogetherJS.require("peers").getPeer(msg.userId);
    TogetherJS.hub.on("pixel-set", function (msg) {
    TogetherJS.hub.on("new-guess", function (msg) {
        var guessUser = TogetherJS.require("peers").getPeer(msg.userId);
        var callback = function () {
        newGuess(guessUser, msg.guess, callback)

The "editor-started" message

As seen above, the "editor-started" message is broadcast when the new editor (the person to draw something on the game canvas) is set. There is a couple of situations when this message is sent. The first one is when the player clicks "Start" button and the TogetherJS session is initialized:

cmdStart: function () {

The second one is invoked when the user reloads the page, thus he/she is automatically reentered in the TogetherJS session. Notice how the <class>TogetherJSConfig_on_ready function is declared to handle the reentering of the participant:

TogetherJSConfig_on_ready = function () {
var Game = function () {
$.extend(Game.prototype, {
    initialize: function () {

And finally the <class>startEditor class itself, which among other things sends the message via the <class>send method of the TogetherJS object.

startEditor: function () {
        type: 'editor-started',
        userId: TogetherJS.require("peers"),
        userIdentityId: TogetherJS.require("peers").Self.identityId,
        avatar: TogetherJS.require("peers").Self.avatar,
        name: TogetherJS.require("peers"),
        category: self.category

The "pixel-set" message

The "pixel-set" message is what enables other participants to see the drawing process.

When the user clicks the drawing canvas, he or she triggers the <class>setPixel function of the <class>PixelViewModel. The message is then broadcast, informing who is drawing and where in the drawing canvas the given color is being painted.

var PixelViewModel = function (index, col, row, even, colorIndex) {
    this.initialize(index, col, row, even, colorIndex);
$.extend(PixelViewModel.prototype, {
    setPixel: function (colorIndex) {
        var self = this;
        if (gameViewModel.isMouseDown) {
            if (self.colorIndex() != colorIndex) {
                if (!game)
                    type: 'pixel-set',
                    userId: TogetherJS.require("peers"),
                    userIdentityId: TogetherJS.require("peers").Self.identityId,
                    pixelId: self.index(),
                    colorIndex: colorIndex

The "new-guess" message

As the drawing becomes more clear, the players will start making guesses, and the new-guess message is sent when the users fills in the <class>txtGuess input box and pushes the Send button.

cmdSend: function () {
send: function () {
    var self = this;
        type: 'new-guess',
        userId: TogetherJS.require("peers"),
        userIdentityId: TogetherJS.require("peers").Self.identityId,
        guess: self.txtGuess()

Game Play

As the connections are established between participants, the editor player is ready to start drawing and the other participants are ready to start guessing. The drawing in one side is shown almost immediately on the other browsers.

In the example below, Kermit and Animal have both entered the same session.

Image 11

Notice how they see one another in the right panel that is provied by TogetherJS:

Image 12

But the drawing board is a bit different for the both of them. Animal is drawing on the left board, and that's why he's holding a brush, while Kermit is trying to guess his drawing, and he sees a top right avatar indicating that it's Animal's turn to draw:

Image 13

Then Animal starts drawing and Kermit immediately sees that drawing happening in his browser:

Image 14

Image 15

Even though the drawing board is a low-res, 16x16 bitmap, sometimes using a brush as wide as one pixel is a lot of work, especially when filling regions (such as painting an elephant). In these occasions, a wider brush would be much more convenient for the task:

Image 16

Using different colors also help making the drawing more clear:

Image 17

Now that Kermit finally figured out what Animal's drawing was about, he fills in the "guess" text box:

Image 18

Image 19

When Kermit sends his guess, this is what is popped up on Animal's browser.

Image 20

Since the game is not complete, it ends here. I know, you wanted more. But for the goal of demonstrating TogetherJS, this might be enough. You are free to extend the game, implement scoreboards, implement turn management, badges, sharing game results on Facebook and Twitter and what else your imagination allows.

Final Considerations

Web based real-time communication is getting more powerful than ever. Very soon there will be in the landscape a commoditization of infrastructure communication technologies that not long ago were available only for the advanced developer. We should be thankful to the efforts made by TogetherJS team to bring us such high level tools, allowing us to save time and focus on our own core application features.

Thanks a lot for the reading, and please feel free to leave a comment regarding the article and the accompanying code.


  • 2013-12-22: Initial version.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Comments and Discussions

Generalthanks Pin
Hooman_Kh23-Aug-15 13:36
MemberHooman_Kh23-Aug-15 13:36 
QuestionAnother outstanding article! Pin
César de Souza23-Dec-13 14:42
professionalCésar de Souza23-Dec-13 14:42 
Questionnice Pin
Sacha Barber22-Dec-13 10:42
mvaSacha Barber22-Dec-13 10:42 
AnswerRe: nice Pin
Marcelo Ricardo de Oliveira22-Dec-13 15:09
MemberMarcelo Ricardo de Oliveira22-Dec-13 15:09 
GeneralRe: nice Pin
Sacha Barber23-Dec-13 3:57
mvaSacha Barber23-Dec-13 3:57 
GeneralRe: nice Pin
bxb6-Jan-14 0:22
Memberbxb6-Jan-14 0:22 
QuestionNice article Marcelo! Pin
Volynsky Alex22-Dec-13 10:40
professionalVolynsky Alex22-Dec-13 10:40 
AnswerRe: Nice article Marcelo! Pin
Marcelo Ricardo de Oliveira22-Dec-13 15:06
MemberMarcelo Ricardo de Oliveira22-Dec-13 15:06 
GeneralRe: Nice article Marcelo! Pin
Volynsky Alex23-Dec-13 9:45
professionalVolynsky Alex23-Dec-13 9:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.