Error 2048 and Flash Policy File Logging

Whenever you are working with Flash or Flex applications which make use of 3rd party feeds or data sources (such as XML or JSON), you need to be aware of how the Flash Player deals with Cross Domain security issues.

The easiest way to debug a 2048 Security Error is to enable Policy File logging in your mm.cfg; Adobe have a guide posted over on their site which explains how to get setup.

Posted in ActionScript 3 | 1 Comment

FlexPMD and ANT – RuleSetFactory Error

Just a quick post to save someone a few minutes of headscratching! I’ve just finished integrating FlexPMD, Adobe’s latest opensource offering into my ant build scripts following their documentation when I hit this error:

java.lang.NoClassDefFoundError: net/sourceforge/pmd/RuleSetFactory

Looking at my taskdef, everything appeared to be in order, it wasn’t until I searched the Adobe JIRA and managed to find this ticket. What’s even more annoying is that the ticket is marked as Closed!

I would update the wiki entry on the adobe site, but when I try and log in the site stacktraces…

Posted in ActionScript 3 | Tagged , | Leave a comment

Automatically Generating a Maven POM file with ANT

This one tripped me up for a while and doesn’t seem to be mentioned in the Maven ANT Tasks Documentation. I was working on a build process which makes use of Maven soley for deploying and versioning releases and ANT for the rest of the build. One thing I wanted to eliminate was the large amount of POM files which were scattered around the project, all of which were basically the same and could most certainly be auto-generated.

The Maven ANT Tasks indicate that the <pom /> task can be used to create an “in-memory” pom which can then be used in the <deploy /> task. With that in mind, I wrote the following:

&lt;artifact:pom id="maven.project" groupId="com.example" version="${build.version}" artifactId="${project.name}" packaging="zip"&gt;
	&lt;remoteRepository id="releases" url="http://maven:8081/nexus/content/repositories/releases" /&gt;
&lt;/artifact:pom&gt;
&lt;artifact:install-provider artifactId="wagon-http-lightweight" version="1.0-beta-2" /&gt;
&lt;artifact:deploy file="deploy/${project.name}.zip">
    &lt;pom refid="maven.project" /&gt; 
&lt;/artifact:deploy&gt;

However, when this ran, the build failed with the following error: “A distributionManagement element or remoteRepository element is required to deploy“. Very confusing, especially as I specified the <remoteRepository /> node as a child of the <pom />. I concluded that this was not a problem with the <deploy /> task as when I dump the contents of “maven.pom” out to disk via <writepom /> I could see that, sure enough, the <repositories /> node was not being created in the POM file! This is where I hit a brick wall and I can only presume it’s a bug with the current Maven ANT Tasks (2.1.0).

With that in mind, I tried modifying the <deploy /> task, adding the <remoteRepository /> node to that instead – again, no joy, same error.

In the end I got it to work with a little bit of a workaround involving temp files – this works fine for me but it’s not ideal, hopefully someone out there has encountered this one before:

&lt;!--  Generate a Dynamic POM file --&gt;
&lt;artifact:pom id="pom.tmp.ref" groupId="com.example" version="${build.version}" artifactId="${project.name}" packaging="zip" /&gt;
 
&lt;!--  Write the generated POM file out to a temporary file on disc --&gt;
&lt;tempfile property="pom.tmp.file" /&gt;
&lt;artifact:writepom pomRefId="pom.tmp.ref" file="${pom.tmp.file}" /&gt;
 
&lt;!--  Read the temporary file back in as the POM reference --&gt;
&lt;artifact:pom id="maven.project" file="${pom.tmp.file}" /&gt;
 
&lt;!-- We can now deploy, but we have to include a reference to the repository --&gt;
&lt;artifact:install-provider artifactId="wagon-http-lightweight" version="1.0-beta-2" /&gt;
&lt;artifact:deploy file="deploy/${project.name}.zip"&gt;
    &lt;pom refid="maven.project" /&gt; 
    &lt;remoteRepository id="releases" url="http://maven:8081/nexus/content/repositories/releases" /&gt;
