Writing Gadget for Google Wave

Recently I got a Google Wave account and could not help myself to play with it. The most interesting feature for me is the shared state associated with every wave. This allows to embed multi-user widgets into the wave (in Google terminology gadgets inside wavelet). All other widgets I know are designed for a single user; for example Mac OS X dashboard widgets are written using the same web technologies and even have access to some system functionality but essentially they are just the tiny web pages. Google wave gadgets are designed with many concurrent users in mind and this makes them really the tiny web applications.

So I decided to write a gadget that is good for several people, and the best candidate seems to be a simple game. Five in a row was a perfect candidate since it requires only and images. It also has a fixed 15 by 15 board and simple win condition.

Google provides a brief but comprehensive guide on the topic of writing gadgets and this is the first thing that you should read. From the developer perspective gadget is composed like this:

  • XML wrapper that describes the gadget and lists its dependencies, name, height and other properties
  • HTML elements that comprise the gadget UI; you will need at least one div that you will use as an anchor to build dynamic UI upon
  • JavaScript code to handle user input and state updates

Physically gadget is an XML file with a Content element that wraps all HTML and JavaScript in CDATA section. This is not convenient because syntax highlighter and other features of dedicated HTML and JavaScript editors do not work for embedded content. I would prefer to have several files with html and js extensions that could be referenced from the XML file. This way it would be easier to create widgets that target several environments. Now if I would decide to make this game available as a Mac OS X dashboard widget I have to create a separate JavaScript file and duplicate the game logic.

There is also one difficult place in the API: concurrent modification of the shared state. The documentation is very succinct on the point:

Not only is a Wave gadget's state shared among all Wave participants, but in the typical case, any participant can change the gadget's state at any time. If two users change values for different keys at the same time, the wave resolves it. However, if the value for the same key is changed, only one change goes through.

What if two users start the game at the same time? After user clicks on the New Game button I send delta with several properties. All property names are the same in two deltas and I think one of the deltas will be just discarded, but if there would be unique property names the state would be corrupted. What is still not clear for me is how they determine when to discard the second delta. I assume they discard it if it comes before all participants are notified about the first delta but it would be helpful to know for sure.

The game logic is simple and I will not put it here except one caveat: full state restore. When game state changes wave sends you an update by invoking a callback function that you register during initialization. During normal gameplay I process only the last move for efficiency but when user switches from another wave the field is clear and I have to perform the full state restore.

  function stateUpdated() {
    var state = wave.getState();
    var move = state.get('move');
    if (!window.g_xoStateFullyRestored) {
      fullStateRestore();
      window.g_xoStateFullyRestored = 1;
    } else {
      if (move) {
        var col = state.get('col' + move);
        var row = state.get('row' + move);
        var cell = cellAt(col, row);
        if (move % 2) {
          makeXCell(cell);
        } else {
          makeOCell(cell);
        }
      } else {
        var board = document.getElementById('board');
        var cells = board.getElementsByTagName('div');
        for (var i = 0; i < cells.length; i++) {
          clearCell(cells.item(i));
        }
      }
    }
  }

I have also designed the game logic in a way that allows users to play both sides at the same time. The same user can start a game and join it but if it is played by two distinct users then of course each user can do moves only of its side.

xo5.png

You can also check this game in the Google wave samples gallery.

Overall I like the platform and would be interested in its success. I have not tried all the features yet but hope to find some time for it. I think the next thing I would try to do is to write a robot that can play this game.

Oh, and here is link to the gadget if you would like to give it a try: http://dizbits.googlecode.com/svn/trunk/xo5/xo5.xml

  • Digg
  • del.icio.us
  • Reddit
  • StumbleUpon
  • LinkedIn
  • E-mail this story to a friend!
  • Print this article!

Comments are closed.