Sunday 16 September 2012

WWX & Try Harder 2012



I just realised that I still hadn't posted anything about the Haxe conference, WWX 2012, I attended at in February of this year, how lax of me! Well actually I was waiting for the videos to be released so I could give a link to the lightning talk I gave on my WebGL experiments from last year. (Un)fortunately however, the lightning talks weren't recorded so you cant see my nervously mumble through my presentation.

I can however link to the videos from all the other speakers that attended the event which were excellent BTW:

http://www.silexlabs.org/?s=wwx

While im here I thought I would mentioned that Im going to be attending try { harder } next month for the second year in a row. As last year the idea is that everyone that attends gives a talk on a topic, it was a fascinating but brain-intensive 4 days last year, im definitely hoping for some more of the same this year!

Tuesday 11 September 2012

All New Post To Tumblr Chrome Extension created with Haxe & Robotlegs



I have been working off and on for a while on an update to my popular Chrome Extension 'Post To Tumblr' and seeing as Tumblr have just changed thier API I thought it was time to accelerate its development and release it, finally.

First some screenshots to give you an idea of what it does:



You can right-click any thing on a page and "Post To Tumblr".



A new tab opens where you can format it how you like.



You can change the post type very easily.



When done you just "Create Post"

This version is written totally from scratch using Haxe's Javascript target. Although not strictly necessary for something as simple as this I thought it was a good opportunity to experiment around with Haxe's JS capabilities. I must admit I was pleasantly surprised at how well it worked.

Most stuff just worked. There are also plenty of externs out there for the popular Javascript libraries on lib.haxe.org such as the "chrome-extension" library.

Having type-safe Javacript is great for for so many reasons that im not going to get into here. I must admit however there were times when I was lazy and didn't want fancy creating a type-safe extern class for a library. Fortunately however Haxe has a mechanism for the lazy coder in the form of "untyped".

An example of this is the way in which you access the "localStorage" object in chrome extensions. localStorage is basically a global object that you can set keys and values in and will persist for the life of your extension. To access it you use: "localStorage[myKey]" to return a value. If you tried to do that in Haxe it would throw an error because Haxe has no concept of global variables (quite rightly).

So to access the localStorage you can use untyped to quickly get access to a global variable, I then decided to wrap this little hack in a Model class to make it a little neater:

[codesyntax lang="actionscript3" lines="normal"]
package models;
import js.Lib;

/**
* ...
* @author MikeC
*/

class ChromeLocalStorageModel extends BaseModel
{

public function get(key:String) : Dynamic
{
var val = untyped localStorage[key];
trace('Getting from localStorage: '+key+" :: "+val);
return val;
}

public function set(key:String, val:Dynamic) : Void
{
trace('Saving in localStorage: '+key+" :: "+val);
untyped localStorage[key] = val;
}

}

[/codesyntax]

This lets you just just mix and match the type-safe stuff when you need to and just do a little "hack" when you need to ;)

The above example also shows off another cool feature im using in Post To Tumblr, which is RobotLegs. Thanks to the fact that the RobotHaxe library is written in pure Haxe (has no platform specific bits) that means I am able to use it on a Javascript project.

The only problem is the issue with Views and Mediation. Because unlike Flash events don't bubble up to a central source there is no way to do automatic mediation in the JS target. Instead what you do is implement "IViewContainer" on your context view, then whenever a child is added or removed you call viewAdded() or viewRemoved() that way the MediatorMap can try to make a mediator for that view.

Im not sure if the way I have used RobotLegs is the correct or best way, it was more of an experiment as I went along. The way I have done it is to wrap many of the main HTML elements in my own view classes. So for example I have a "DivView" that represents a "div" and extends BaseView:

[codesyntax lang="actionscript3" lines="normal"]
class DivView extends BaseView
{

public function new(elementId:String=null)
{
super(Lib.document.createElement('div'));
if (elementId != null) element.id = elementId;
}

}

[/codesyntax]

BaseView implements the IViewContainer interface:

[codesyntax lang="actionscript3" lines="normal"]
class BaseView implements IViewContainer
{
public var viewAdded:Dynamic -> Void;
public var viewRemoved:Dynamic -> Void;

public var element : HtmlDom;
public var parent : BaseView;
public var children : Array;

....

public function new(element:HtmlDom)
{
this.element = element;
this.children = [];
isLayoutInvalid = true;
}

...

public function add(child:BaseView) : BaseView
{
children.push(child);
child.parent = this;
child.viewAdded = viewAdded;
child.viewRemoved = viewRemoved;
if(viewAdded!=null) child.addChildren();
element.appendChild(child.element);
if (viewAdded != null) viewAdded(child);
return child;
}

public function remove(child:BaseView) : Void
{
if (viewRemoved != null) child.removeChildren();
children.remove(child);
child.parent = null;
child.viewAdded = null;
child.viewRemoved = null;
element.removeChild(child.element);
if (viewRemoved != null) viewRemoved(child);
}

...

}

[/codesyntax]