&lt;/artifact:deploy&gt;
Posted in ActionScript 2 | 1 Comment

Sorting Values Stored in a Dictionary

Looking through my incoming seaches from Google I’ve noticed that a lot of visitors to my site are trying to figure out how to sort values stored in a Dictionary. The short and simple answer is that you can’t as Dictionary’s in AS3 are meant to represent un-ordered HashMaps, however, there’s nothing to stop you moving the un-ordered data out of the Dictionary and into an Array:

package {
	import flash.display.Sprite;
	import flash.utils.Dictionary;
 
	/**
	 * @author Jonny Reeves
	 */
	public class DictionarySort extends Sprite 
	{
		function DictionarySort() : void
		{
			var myDictionary : Dictionary = new Dictionary();
 
			// Provide some values to sort.
			myDictionary[500] = "Five Hundred";
			myDictionary[55] = "Fifty Five";
			myDictionary[1] = "One";
			myDictionary[231] = "Two Hundred and Thirty One";
 
			var myKeys : Array = this.extractKeysFrom(myDictionary);
			trace("myKeys Array before sort: " + myKeys);
 
			// Apply a Numeric sort to the Array.
			myKeys.sort(Array.NUMERIC);
			trace("myKeys Array after sort: " + myKeys);
 
			// You can now use the extracted Keys to read from the Dictionary in
			// the required order.
			for each (var thisKey : * in myKeys)
			{
				// Will trace out the number followed by the english words.
				trace(thisKey + " = " + myDictionary[thisKey]);
			}
		}
 
		/**
		 * Helper method to extract the Keys from a Dictionary Object and return
		 * them in an Array.
		 */
		private function extractKeysFrom(source : Dictionary) : Array 
		{
			var output : Array = [];
 
			// Note that Dictionary's Keys are untyped as they can contain
			// any value.
			for (var prop : * in source)
			{
				output.push(prop);
			}
			return output;
		}
	}
}
Posted in ActionScript 3 | Tagged , , | 4 Comments

Sorting values in ActionScript 3

One of the next big projects at work will involve displaying a list of data to the user, this list will be generated server side and sent down as un-ordered XML, it is up to the client to sort the data and display it to the user. The system will need to be able to sort a large amount of data (at present, the server could be sending down up to 10,000 records) and we needed to find out if this sorting would be fiesable – to find out, I set up a quick little test script which provides a couple of interesting findings:

package 
{
	import flash.display.Sprite;
	import flash.utils.Dictionary;
	import flash.utils.getTimer;
 
	/**
	 * @author Jonny
	 */
	public class Sorting extends Sprite
	{
		public function Sorting()
		{
			var source1 : Array = this.generateViaIndexOf(10000);
			var source2 : Array = this.generateViaDictionary(10000, false);
			var source3 : Array = this.generateViaDictionary(10000, true);
 
			this.sort(source1, Array.NUMERIC);
			this.sort(source2, Array.NUMERIC);
			this.sort(source3, Array.NUMERIC);
 
			debugOutput("indexOf", source1);
			debugOutput("nonCast", source2);
			debugOutput("cast", source3);
		}
 
		private function debugOutput(name : String, values : Array) : void
		{
			trace(name + "[0] = " + values[0] + ", " + name + "[1] = " + values[1]);
		}
 
		private function sort(source : Array, sortMethod : uint) : void
		{
			var startTime : uint = getTimer();
			source.sort(sortMethod);	
			trace("Array sorted in " + (getTimer() - startTime) + "ms.");
		}
 
		private function generateViaDictionary(length : int, castOutput : Boolean) : Array
		{
			var startTime : int = getTimer();
 
			var pushed : Boolean;
			var dictionary : Dictionary = new Dictionary();
			while (length--)
			{
				pushed = false;
				while (!pushed)
				{
					var thisRand : uint = Math.ceil(Math.random() * 100000000);
					if (dictionary[thisRand] == undefined)
					{
						dictionary[thisRand] = true;
						pushed = true;
					}
				}
			}
 
			var output : Array = [];
			for (var prop : String in dictionary)
			{
				if (castOutput)
				{
					output.push(parseInt(prop));					
				}
				else
				{
					output.push(prop);
				}
			}
 
			trace("Source Array containing " + output.length + " items created in " + (getTimer() - startTime) + "ms.");
			return output;
		}
 
		private function generateViaIndexOf(length : int) : Array
		{
			var startTime : uint = getTimer();
 
			var pushed : Boolean;
			var output : Array = [];
			while (length--)
			{
				pushed = false;
				while (!pushed)
				{
					var thisRand : uint = Math.ceil(Math.random() * 100000000);
					if (output.indexOf(thisRand) == -1)
					{
						output.push(thisRand);
						pushed = true;
					}
				}
			}
 
			trace("Source Array containing " + output.length + " items created in " + (getTimer() - startTime) + "ms.");
			return output;
		}
	}
}

