Monday, 28 February 2011

Mootools and the Closure compiler

I (and Dan over at teadriven) have been battling with the Google Closure Compiler for a few days now. I say "we". As the more javascript literate Dan has been doing the vast majority of the work while I poke things with sticks and apply googlefu to trying to find solutions to problems.

The first interesting thing is that, if you search for information about how mootools works with the closure compiler, you'll find next to nothing. There's a very brief post from 2009 claiming that mootools + closure compiler "behaves quite nicely", and a couple of posts stating that you can only use advanced optimisations on closure if you've designed your code for it, and you know what you're doing. Setting the "you need to know what you're doing" part of it aside for a moment the implication is that mootools and closure don't behave quite nicely together at all. This tallies with what we've seen. Initially we were thinking we just needed to provide an externs file for Mootools and we were a little surprised that one didn't exist in the closure contribs. Then Dan started trying to make one while I blithely disappeared to try to fix my bike, which is a whole different story. A story punctuated with increasingly irate/despairing IMs popping up on my phone as the fundamental differences of opinion between Closure and Mootools started to become apparent.

We're nearly at a point where our js has been hacked to work, but it's not a case of having made Mootools and Closure work well together. And here's some of the reasons why:

  1. Javascript sucks at object orientation. Why is that a problem? Because there's no standard way to do object orientation in javascript. Mootools and Closure approach the problem differently. Closure requires javadoc tags to help it to parse the javascript correctly, and there's currently no tag that allows you to describe a mootools-style object definition. Therefore Closure doesn't like Mootools.
  2. Closure doesn't like you messing with Element. More accurately, it doesn't like you overloading the w3c Element. Mootools does overload Element (I know, technically it doesn't, it redefines it). Therefore, Closure doesn't like Mootools.
  3. There is no externs file for Mootools. If you want to use Mootools without compiling it in to your code, you need an externs file. Currently, none exist. Therefore, Closure doesn't like Mootools. Until the other problems are solved, there's no point making one which I suppose explains this.
The last problem is relatively trivial but the first two are real issues. For the first, the best way I can see around it is for the Closure compiler code to make explicit provision for the Mootools way of doing things, probably through a specific javadoc tag. I'm sure this isn't high up the priority list for The Google. We've pulled the source, though, so there's at least the chance we'll find the time to attempt to hack such a thing in. You can sort of hack your javascript into line, though.

To create a class in Mootools, you pass in an object of properties and functions to the Class function, which then spits out a new one of the things defined by the object you passed in. There's nothing there that's inherently wrong from Closures point of view, except you need to somehow tell Closure that this is a class instantiation based upon the object you pass in (it is expecting you to be a little more traditional and create a class with a constructor function which you tag with a @constructor javadoc). Closure is, therefore, confused by what "this" you're referring to inside the class. This can hackily be resolved on a case-by-case basis by liberal use of the @this javadoc tag, which is messy. It'd be much nicer to be able to tag something as a mootools-style constructor in Closure, and that would also allow Closure to understand the object inheritance tree (which is sort of broken with this hack).

As for problem two - again, I can't really find anything on the web that talks about this. I suppose nothing else (other than mootools) really tries to overload Element, so no one else has this issue. Not entirely sure why Closure protests, or how one is supposed to tell it that you're overloading/redefining Element and no, really, that's fine. I suppose going through Mootools and renaming Element as "Mooliment" or something could, potentially, be a workaround.

Slightly frustrating to have no definitive resolution to tail this post, but there's so little information out there about this problem at time of writing that even a "mootools and closure don't work well together" post seemed like a useful contribution of sorts.

Monday, 11 October 2010

Browser game development.

For the past....oooh, three quarters of a year? I and a couple of friends have been working on a little project in our spare time. I've played a few browser based MMPORPG in the past, and I've often criticised them. In some cases - such as the now-defunct Nexus War - because I've just enjoyed the game so much that the bits that I'd do differently become huge in my mind. In others, like Shintolin it's more that I'm frustrated that the developer seems to have lost interest before an interesting concept has really reached fruition. There's also an element of arrogance, I suspect, in that I know best and all these people are doing it wrong (that's almost - but not quite - entirely a joke). Of course, it's easy to be a backseat coder so earlier this year I, with a couple of like-minded, foolhardy friends, decided to put my build chain where my mouth is and write a browser game. I liked the idea of a stone-age sandbox-y game so, with apologies to Shintolin, began work on a project currently bearing the working title "Henge".

There're quite a few things that I've learned along the way - work on the game has seen my try out (and hate) Seam, has seen me tinker with and discard Eclipse, Netbeans and ultimately Java itself. Which is noteworthy mainly because part of the motivation behind this project was to learn Java. Ho hum. On the other hand, my game has definitely been raised in the C# stakes - I've moved from rather disliking the language to an appreciation that it is, in fact, fricking cool. I've learned a lot about NHibernate, which was really handy for work. Sadly, despite it proving extremely useful for non-Henge purposes it became apparent (at least to two thirds of the team) that even with NHibernate, a SQL database was forcing too many compromises on us, so we ditched it almost entirely in favour of db4o. My word, there was a decision that led to a ludicrous amount of work. On top of that, Henge has allowed me to get to know and to love git. I've moved from cvs to subversion to git over the years and each step has been a massive leap forward. As much as I've championed subversion in the past I have to say - these days, if you're not using git you're almost certainly doing versioning wrong.