Then say I want to construct the following html:

[codesyntax lang="html4strict"]
<div id="container">
<div id="inner">Hello World!</div>
</div>

[/codesyntax]

I would do something like this:

[codesyntax lang="actionscript3" lines="normal"]
class MainPopupContainer extends DivView
{
private var inner : DivView;

public function new()
{
super("container");

inner = new DivView("inner");
inner.element.innerHTML = "Hello World!";
add(inner);
}
}

[/codesyntax]

Then perhaps I want to turn the "Hello World!" red when clicked I would do something like this:

[codesyntax lang="actionscript3" lines="normal"]
class MainPopupContainer extends DivView
{
private var inner : DivView;

public function new()
{
super("container");

inner = new DivView("inner");
inner.element.innerHTML = "Hello World!";
add(inner);

new JQuery(inner.element).click(onInnerClicked);
}

private function onInnerClicked()
{
inner.element.style.color = "#FF0000";
}
}

[/codesyntax]

What this means is you have a RobotLegs-familiar looking View with a Mediator behind it (thanks to the mediation happening when you call add()) which is nice. What it does mean however is I have quite abit of boiler plate wrapping the HTML nodes, which definitely slowed down my development.

Another thing im not sure about is my mixing of in-line styles and stylesheets. Sometimes I would use the styles in my css and other times I would just set them on the element directly. To be honest, because I was using classes and inheritance and all that good stuff I usually found it easier and more expedient to set the styles inline in my View class rather than go digging through several hundred lines of css to find the selector I was looking for

For example I may have a "HeaderOptionButton" that defines some inline styles then whenever I wanted a button that looked and acted like a header button I would just make and add a HeaderOptionButton. I know im probably going to get flamed to hell and back for that!

As I said, im not sure if im doing it the "right" or "best" way, its just the way that seemed to work at the time ;)

Well that's a quick overview of where im at. Once I have cleaned the project up a little and added some missing features ill be sticking the source up on GitHub for anyone interested.

Saturday 8 September 2012

Mr Nibbles - The Post Mortem



Well its been a couple of weeks since we launched on iOS and a few weeks since Android, so I have decided to write one more post on the Mr Nibbles project. A post mortem into what went right, what went not so right which should hopefully serve to solidify my learning from the process and perhaps help others who should embark on something similar.

Before I dive into that, first some statistics thus far..

Statistics


Android



We have had 2,867 User installs and 1,623 active device installs. Not bad :)

iOS



3,789 iOS installs, making a grand total of 6,656 mobile installs, not bad :)

The Process


So from the beginning the this project was to be a quick turn around project. The idea was to try and complete the whole thing in three weeks. It actually ended up being more like 5 weeks for me and 4 weeks for Moh the artist (he was on holiday for one of those) but still not months of development which I wanted to stay clear of.

For me, short time-scale games are so much more fun to make than long games. In a short time you can iterate quickly over the core idea then get it out there quickly and see what people think. When time constrained you are are forced to only implement the core functionality and discard the rest. In all likelihood the other stuff is probably just fluff anyways and not really necessary to the game.

As for the time-overrun, there is no one main reason for it. Lots of small things such as; unfamiliarity with NME / iOS / Android development, windows / osx development workflow and testing taking longer than expected. Making and testing each of the 30 levels took alot more time that I had anticipated. Working around some small NME issues (more on that below) took some time. Writing these blog posts every week (sometimes more) took some time out of what could have been development time too (more on blogging below).

The hours we worked on the project were actually okay. Because this was a personal project and both of us have full time jobs at Playdemic we could only work on the game during our evenings and weekends. During week days we tended to start about 6-6:30pm then work until we were kicked out of the office by the security guard. 8:30-ish usually. Occasionally (mostly towards the end of the project) we stayed a little later to get stuff done before release.



This sort of schedule and working pattern suited us both. Being able to see who you are working with and talking face to face I think really adds to the experience and fun of making an indie game. Its definitely more exiting to run over and show the other person some cool new level on your iPad rather than try to describe it over MSN from your bedroom. Working like this obviously wouldn't have been possible if the management at Playdemic weren't so awesome by allowing us to use the office after normal office hours so definitely a massive thanks there.

Blogging


I strongly feel that blogging everything is one part of the process I definitely wouldn't change. Sometimes I choose to work in private on some projects however  this one I decided to be very public, announcing upfront the intent and regularly updating on progress. Blogging regularly and getting feedback on progress really encouraged me to stick with it every singe evening. It also served as a way to keep the project fun (absolutely critical for me) as the immediate feedback from people would serve as a basis for ideas and improvements.

Also writing things down has been proven to encourage stronger learning and memory retention, so hopefully in the future I wont make the same mistakes ;)

Haxe + NME


I have been using Haxe for over a year now for various personal and professional projects so I was fairly familiar with the language going into this project. Haxe is a good language, similar to AS3 / ECMA based langues and so it shouldn't feel too alien to a seasoned flash developer. It does however come loaded with many improvements over AS3 such as proper generics, type inference, macros and many more awesome features.