When run, this code produces the following output:

Source Array containing 10000 items created in 3082ms.
Source Array containing 10000 items created in 71ms.
Source Array containing 10000 items created in 102ms.
Array sorted in 19ms.
Array sorted in 312ms.
Array sorted in 17ms.
indexOf[0] = 4532, indexOf[1] = 14806
nonCast[0] = 3553, nonCast[1] = 6646
cast[0] = 10432, cast[1] = 22513

We can immediatley draw the conclusion that performing Array.indexOf to determine if a value is unique in a given array is woefully inefficient, the use of a Dictionary (serving as a lookup table) is much better. The other interesting point is that Array.sort(Array.NUMERIC) works quicker if the source values are cast to integers (instead of the Strings a for…var…in loop produces).

For those interested, my final stratergy will be to parse the data returned from the Service layer into strongly typed Objects and then store these in a Dictionary mapping User.id => User Object, then when I need to perform a sort I can simply dump the keys from the Dictionary into an Array.

Posted in ActionScript 3 | Leave a comment

Using Dictionary Objects to Map Classes and Instances

This is a neat little ActionScript 3 trick which I’ve been using more and more of recently that I thought I would share.  The basic premise is that it allows you to use a dictionary which maps Classes to other data, the twist is that you can supply either the Class definition or an instance of the Class as the key.

The most obvious example I have come across for this is when creating Asset Mappings. Let’s say I have a generic Model-esq class, ie: a Car and I know that each instance of Car (Ferrari, Porsche, etc) has an assosiated asset (ie: a SWF file). These assets are stored on the server and use the name property as part of that assets filename, for example:

  • Ferrari maps to /flash/assets/cars/ferrari.swf
  • Porsche maps to /flash/assets/cars/porsche.swf

Now, it’s clear that the “/flash/assets/cars/” part of the URL is common to all instances of the Car class and we can leverage this fact when building URLs with the help of a URLManager Class and a common interface that all Model objects which contain Asset Paths share:

Car Class

package uk.co.jonnyreeves.classmapping {
 
	/**
	 * Example Model Class for a Car
	 */
	public class Car implements IContainsAssetPath
	{
		/**
		 * The name of this Car.
		 */
		private var name : String;
 
 
		/**
		 * Constructor.
		 * @param name		The name of this car.
		 */
		public function Car(name : String)
		{
			this.name = name;
		}
 
		/**
		 * Returns the name of this car.
		 */
		public function getName() : String
		{
			return this.name;
		}
 
		/**
		 * Return the filename for this Car's Asset SWF.
		 */
		public function getAssetPath() : String 
		{
			return this.name + ".swf";
		}
	}
}

IContainsAssetPath interface