And after all that - and a lot more - we still don't have a playable game. As it stands at the moment, you can create a character, walk around a map, starve to death and drown. But it's getting there. There's an awful lot of architecture in place now. Hopefully one day you'll be able to play it and see what all this effort has been for. But one of the big things this has shown me? All those one-man bands who managed to design and build their own browser game, from the sophistication of Nexus War to the simplicity of Urban Dead and even the semi-complete mess (sorry, really I am, but look at the code. It needs a rewrite!) of Shintolin... they all all managed to do an amazing thing. Getting one of these things up and running is bloody hard work. Or, at least, that has been my experience of it so far.

Hopefully I'll find the time and motivation to write a little more about the design of henge before I forget too much about it; it's already started to happen - there are things that I've had to spend a long time figuring out twice because I forgot why we did them the way we did them in the first place. If not, I hope at least to get enough working to let some people poke it with sticks until it falls over.

Updating a Samsung Galaxy S i9000 the "official" way

Before we start, I'd say that going through this is beyond painful. The only reason to do it this way is if you particularly care about being able to claim on your warranty with Samsung if things go tits up. That or a sense of bloody-mindedness.

What You Will Need:

  • One i9000 (rooted or not shouldn't matter, but you'll probably need to be running stock firmware. For the record the one device I've got this working on was running stock, Orange-branded firmware, was not rooted but was SIM unlocked).

  • One Windows machine, physical or virtual. I was running XP pro on a VMWare virtual machine in an Ubuntu host but also verified every step except actually blowing the image on a physical machine; they behaved similarly. The VM was, if anything, a better experience than the physical machine. All windowses involved are 32bit, ymmv with 64 bit (I have seen reports of problems running on a 64 bit machine).

  • Patience.

How To Make The Damn Thing Do What It Should:

First, Install Windows Media Player 11. If you don't have this, one of two things will happen. Either kies (the samsung piece of crap you're about to use) will simply refuse to install or it will install perfectly happily, but will be unable to communicate with the phone. The symptom of the former is that the install process will hang waiting for a .cab file to be downloaded (sitting at 0% progress) and then abort with the error message "Installation Aborted". The symptom of the latter is that when you plug your phone in to the machine ready to connect to kies, Windows will detect a new MTP device and begin installing hardware but never complete the process. Should you end up in this state, just press the home button on your phone and disconnect it. Windows will eventually give up trying to install the hardware and tell you that it may not work properly. I've also noticed mysterious shutdowns happening on the phone a couple of minutes after disconnecting it when this second situation occurs. You may need to yank the battery to bring it back to life since the phone may well not respond to the power button.

If you've already hit either of the above problems but haven't installed Windows Media Player 11, you don't need to uninstall kies - just install WMP 11. You'll need to reboot the machine after installation, but then things should begin to work.

Now download Kies and install it. I used version 1.5.3.10093_80. When Kies starts up it may ask you to let it update itself (or it may not; on my VM it didn't on my physical machine it did). I didn't manage to get it to work after updating, though that isn't to say that it wouldn't; simply that I hadn't figured out all the rest of the workarounds yet. Regardless, you can certainly update your phone without running an updated kies. It's up to you if you want to take a punt and update. Close Kies down again and open up the registry editor (enter "regedit" into the Run... dialogue on the start menu). You need to add two registry keys in order to stop the firmware update software from recursing its way into a stack overflow as it tries to look for them when you start the upate process:
  • In System/HKEY_Local_Machine/Software/Samsung add a new key named FUS
  • In System/HKEY__CURRENT_USER/Software/Samsung add a new key named FUS
Close the registry editor and restart kies. If you don't do this, the firmware update will stall at 0% trying to download binaries, and eventually you'll get an error message about MSC.Thunder.FirmwareUpdate running out of memory. If this happens to you don't worry; the updater hasn't actually started doing anything to your phone yet. Once it's crashed you can just unplug your phone.

Over to the phone now: Switch your phone to Samsung Kies mode in the USB settings menu (which is hidden inside the "About Phone" menu in the main settings menu) and switch your launcher to TouchWiz or Kies won't play nice. I set it as the default for the upgrade, just to be safe. Navigate to the homescreen and plug your phone in to the PC. If you're lucky, you'll get the MTP screen up on the phone with the message "Initialising" shortly followed by "Connected". If you're unlucky your phone will, at this point, go mental and start rapidly switching between the homescreen and the MTP screen. In this case, unplug the USB cable and go on the phone to settings->SD card and phone storage->Internal SD card. Unmount and format the internal SD card. Plug the phone back in to the PC, and you should get to the "Connected" screen. Kies should now see your phone pretty quickly, and offer you a firmware update (if one is available). It should be plain sailing from this point, just go through the update process marvelling at the incomprehensible language used in the dialogues. Don't mess with your phone at all until the update is complete.

Once the update is complete, your phone will sit on the S splash screen for what seems like an age. It'll also be extremely unresponsive after it finally starts up. I assume it's doing some book keeping behind the scenes, since this will pass after a short while.