NME is a library built ontop of Haxe. It provides a familiar flash api but is able to many platforms natively. Using exactly the same Haxe code base I was able to compile Mr Nibbles to Flash, iOS, Android, Blackberry, Windows and OSX thanks to NME. The library really is great for this sort of fast-turn-around game. Mr Nibbles certainty wouldn't have been possible without it (not in 5-weeks anyways).

The NME developers have put a lot of time into making the build and certification process as easy as possible for the various platforms. So with "nme setup android" from the command line for example you are able to download and setup the android SDKs and get your certs setup in the correct place for building. Its really great to see that sort of dedication to making the cross platform compilation process as smooth as possible.

The performance of NME is truly great. Thanks to its batched sprite rendering there are very few draw calls and expensive texture-switching. Mr Nibbles runs at solid frame rates on pretty much every smartphone you can think of from the Android G1to the Galaxy S III to the iPhone 3G to the iPad3. After having worked with the nightmare that is J2ME mobile games in the past, being able to run your game on so many devices without any code changes really is a pleasure.

NME isn't perfect however and does have a few issues such as slow and imperfect vector rendering from SWF files. It is however constantly constantly being worked on and im sure it wont be long before the issues are ironed out.

Because both NME, Haxe and most of the third-party libraries are open source you are always free to dive in and fix any issues yourself. For Mr Nibbles, the SWF rendering was "good enough", such that we were able to make nice looking menu screens that dynamically scaled to any device resolution and pixel density (a real time saver!). Most of the time when I ran into the issue I would post it on the NME mailing list. More often than not it would be answered (often by the NME-super-hero Joshua Granick) within an hour or less!

iOS


iOS was definitely the primary platform we were developing Mr Nibbles for. Mostly because it was the platform I owned a mobile and tablet device for ;) To develop for iOS you need to use osx and xcode, so I took my MBP into the office and hooked it up via Ethernet to the network. I setup a shared folder on my desktop machine and the pointed xcode on my MBP to that shared folder. That way whenever I made a change on my windows computer I would only have to hit one button in OSX to rebuild and test on my iOS device. It was a real time saver over the other approach I was previously using, syncing over Dropbox.

There were are few frustrating moments towards the end of the project when I was running into issues regarding ArmV6 and ArmV7 when NME was compiling. Fortunately I noticed in the nmml spec for NME there was an option to compile to "FAT" which seemed to make the issue to away ;)

Android


Android was a lot easier to iterate and test because it could all be done from my desktop machine. In hindsight, and with the devices that only became available towards the end of the project, it would have been better if we had concentrated on the Android build first then ported to iOS later. Once we had some devices to test on however I was incredibly impressed with how easy it was to build and launch the game onto an Android device with NME. Literally just "nme test android" from the command line and it would compile and launch directly to the device, no faffing about.

Since launch there have been a few issues with audio crashing on Android. However I believe some people have been working on this so I may do a new build of Android in the near future and push an update of the game to the Google Play store.

Blackberry


The blackberry build has only been finished very recently, hence the lack of stats thus far. It was actually really easy to build for Blackberry, again just a matter of changing a single word on the command line "nme rebuild blackberry" and that was it.

The hardest part was testing it as I had no Blackberry device to test on. Joshua Granick was extremely kind and offered to test the game out on his device. Not only that, he put in a kind word and managed to get a Playbook shipped out to me so I could test too, thanks Joshua :)

Conclusion


Overall I had an absolute blast working on this game. Sure it was hard work, alot of evenings and weekend spent in the office till 9pm and sure it went over budget by two week but it doesnt matter because I was having fun the entire time.

This is what making games is all about for me, if you want to have fun programming I cant think of a better way than to make than to develop short-project games. Haxe with NME were instrumental in making the process as fun as possible by taking out much of the bull sh*t with cross-platform development, letting you get down to business of turning your ideas into reality. So massive thanks to everyone that has worked on developing Haxe and NME.

Finally I want to say a massive thanks to my colleague and artist partner on this project Moh who's time and hard work made Mr Nibbles come alive, nice one Moh!

Mr Nibbles & Blackberry



Im proud to announce that Mr Nibbles is now available on Blackberry App World :)

Thanks to the cross-platform nature of Haxe and NME it was actually really easy to do. Just a matter of changing a single word on the command-line: "nme build blackberry" and that was it, everything just worked out of the box!

I want to give a massive thanks to Joshua Granick for helping with some of the strange certification issues I was getting. Joshua also very kindly helped test the blackberry build out on his Playbook before very kindly asking RIM to ship one out to test on myself.

Joshua also recently written a blog post on the Blackberry developer blog highlighting the awesomeness of NME and its ability to target Blackberry devices natively:

http://devblog.blackberry.com/2012/09/fast-native-games-for-blackberry-without-cc/

He was also kind enough to mention Mr Nibbles in the post :)

So that means Mr Nibbles is now available on the Web, Android, iOS and Blackberry. I wonder where it can go next!