20 November 2007
Time
At the moment I am working on a different project, a sort of web-forum based around old picture postcards - a favour for my father.
All of this is to gather skills, so anything learnt about building a more conventional web app can be farmed back into Facebook Trumps.
I hope a better version of Facebook Trumps will arrive soon! At the moment it averages about 1 add per day, and I do have some people who have a couple of games a week!
Labels: guice, java, wideplay warp
16 September 2007
More Fixed Windows.
I'm finding the idea of fixing everything before moving on a little tedious, but really its the right thing to do. Fixed Windows at present include:
- The stylesheet on this site: why was it orange? It is now blue.
- The link on this page now goes to "add application" rather than "play game".
- Upgraded host to Tomcat 6 (this was very involved).
- I can now view the Tomcat logs from the web.
- The logfile output location no longer throws an error everytime the game is started.
- The game is properly deployed and working.
Still more to do before I dabble with the next iteration!
- Complete "Finish Screen", displaying winner and option to restart.
- Present "Return to Game" button on Browse Trumps screen.
- Change last few "orange" links on this page.
So work to do ... the good thing is any of the 39 million people on Facebook can click the link on the right and actually play the game!
Labels: approach, facebook api, java, tomcat
08 September 2007
Broken Window Number 1: Replaced.
I discovered the problem was with the code which deals the cards to the two players. This makes use of the .clone() method of the TrumpStack object, basically just an Arraylist which represents the stack of Trump Cards. Another method shuffles the cards, the deal method then gives the entire card deck to to player, clones a copy to the opponent, deletes the top half of the cards from the players deck and the bottom half from the opponent's deck.
private void dealPack() {
// Give opponent half cards.
_session.setOpponentStack((TrumpStack) _session.getPlayerStack().clone());
_session.getOpponentStack().clearFirstHalf();
_session.getPlayerStack().clearLastHalf();
}
Turns out the behaviour of .clone() differs between web-mode and hosted. In the hosted implementation .clone() makes a copy of the TrumpStack object (which is basically an Arraylist) and all the elements too. In the web mode version the elements are not cloned but just the object (?!). This is doubly odd as the Sun API (Sun API Documentation) implies that the web behaviour is correct, although when running in Java that is not what happened.
What happens is, when the code accesses the first card in the opponent's stack of cards it gets a null value, which causes an error in Javascript. That at least, in the absence of better Javascript debugging tools, is what I think is happening.
In any case I have implemented my own method called .copy() which does copy all the elements, which I have then been able to give a return type of TrumpStack, getting rid of the need to cast in the dealing code above. I have also place a check for nullity in method which accesses the opponents first card. This might happen for example if the player only has one friend.
Labels: gwt, java, javascript
Google Code
http://code.google.com/p/facebooktrumps/
Labels: google code, gwt, java
02 September 2007
Broken Windows
One broken window, left unrepaired for any substantial length of time, instills in the inhabitants of the building a sense of abandonment- a sense that the powers that be don't care about the building. So another window gets broken. People start littering. Graffiti appears. Serious structural damage begins. In a relatively short space of time, the building becomes damaged beyond the owner's desire to fix it, and the sense of abandonment becomes reality.
Don't leave "broken windows" (bad designs, wrong decisions, or poor code) unrepaired. Fix each one as soon as it is discovered. If there is insufficient time to fix it properly, then board it up. Perhaps you can comment out the offending code, or display a "Not Implemented" message, or substitute dummy data instead. Take some action to prevent further damage and to show that you're on top of the situation.
This seems like wisdom to me and at this point in the project I need to focus on this implications of it. Before I start on adding the new features I need to deploy and iron all the creases out of the current version.
Labels: approach, guice, gwt, java
Third Version of the Game
For the next version of the game, which I would want to be of a sort of "beta" quality I am after the following:
- More on the server-side. I'm already using Guice (http://code.google.com/p/google-guice/), but I want to add things like persistence, for the game scores etc, but also to keep track of users who have successfully accessed the game (just their names and UIDs).
- Look and feel. I need it look more polished, I want to present an option to go "full screen", using a maximized browser window with just a control bar and URL field. Need more ques for the user to orient them to where they are in the game. Especially need to be more clear during opponents turn.
- Iron out issues which arise from testing. I need other people to test it live off the server and see what issues it throws up.
- Client Side Refactoring - I am tempted to make some alterations to the Event code and some major work on the EventCapableComposite which all the View components inherit from. Also to move the framework code into its own package.
Labels: facebook api, guice, gwt, hmvc, java
19 August 2007
Overlaying application flow onto HMVC
I need to put the conclusions of the past two posts together- I need to decompose the application structure implied by my flow diagram into a set of HMVC triads as described below.
The top level triad will have responsibility for moving the application from one phase, i.e. the game creation stage or the end game stage, to the next, and also for providing RPC functionality - I don't want that kind of code just spotted round the place. The Root/Container Triad:
- Model: Contains RPC methods and global state.
- View: Practically none - contains "Loading..." view.
- Controller: Co-ordinates transistions from one Triad to another.
After the Root triad has obtained the stack of Trumps for that appropriate player, it creates a child Triad to "setup" the game: The Create Game Triad:
- Model: Instantiate Game, Set players, Shuffle cards, Deal Cards, Toss Coin.
- View: Welcome and display outcome of game initialisation.
Next the Create Game Triad signals it is finished and the Root controller destroys that entire triad, replacing it with the Game Triad, which again is a child of the root controller. Due to the complexities of this view it is decomposed into further HMVC triads which are orchestrated by the Game Triad Controller:
- Player Turn VC Triad
- Opponent Turn VC Triad
- Show Result VC Triad
These are "cut-d0wn" HMVC triads, consisting only a view and a controller. All of the model code however is contained within the higher level Play Game Triad. Messages are passed between components and the Play Game Controller will create and destroy the alternate child Triads as required. Therefore the Play Game Triad looks like this:
- Model: Evaluate winner of turn functionality, Determine if game has been won functionality.
- View- Several View/Controller Triads as above.
- Controller: Manage interactions between all these! Create/Destroy child Triads.
Finally there is a End Game Triad to display the winner of the game and offer the oppotunity to return to the beginning of the game.
- Model: Send result via RPC (I will actually leave this until the next iteration of the game).
- View: Show End Result.
- Controller: Allow to go back to the start.
The structure described above will allow me to decompose my code into disgestible modular chunks and also due to the separation of functionality and standardisation of messaging will allow easy modification and improvement later. It won't be a matt of spaghetti.
Labels: approach, facebook api, gwt, hmvc, java
Application flow