package uk.co.jonnyreeves.classmapping {
 
	/**
	 * Common Interface for all Models with Assets
	 */
	public interface IContainsAssetPath 
	{
		/**
		 * Returns the final stub path to this asset.
		 */
		function getAssetPath() : String;
	}
}

Finally, the URLManager which will help build the URLs for all Models which implement IContainAssetPath

URLManager Class

package uk.co.jonnyreeves.classmapping 
{
	import flash.utils.Dictionary;	
 
	/**
	 * Helper for building URLs from Car Objects.
	 */
	public class URLManager {
		/**
		 * Dictionary which will contain mappings between Class Definitions
		 * and URL Stubs used to build asset paths.
		 */
		private static var objectMappings : Dictionary = new Dictionary();
 
		/**
		 * Singleton Instance.
		 */
		private static var instance : URLManager;
 
 
		/**
		 * Singleton Accessor Method.
		 */
		public static function getInstance() : URLManager
		{
			if (instance == null)
			{
				instance = new URLManager();
			}
			return instance;
		}
 
		/**
		 * Private Constructor for Singleton Pattern.
		 */
		public function URLManager() 
		{
			createObjectMappings();
		}
 
		/**
		 * Populate the ObjectMappings Dictionary.
		 */		
		private function createObjectMappings() : void 
		{
			// Here we create relationships between the Class definitions and their
			// URL Stubs.  We use the constructor object to create a common relation
			// between ClassDefinitions and instances of those Class Definitions.
			objectMappings[Car.prototype.constructor] = "/flash/assets/cars/";
		}
 
		/**
		 * Retrieve the AssetURL for the supplied instance of the IContainsAssetPath interface
		 */
		public function getAssetURL(source : IContainsAssetPath) : String
		{
			// Here we can extract the constructor object from the incoming IContainsAssetPath
			// implementation.  This will be the same object as the one we stored in 
			// this.createObjectMappings();
			var sourceConstructor : Object = (source as Object).constructor;
 
			// Check to see if a mapping exists for this Class Definition.
			if (objectMappings[sourceConstructor] == undefined)
			{
				throw new Error("Asset Mapping does not exist for object: " + source);
			}
 
			// We can now build the complete URL.
			return objectMappings[sourceConstructor] + source.getAssetPath();
		}
	}
}

The technique relies on the fact that the Class Definition’s prototype will yield the same constructor object as the instance of that Class Definition. This has come in incredibly handy when I only have the Class Definitions avaliable to me whilst writing code but need to create mappings to them at run-time. For those that want a complete the example, here is the source.

Posted in ActionScript 3 | Leave a comment

MoshiMonsters.com Homepage Redesign

As some of you may know, I am currently working for MindCandy as an ActionScript 3 developer hacking away on Moshi Monsters – a safe, online world for kids to learn and play.  This week is a very proud one for myself as the homepage redesign which I worked on went live – I thought I would take the opportunity to explain some of the problems faced and the solutions used.

MoshiMonsters.com Homepage, March 2009

First off I need to give full credit where it’s due; to our amazing designers.  I got to work with three such talented chaps on this project, Trevor, Ben P. and our latest hire, Axel.  These guys spent a good week illustrating the concept for the new homepage and creating the animations and elements which I wired up to make the finished product.

The page splits into two parts, the main body and the navigation is delivered in normal HTML with CSS styling and the central content including the monsters and ocean background are delivered using Flash.  One of the challenges to over-come was the fact the page had to scale horizontally to allow the user to resize their browser, this was achieved by using the ActionScript StageScale.NO_SCALE setting and using SWFObject to set the embed width to 100%.  By registering an Event.RESIZE  listener to the Stage, I am able to adjust the width property of the background gradients’ (which make up the ocean) DisplayObject.  It’s awesome to see the site still look great even when stretched across two 24″ monitors!

