RaphaelWrapper demo and sample code

As promised, I published a small online demo application that uses RaphaelWrapper (if you do not know what I’m talking about, read this other post).

Click here to see the demo

The code of the demo is open source and you can find it on github at this address, you can use it as a brief sample code for the library while I put up something more detailed.

RaphaelWrapper has gone Open Source

Today I decided to publish the source of my Sproutcore-Raphael integration framework – called RaphaelWrapper – so that others can exploit it and hopefully help me extend it. I posted it on github, you can find it here: https://github.com/demerzel3/RaphaelWrapper.

RaphaelWrapper basically gives access to Raphael functions through a Sproutcore-friendly view called CanvasView. I’m using this framework as the basis for my bigger project Calliope, but since it is a completely independent component of the application I thought it could have been useful to make it public.

In the next days I will publish an usage example, and hopefully a little online demo as well.

Building Calliope – Data Model

If you don’t know what Calliope is, please read this other post before continuing on.

Understanding the game

The first step I took in building the data model for Calliope was trying to figure out how a game was structured, keeping in mind that a game is meant to be played in real time by different persons on different machines, and that the whole state of the game must be persisted in order for a player to be able to shut the game and go back to it anytime.

Obviously there are two or more players taking part in a game, and the game itself can be split into turns in which players interact. But what are the building blocks of a turn? During a turn a player can pick letters from the sack to put them on his/her rack, move letters around (between his/her rack and the board), chat with the opponents, and pass the turn. Each of these steps must be recorded by the system in the current player’s machine, in order to be reproducible on the other connected machines. I decided to threat the above steps all in the same way and to call them actions.

Continue reading

New look

I’ve always thought that white text on black background was difficult and tiring to read. Strangely enough, when I put up this blog I forgot that entirely and chosen a black theme. Today I realized that was an error, and replaced it with the Duster theme you are seeing right now.

Hope you like it, because I do!

Building Calliope – Index

Update (19/4/2011): New screenshots and Todo list of first preview

In the last post I introduced my latest effort: Calliope. As a further step I want to share with you a little more about the challenges and problems of the project, and about the solutions I came up with. Here is what I am going to write about:

  • Data model – how the game is represented in SQL tables, and how this relates to real-time problems;
  • Services Design – how the data model is being published by a series of RESTful web services;
  • The Server – building the services to serve data using symfony 2;
  • Sproutcore data sources – getting access to the data from the client;
  • Sproutcore and Rapahel – something about the integration layer I built among the two libraries;
  • Building the board – a little insight on how the game board – the main component of the client – has been built;
  • Real-time magic – how real-time playing is ultimately achieved in the client.

I am going to publish one post (or more) for each point in the list, about once a week. If you have preferences about what topic I should cover first or questions about the project, just let me know in the comments (or even in private if you prefer) and I’ll do my best to answer.

Introducing Calliope

Recently I felt the need to share more of my “private projects”, so that someone else passing by can read about them and maybe find them interesting. My hope is that by making more things public I can get more motivated to continue on and not let those projects die.

For those reasons, I’m introducing to you my latest project: Calliope.

Calliope is a word game similar to Scrabble, but with a twist. It is played by two or more players, with every player having 7 lettered tiles on a rack; points are scored by placing them on a board to form existing words. The twist that I added to the game is that during your turn you can use all the letters already on the board, that is: you can grab them and move them around at your wish to form new words (I grabbed the idea from a popular – in Italy – card game called Macchiavelli); you however only receive points for the words in which you put at least one of your rack’s letters.

In the same period I “invented” Calliope by merging Scrabble and Macchiavelli I was discovering the existence of new web frameworks and technologies that I would have liked to experiment with. Since at that time I hadn’t a “private project” going on I decided to start one on Calliope itself, and to implement a digital version of the game based on web technologies.

Here is a sneak peak of the result at current stage of development:

Update: more screenshots here!

It is essentially a multiplayer real-time game, in which two or more players can interact with the board in turn. As you can see there’s the rack on the bottom of the page, and there’s a chat on the right with which one can communicate with the other players. Here is how it is constructed:

  • the client side – portraid in the picture – is made on top of Sproutcore, a javascript framework aimed to build desktop-like applications, great stuff;
  • the graphic part (essentially, the board) has been built using Raphael, which gives a nice and smooth javascript interface to SVG programming – I integrated it with Sproutcore myself;
  • the back of the house/server side is built on top of symfony 2, a blazing fast any-purpose php framework.

At the beginning of the project I had no idea of how Sproutcore, Raphael or symfony 2 worked; it has been – and will be – an opportunity for me to learn them. By the way, I also experimented on two other things: RESTful web services (to prepare for the topic I also read this book by Richardson and Ruby) and git, which I never tried before.

At current stage of development, the game is playable but not really stable, and there are still a number of open things to be done. However, I am hoping to put a demo online as soon as possible, to show you more of the project.

This was only an introduction, stay tuned for more! 🙂

Update: this post has become the first of a series of posts about Calliope, you can find the index here.

A better Record::copy()

Today I’m going to bore you with low-level technical stuff so, if you’ve nothing to do with Symfony or Doctrine you are allowed to leave now.

For the rest of you who love this kind of things, here’s the situation: I’m working on a project which was made some months ago using Symfony 1.2 with Propel and by opening it up again to make some big changes I decided to migrate to Symfony 1.4 and Doctrine (which seems to be the preferred choice for Symfony now).

During the transition I found that the copy() method of Doctrine_Record doesn’t behave at all as its Propel counterpart, and is infact quite buggy: it does duplicate child records (which it should) but is does duplicate parent records as well (which it shouldn’t!) and it doesn’t duplicate referenced records if you don’t load them in advance from the database.

To fix this behavior I defined a new class called BaseDoctrineRecord with my own version of copy(), here it is:

  class BaseDoctrineRecord extends sfDoctrineRecord
  {
    /**
     * Fixes the buggy copy method of Doctrine_Record
     *
     * @param bool $deep
     * @return BaseDoctrineRecord
     */
    public function copy($deep = false)
    {
      $ret = parent::copy(false);
      if (!$deep)
        return $ret;

      // ensure to have loaded all references (unlike Doctrine_Record)
      foreach ($this->getTable()->getRelations() as $name => $relation)
      {
        // ignore ONE sides of relationships
        if ($relation->getType() == Doctrine_Relation::MANY)
        {
          if (empty($this->$name))
            $this->loadReference($name);

          // do the deep copy
          foreach ($this->$name as $record)
            $ret->{$name}[] = $record->copy($deep);
        }
      }
    }
    return $ret;
  }

Then it was only matter of changing the base class of doctrine auto-generated models to my new BaseDoctrineRecord, and this can be done by adding the following lines to ProjectConfiguration:

  public function configureDoctrine(Doctrine_Manager $manager)
  {
    $options = array('baseClassName' => 'BaseDoctrineRecord');
    sfConfig::set('doctrine_model_builder_options', $options);
  }

And that’s all, simple as that. For me it’s just working perfectly, feel free to reuse the code in your own project.

Hope this can help someone, byeee.