Labels: facebook api, gwt, hmvc, java
The client/GUI Framework.
The client component needs to obtain a stack of trumps via RPC, compute the various outcomes in the game, communicate rich perspective on the game state to the user and accept interactions from the user. The most appropriate framework I could find is the HMVC (Hierarchical MVC) which is treated at length here: http://www.javaworld.com/javaworld/jw-07-2000/jw-0721-hmvc.html.
Following MVC principles the view (GWT Widgets) are delineated from the controller (flow logic) and the model (rpc, game logic). HMVC however fills in some of the gaps with respect to how these elements are composed and structured, and how these elements can communicate amongst one another. The heirarchical aspect allows a root controller encapsulating global concerns (such as the game and the trump stack) to control various children, such as turn screens, scoreboards or outcome views.
A concrete and usable example of HMVC is availible here, tp://www.thecentric.com/wiki/index.php/HMVC_Tutorial, which can easily be adapted to work with GWT.
Labels: approach, facebook api, gwt, java
12 August 2007
The Facebook API
Facebook applications can operate according to a number of models. Desktop or external web applications can make API calls - given a session has been authenticated via the Facebook site. This is the one extreme of "separateness" from the Facebook site.
There is also the option of having you application generate "FBML" (http://developers.facebook.com/documentation.php?v=1.0&doc=fbml) which is passed to a Facebook server. Facebook then in turn renders this as part of the user's profile screen. This option is perhaps the other extreme, least "separate" from the Facebook site.
The third option, which I have adopted, has the application run inside of a "canvas" page (http://wiki.developers.facebook.com/index.php/Your_callback_page_and_you). A user who is "on" Facebook follows a link to a specific page within of Facebook. This page appears as a normal Facebook page with menus etc, but contains an IFRAME which dominates the major content area. It is here I shall have the Facebook Trumps application run.
Labels: facebook api, java
Language Choice: Java
I chose Java. Java is a "proper" programming language - it is object oriented, typesafe and it is backed by two massive corporations (http://java.sun.com/ and http://www.ibm.com/developerworks/java). As I see in my day to day job massive corporations use Java to create complex business systems.
Skills gained in this language I believe will have more value than more lightweight languages such as PHP or "designer" oriented packages like Flash. Java is also free, unlike .Net, but very similar both in syntax and architecture (http://www.google.com/search?q=java+c%23).
The real alternate which offered itself was Ruby, or its web component, Rails (http://www.rubyonrails.org/). So many comments about this language rave about it and say how productive it is, and how it encourages you not to reinvent wheels. Both of these arguments are tempting, however for now I feel Java is more established, and for now, a better skill to learn.
Labels: .net, flash, gwt, java, php