One of the key points of the new homepage’s Acceptance Test was that it weighed around the same as the static HTML version it was replacing.  Using firebug, I was able to tell that the original homepage weighed ~360kb; it wasn’t going to be easy providing all this interactivity.  We managed to come in at ~430kb which wasn’t too far off!  We made savings filesize savings on both the HTML and Flash by a combination of CSS Spriting and optimisation of all animations and MovieClips (the majority of the Flash optimisations were done by our Animator Ben P. so you will have to ask him for his tips and tricks!).  We didn’t go down the route of trying to optimise the ActionScript to reduce filesize as legibility is more important to us than a couple of kilobytes at the CDN.

Finally, the last goal of the new site was that it displayed on the user screen as quickly as possible – the last thing we wan the user to see is a massive white hole in the middle of our page whilst it loads!  Pre-Loaders in ActionScript 3 are not quite as intuitive as they used to be in AS2, but thanks to Keith over at Bit-101, they are reliviley straight forward once you know what you’re doing!  During the Preloader we render the background gradients in actionscript which helps the Flash element fit seamlessly with the HTML and CSS while the remaining 200kb loads.  Once the app has finished loading, the user can start interacting with the buttons, watch the tour video, etc.  At this point, we send off a background call to load in the monster animations and sound effects.  The monster anims are all contained in a single swf which weighs in around 130kb – we chose to use a single swf to reduce the number of requests on the web server (infact the entire page now renders in under 15 requests to our own server, down from well over 30!).  The monster animations SWF contains linkages for all the various animations – these are loaded into the Current ApplicationDomain and then initialised via getDefinitionByName.

If you are already a Moshi user then I hope you enjoy the new MoshiMonsters homepage and all the new features that our team keeps working on – and if you’re not yet a member, well get on over there and adopt one today!

Posted in ActionScript 3, Personal | Leave a comment

Steaming HD Content to the Playstation 3 with Windows Media Player 11

This month I took the plunge and upgraded my entire Media Setup in the front room by replacing my ancient Goodmans 32″ CRT TV with a Samsung 37″ 720p LCD.  As with most major upgrades, this started a chain of events which resulted in me replacing my trust soft-modded Xbox running XBMC with a shiny new Playstation 3 to take advantage of the HDMI Output, HD Playback and enhanced upscaling which the system offers over the Xbox. (The compression artifacts on Xvids became incredibly distracting on the LCD screen and the Xbox is simply not powerful enough to play back HD.)

The first step in my journey was to setup a DLNA Media Server to push my media to the Playstation.  I must admit that I was pretty disappointed that I couldn’t just set up SMB shares as I could on XBMC – but then the entire Playstation 3 experience isn’t terribly configurable (I guess Sony recon most people aren’t interested in tinkering!).  After a bit of reading on the AVSForums, I realised that my two options for the DNLA Media Server on Windows Vista x64 were Windows Media Player 11 and TVerstity.  Havnig a bit of a distruct of Windows Media Player, I opted to download and install TVersity from their site – however, during the install I was instructed to turn off UAC (Vista’s User Account Control security model).  I know a lot of people hate UAC but I see it as a serious step forward for Window’s security model and if programmers aren’t willing to write their software to cope and comply with it then I’m not interested in running it – so TVersity was ruled out leaving Windows Media Player as the only option.

Setting up DNLA Media Sharing on WMP11 (Windows Media Player 11) is straight forward – I was also able to add additional folders outside of the “My Videos” folder in my User Account folder visible.  Once this was done (and my PS3 was granted access), My computer showed up in the list of avaliable sources on the Playstation’s ‘Home’ screen and all of my Xvid files were immediatley made avaliable and played back without hassle (Complete with excellent upscaling and filtering with the Playstation 3 offers which smooths out nearly all compression artifacts without making the image appear out of focus).  However, all was not smooth as every 10 minutes or so the video stream would break up between key frames due to network dropouts – a problem which I had not experienced on the Xbox.  I presumed that the dropouts were due to the PS3 not using a large enough cache for the video stream; wireless networks are inherently dodgy and prone to dropouts – I could live with this for the time being, but I knew it would have to be addressed at some point.

I was fairly happy at this point – Xvids were playing back and looking better than on the Xbox, but it was time to try out some HD content and start playing back some video encoded using the h264 codec.

Using Handbrake, I converted a set of DVD VOBs into an MP4 file using the Playstation 3 preset.  The resulting MP4 file looked amazing on the computer via Quicktime and I was looking forward to being able to archive all my DVDs in this new, higher quality format.  I put the MP4 file into the “My Videos” file and then jumped onto the PS3.  When I first looked, I couldn’t see the MP4 file, so I restarted the PS3 – still no MP4 file – this is when I started to get a bit upset.

After a bit of googling I discovered that Windows Media Player 11 does not, by default, support the “discovery” of h264.  I was surprised by this as I had already installed the CCCP (Combined Community Codec Pack) and the files could play back via WMP11 on the PC.  Luckily there is a small registry hack (compatible with both Vista 32 and 64) which enables the discovery of h264 content.  Once the patch is installed and your computer is restarted, the PS3 will be able to see the mp4 files – excellent!  I dived onto the couch and hit the Play button the Remote – only to be bitterly disappointed.

Although the video played back (and looked fantastic compared to the Xvids before it) – the dropout made it un-watchable.  The video was stuttering all over the place!  A quick check via the ‘Select’ button showed that the video was trying to steam 5mbps over the wireless – seeing as 802.11g only offers an ideal bandwidth of 54mpbs (which is pretty much theoretical) I knew that asking it for 5mbps (plus the overhead from the DLNA services) was pushing it too far!  As my house doesn’t have CAT-5 running through the walls, my own hope was to purchase a set of HomePlug network devices to run the network data over my home’s powerlines.  I’ve always been a bit dubious of HomePlug’s and had heard negative things about them but seeing as I didn’t have many optins left, I opted for a pair of Linksys PLE200′s from Scan.co.uk (I was quite suprised that they were only £49 for a pack of 2, I expected to pay twice that much).  These devices touted that they were capable of stream HD Content over a network and could manage 200mbps (Which is a lovely bit of marketing seeing as they only have 100mbps interfaces – the 200mbps mentioned on the box is referring to the devices running in full duplex mode – and seeing as I only have a 100mbps router, it all becomes a bit of a moot point).

The Homeplugs arrived the next day and I set about installing them.  The box told me to install the management software before plugging them in.  I dutifly inserted the CD and ran the software only to be greeted by an error dialogue reading: “Failed to initialize Networks Interface – exiting”.  I guess the software that ships with the devices isn’t compatible with Vista x64 then.  Throwing caution to the window I proceeded to plug the devices in, wiring one into my router and the other into the back of the PS3.  I then headed to the Linksys website and began downloading the latest drivers for the PLE200.  The download was coming in at a miserable 60kbps so I switch my attention back over the PS3 and went to see if the devices would work without the managment software (after all they are network devices – what setup do the really need once they gain a DHCP lease from the router?).  To my suprise, the PS3 managed to gain a lease and sucessfully connect to the Internet – score one for Homeplugs!  Seeing as I live in a bungalow I don’t really see the point of enabling encryption on the devices (which I’m pretty sure would just limit the amout of avaliable bandwidth anyway due to the overhead) so I am yet to install the latest managment software (and to be honest, I don’t really want to install another bit of crapware on this box anyway!).

With the Homeplugs setup and my PS3 back on the network, I tried to watch the mp4 file again – to my delight it started playing back smoothly; a smile almost crept onto my face!

So, now that I had x264′s playing back, my last hurdle was to get true 720p HD content in the MKV container to play back on the PS3.  I knew already that the PS3 (nor WMP11) supports the MKV container (which is a great shame, as it’s the best replacement for the aging AVI contaner out there), so I jumped back onto Google and came across a guide which detailed How to Play MKV Files on the Playstation 3.  As MKV is just a container, your first step is to swap out the contained Video and Audio streams and place them into a container the PS3 can accept (VOB).  The piece of software which performs this magic mxing is called (immaginativley) MKV2VOB and does exactly what is says on the tin with no loss of quality.

MKV2VOB takes about a minute to swap the containers of a 120 minute MKV movie, once the conversion was complete I was able to see the resuling .mpg file on the PS3 but it complained about “Corrupt Data”, a commenter on an earlier Blog Post pointed out that he had to change the file extension to be “.MP4″ before the file would playback on the PS3 and sure enough this worked and I was able to watch the re-muxed MKV on the PS3 in glorious HD with an average datarate of almost 10mbps! – lovley stuff.  To make future transcoding easier, MKV2VOB has a setting in it’s Configuration tab to automatically rename the output file to .MP4 and then delete the source MKV – combined with a bit of scripting, it will probably be farily easy to get this conversion to happen automatically.

The only thing I need to figure out now is:

  • How to get thumbnails to appear on the PS3 when browsing the Video’s served via WMP11
  • How to change to way the folders are presented on the PS3 as all my media is currently buried under a massive folder hierarchy.  (Videos -> Folders -> Videos -> TV Shows!)
Posted in Personal | Tagged , , , , , , , | 3 Comments

Dead Space Review.

I’ve been doing a bit of reviewing over at dooyoo.co.uk in an attempt to raise a bit of pocket money in my down time.  I thought I’d cross post my thoughts on Dead Space.

It’s not often that a game will scare you senseless, but Dead Space is one of those rare gems which, if you allow it, will leave you with nightmarish visions, twitching in the corner!

Dead Space takes a slightly different spin on the usual First Person Shooter genre by positioning the camera just behind your avatar’s shoulder, in a similar vein to Gears of War. At first I didn’t think I’d like this angle, but after a few hours of gameplay I hardly even noticed the aspect shift; infact I’ll go as far as to say that I think it adds to the game, showing your character (Isaac) getting slammed to the floor, or dragged along by his leg by a monstrous tentacle, which brings me nicely onto the best aspect of dead space – the enemy!

The game’s opening cinematic gives nothing away – you and a small crew aboard a service ship are heading towards the USG Ishimura to repair a damaged comms array; from the moment you step foot off the shuttle you can fear the tension close in around you knowing full well that something is about to go hideously wrong. This is one game that really needs to be played in the dark with a good pair of headphones in order for you to get the most out of it; The audio is superb with a great score which puts the predictable dross of the Lost Soundtrack to shame. This is further heightened by whispering voices, malfunctioning equipment and eerie clanking noises emanating from the vents and ducts. The game has some excellent environment effects, the first time you experience a hull breach and are introduced to the vacuum of space is pretty intense.

The game continues the immersion by removing all HUD elements from the screen; this is replaced with a health meter running down your character’s spine and ammo readouts on the weapons themselves. The developers came up with a clever system for accessing the inventory; pressing the Tab key will project a hologram infront of your avatar which moves around in the game world. Activating the inventory does pause the game, so there’s no respite in the midst of an intense battle, again adding to the sense of urgency rather than taking away from it. New weapons, ammo and items can be purchased from the shops which are scattered around the game – I find it hard to believe that these would still be functional whilst the entire crew lies in pieces, but I guess the story writers ran out of good ideas!

Some reviewers have critiqued Dead Space for its unimaginative and repetitive scenery, however I think this is slightly unjust given the setting of the game (Spaceships, for all their intergalactic glory, are pretty grey affairs on the inside). The Game progresses you through multiple parts of the Ship with boss battles taking place around the usual landmarks (The sequence in the morgue is particularly memorable). However I will agree with others that the range of weapons is lacking – you’ll often find yourself falling back one one or two staple weapons, especially when the ammo starts getting sparse later in the game, but I guess we should be grateful that the developers didn’t fall back on the usual Doom formula of shotgun, rifle, rocket launcher.

Dead Space is another one of those game which feels like a console port – for example, you can only save you game at certain Save Points (at which you are also limited to four saves!) and there is no Quick Save (but again, this adds to the tension and makes you value your health!). The transition from gamepad to keyboard feels slightly strange and no matter how I remapped the keys I never felt I had that “Half-life level” of keybinding. There are also certain gameplay elements that don’t translate as well; one mission has you shooting at incoming asteroids, something which is quite tricky on a PS3 (or so I’m told), but it was just 5 minutes of tedium for me as I popped off rock after rock with the pinpoint precision a mouse offers you)

The graphics are one place where the PC version shines above its console brethren; I was able to run the game with everything on High setting at 1680×1050 resolution on my 768mb Nvidia 9800GTS (far in excess of the 720p limit on the consoles). One small problem that I came across was the incredible mouse lag when I first started it up; this was quickly solved by turning off the VSync setting in the Graphics menu (and no, this did not produce any visual tearing for me). It should also be noted that you can further improve the graphics by enabling Anti-Aliasing in your Graphics Card settings as there are no AA Options in the Game.

To conclude, I really can’t fault Dead Space, it’s been a long time since I’ve played a game compelling enough to warrant 8 hour stints that last long into the night. Of course, this game is not without its faults, but it would definitely be in my Top 5 picks of 2008. This game would make an excellent present for any avid gamer, but I wouldn’t reccomend letting younger children play it due to the extreme graphic nature and the incredibly dark and twisted setting (I’ve woken up from a couple of warped dreams since playing this game!)

Posted in Game Reviews, Personal | 3 Comments

My Development Environment.

I spend most of my development time sat in Eclipse, I find it funny (or maybe slightly alarming) that only four moths ago I had never ventured near an Integrated Development Environment and spent a lot of time toiling away with a Crimson Editor.  All I can say is that if you haven’t tried getting to grips with Eclipse, then now is the time.

As my work is split between programming in PHP and ActionScript, I use Flex Builder as the base for my Eclipse Setup (Flex Builder 3 is built ontop of the Eclipse 3.3 platform).  Flex Builder comes with an ActionScript parser and debugger.  The parser is not as good as FDT (which I use at work), but is a damn sight cheaper which is always welcome.   Eclipse is incredibly modular and allows you to enhance it’s basic functionality buy installing components which provide additional perspective and functionality.   I make use of the following:

  • PDT 1.x – PHP Development Tool, includes code completion and syntax highlighting.
  • Subclipse 1.4 – SVN Integration for eclipse, essentail for checking in my own code and 3rd party code which I make sure of (Such as the CakePHP Core).  Again, if you’re not using SVN then you really should!

I keep my PHP and ActionScript development seperate by using two Workspaces and swtiching between the two (I do a similar thing at work by having two workspaces for our ActionScript 2 and ActionScript 3 projects at Mindcandy).  To avoid any potential UAC problems in Vista, I make sure that my Workspace is located in my User folder – this also helps with backups keeping everything in one place.

To back this up, I run a straight forward Apache 2.2, MySQL 5 and PHP 5.2 stack ontop of Windows Vista x64 (Even with UAC turned on!).  I had no problems installing the stack, I just made sure that everything was installed inside my User folder.  (ie: C:UsersJonnyWebrootApache2-2, etc).  I configure individual vhosts for the projects I work on and point the webroot at my Eclipse Workspace (ie: C:UsersJonnyProjectsPHPProject_Name). This allows me to simulate a webdeploy environment which makes deploying sites to a web server easier.  To complete my local dev setup I setup fake sendmail which allows the mail() funcitons inside PHP 5 to be relayed to a remote mail server (very handy! — again, I was suprised that this worked without a hitch on Vista x64).

Posted in ActionScript 3, CakePHP | Tagged , , , , , | 1 Comment