<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Salt Games</title>
	<atom:link href="http://www.saltgames.com/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.saltgames.com</link>
	<description>Games and Toys in Flash</description>
	<lastBuildDate>Thu, 08 Jul 2010 17:27:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Introduction to Pixel Bender in Flash</title>
		<link>http://www.saltgames.com/?p=207</link>
		<comments>http://www.saltgames.com/?p=207#comments</comments>
		<pubDate>Sun, 28 Feb 2010 20:05:58 +0000</pubDate>
		<dc:creator>Salt</dc:creator>
				<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.saltgames.com/?p=207</guid>
		<description><![CDATA[I present my methods for getting custom shaders made in Pixel Bender working in Flash projects. This is quite a lengthy tutorial.  It includes a brief introduction to pixel shaders in general; a tour of the most important aspects of Pixel Bender for use creating shaders specifically for Flash; directions for integrating the custom shader [...]]]></description>
			<content:encoded><![CDATA[<p>I present my methods for getting custom shaders made in Pixel Bender working in Flash projects.</p>
<p><span id="more-207"></span><strong> </strong></p>
<p>This is quite a lengthy tutorial.  It includes a brief introduction to pixel shaders in general; a tour of the most important aspects of Pixel Bender for use creating shaders specifically for Flash; directions for integrating the custom shader you create into a Flash project; and full source for two simple examples.</p>
<p><strong>Some Introductions</strong></p>
<p>Shaders, specifically pixel shaders.  These are programs that operate on an image on a per-pixel basis.  Per-pixel means the program operates on each pixel individually, without reference to operations carried out on other pixels.  Because shaders operate in this per-pixel manner they very well suited to parallel processing: Having many instances of the shader operating at the same time, each on their own pixel.  Operating per-pixel means that there are certain tasks that are well suited to being performed by a shader as well as many tasks that are completely unsuitable.</p>
<p>Filters, Effects, Blendmodes, Kernels.  There's a lot of terminology floating around depending on where you read about stuff.  I'm going to call everything a Shader, because that's the name of the class I end up using in Flash for everything (not the best method for naming things, but still.) To give a very rough idea to help you follow other documents: Filters and Effects are applied to just one image; Blendmodes are applied to two (or more, in theory?) images; a Kernel is the thing you make when you type code into Pixel Bender.</p>
<p>Pixel Bender.  The Pixel Bender Toolkit, to give it its full name, is a neat program made by Adobe to produce custom filters and effects for use in a variety of their applications.  A large amount of its functionality is unavailable for use in Flash.  Beware when reading general information about Pixel Bender; a lot of it is not going to apply to us.  Pixel Bender is available for free <a href="http://www.adobe.com/devnet/pixelbender/">from Adobe</a> (look to the right of the page.)  Pixel Bender was known as Hydra when it was in development, so you may see that name crop up around the place too.</p>
<p><strong>Here be monsters</strong></p>
<p>Using Pixel Bender to make shaders for Flash is - to put it politely - prone to inconsistencies.  The Pixel Bender Toolkit lets you run your shader within it to test it.  What you see in the preview will quite often not match what comes out in Flash.  I'm attempting to build up a <a href="http://www.saltgames.com/?p=216">record of ways</a> in which the two do not match but it's far from complete.  Just be aware that you should test primarily in Flash and not rely on the inbuilt preview.</p>
<p><strong>What's the point</strong></p>
<p>So Pixel Bender can make buggy programs that are limited to operating on images in a per-pixel basis.  Why am I bothering learning this?</p>
<p>Because it's <em>fast!</em></p>
<p><em><span style="font-style: normal;">You might like to look at a <a href="http://www.saltgames.com/?p=191">normal mapping example</a> I put together recently.</span></em></p>
<p>Flash programs are pretty slow generally, and are limited to executing in a single thread.  Consider if you want to tint an image red in Flash.  If you're hopelessly naïve you might write something like:</p>
<pre>for (var x:int = 0; x &lt; image.width; x++)
{
   for (var y:int = 0; y &lt; image.height; y++)
   {
      var colour:uint = image.getPixel(x, y);
      colour = (colour | 0xff0000); //set the red channel to 255
      image.setPixel(x, y, colour);
   }
}</pre>
<p>This will be slow.  It'll be slow because of the <strong>BitmapData.getPixel</strong> and <strong>BitmapData.setPixel</strong> operations being called huge numbers of times, but on a more general level it's slow because you're visiting each pixel in turn when you could be performing that operation on all the pixels at once.  This is effectively what a custom shader from Pixel Bender does.</p>
<p>Your shader will not <em>actually</em> operate on all the pixels at once, as it's limited by the number of threads it can execute on the machine its on.  But thinking of it as operating on every pixel at once is a useful mental model.</p>
<p>Pixel Bender was designed to run on GPUs, which are especially well suited to performing many parallel tasks.  When running in Flash it is actually limited to using the CPU.  This means it's not nearly as fast as it <em>could</em> be, but it still has the potential to be many times faster than plain old actionscript.</p>
<p><strong>To the Pixel Bender!</strong></p>
<p>Let's get right in and actually make a shader and get it working in Flash.</p>
<p><a href="http://www.adobe.com/devnet/pixelbender/">Download</a> and install Pixel Bender.</p>
<p>Set a couple of options within Pixel Bender (<strong>Edit </strong>menu, <strong>Preferences...</strong>) to tell it you'll be exporting to Flash:</p>
<p><a href="http://www.saltgames.com/wp-content/uploads/2010/02/preferences.jpg"><img class="aligncenter size-full wp-image-218" title="preferences" src="http://www.saltgames.com/wp-content/uploads/2010/02/preferences.jpg" alt="" width="444" height="314" /></a></p>
<p>Select <strong>New Kernel</strong> from the <strong>File </strong>menu.</p>
<p>You'll now have the code for a shader that does nothing.  Excellent!</p>
<pre>&lt;languageVersion : 1.0;&gt;
kernel NewFilter
&lt;  namespace : "Your Namespace";
   vendor : "Your Vendor";
   version : 1;
   description : "your description";
&gt;
{
   input image4 src;
   output pixel4 dst;
   void
   evaluatePixel()
   {
      dst = sampleNearest(src,outCoord());
   }
}</pre>
<p>Oh no, this isn't Actionscript!  Time to learn a new language.  Good news is it's easy, and you can ignore most of it.</p>
<p>So what actually matters here?</p>
<pre>input image4 src;</pre>
<p>This declares a variable of the type <strong>image4</strong> named <strong>src</strong>, and says that this variable will hold the input that our shader is given.  Later we'll see how a shader can have multiple input images.</p>
<p>The type <strong>image4</strong> just means that it's an image with 4 colour channels: Red, green, blue and alpha.  There is also <strong>image3</strong> if you want to ignore the alpha channel.</p>
<pre>output pixel4 dst;</pre>
<p>This declares a variable of the type <strong>pixel4</strong> named <strong>dst</strong>, and says that whatever value we put in this variable will be the output of the shader.  <strong>pixel4</strong> is a single pixel with 4 colour channels.</p>
<p>But wait!  We're taking a whole image as input, and only giving a single pixel as output?  Shouldn't this be producing a whole image?</p>
<p>I was just getting to that.</p>
<p>The <strong>evaulatePixel()</strong> function is the heart of our shader.  It is executed once for <em>each pixel</em> of the source image.  It produces just a single pixel - our output variable named <strong>dst</strong> - which is then built up to form the finished image.</p>
<pre>void
evaluatePixel()
{
   dst = sampleNearest(src,outCoord());
}</pre>
<p>Here's the <strong>evaluatePixel </strong>function in full.  The only bit you ever need change is between the curly braces.  In this case it takes the result of the built-in function <strong>sampleNearest</strong> and assigns that to dst.  Note that unlike actionscript functions where you use 'return' to have a function produce a value, evaluatePixel just sets the value of the variable that we've previously defined as the shader's output.</p>
<p>What does <strong>sampleNearest</strong> do?  Press F1 in Pixel Bender to get the documentation.  The majority of the documentation doesn't apply to us (most sections end with "Flash player note: X is not supported in Flash Player.")  But it has lists of built-in functions and data types, most of which are supported.  <strong>sampleNearest </strong>gives us the value of a single pixel from the image passed as the first parameter, which in this case is <strong>src</strong>.  Which pixel to return is determined by the second parameter, which in this case is the result of another built-in function: <strong>outCoord<span style="font-weight: normal;">. This function returns a </span>float2<span style="font-weight: normal;"> value giving the position of the pixel that in this instance </span>evaluatePixel</strong> was called on.</p>
<p><strong>Vector data types</strong></p>
<p>Unlike actionscript, Pixel Bender uses something called vector data types.  These store several values within one variable.  For instance a position in two-dimensional space can be specified by a <strong>float2</strong> value, which is just two floating point values (basically the same as <strong>number</strong> in actionscript) joined together.  You can access the individual values, or operate on them as a whole.  Let's take an example:</p>
<pre>void
evaluatePixel()
{
   pixel4 myPixelVariable;
   myPixelVariable = sampleNearest(src, outCoord());
   dst = myPixelVariable * 2.0;
}</pre>
<p>First new thing:</p>
<pre>pixel4 myPixelVariable;</pre>
<p>Simply declares a variable named <strong>myPixelVariable</strong> which is of type <strong>pixel4</strong>.</p>
<pre>myPixelVariable = sampleNearest(src, outCoord());</pre>
<p>As you'd expect we can assign a value to it.</p>
<pre>dst = myPixelVariable * 2.0;</pre>
<p>Then we can multiply the whole thing by 2, and assign that to our output variable.</p>
<p>This is exactly the same as performing:</p>
<pre>dst.r = myPixelVariable.r * 2.0;
dst.g = myPixelVariable.g * 2.0;
dst.b = myPixelVariable.b * 2.0;
dst.a = myPixelVariable.a * 2.0;</pre>
<p>Isn't that neat.</p>
<p><strong>myPixelVariable.r</strong> is accessing one of the four elements that make up the variable.  The elements can also be accessed by:</p>
<p>myPixelVariable[0], myPixelVariable[1], myPixelVariable[2], myPixelVariable[3]</p>
<p>myPixelVariable.x, myPixelVariable.y, myPixelVariable.z, myPixelVariable.w</p>
<p>myPixelVariable.s, myPixelVariable.t, myPixelVariable.u, myPixelVariable.v</p>
<p>The suffixes <strong>[0]</strong>, <strong>.r</strong>, <strong>.x</strong> and <strong>.s</strong> are all equivalent.</p>
<p>You can access several elements of a vector-type variable at once.</p>
<pre>myPixelVariable.rg *= 2.0;</pre>
<p>Will multiply just the red and green channels by two.</p>
<p>You can also assign values between elements of a vector-type:</p>
<pre>myPixelVariable.rgb = myPixelVariable.brg;</pre>
<p>This assigns the blue value of the pixel to be the red value, the red to the green and the green to the blue.</p>
<p>You can specify each element of a vector-type like so:</p>
<pre>myPixelVariable.rgb = float3(0.5, 0.2, 0.8);</pre>
<p><strong>Fussy about types</strong></p>
<p>Notice that in the examples above we multiply by <strong>2.0</strong> rather than just <strong>2</strong>.  This is because unlike actionscript, Pixel Bender doesn't do implicit conversion.  What that means is that it will interpret <strong>2</strong> as an integer, and not know how to multiply that by the <strong>float</strong> values of a <strong>pixel4 </strong>variable.  Writing the value as <strong>2.0</strong> makes it clear that you want it treated as a <strong>float</strong>. You could also use <strong>float(2)</strong> to explicitly convert the <strong>integer </strong>into a <strong>float</strong>.</p>
<p>Slightly weirdly there seems to be little difference between <strong>pixel4 </strong>and <strong>float4</strong>.  I think there's a difference in how accurately the values are stored, but they are largely interchangeable.</p>
<p><strong>A working shader</strong></p>
<p>Let's pull that together into a simple working shader so we can move on to implementing it in Flash:</p>
<pre>kernel NewFilter
&lt;    namespace : "Your Namespace";
     vendor : "Your Vendor";
     version : 1;
     description : "your description";
&gt;
{
    input image4 src;
    output pixel4 dst;

    void
    evaluatePixel()
    {
        dst = sampleNearest(src,outCoord());
        dst.r *= 2.0;
    }
}</pre>
<p>This will just take each pixel from an image and double the red channel.</p>
<p>We can give this a quick test within Pixel Bender.  Just <strong>Load Image 1...</strong> from the <strong>File</strong> menu and select any old photo you have laying around. Then hit the <strong>Run</strong> button (or <strong>F5</strong>) and the photo will be displayed with a red tint.</p>
<p>Now choose <strong>Export Filter for Flash Player...</strong> from the <strong>File</strong> menu.  This will create a <strong>.pbj</strong> file containing Pixel Bender byte code which Flash will be able to understand.  Whenever you change a shader you're working on, remember you'll need to re-export it to have those changes show up in Flash.</p>
<p><strong>And in to Flash</strong></p>
<p>Once you know how, getting the shader in to your Flash program is actually quite simple.  The basic technique is very similar to embedding an image, font or sound:</p>
<pre>[Embed(source = 'TestShader.pbj', mimeType = 'application/octet-stream')]
private var TestShader:Class;</pre>
<p>And that's it embedded!  To create an instance of the shader:</p>
<pre>var myShader:Shader = new Shader(new TestShader() as ByteArray);</pre>
<p>The shader we've created requires an input image, so we need to point <strong>myShader</strong> at an image to use as its input.</p>
<pre>myShader.data.src.input = myBitmapData;</pre>
<p>This assumes we already have an image loaded and named <strong>myBitmapData</strong>.  Note that the <strong>src</strong> corresponds to the name we gave the input variable in Pixel Bender.</p>
<p>To actually run the shader, we make use of a <strong>ShaderJob</strong>.</p>
<pre>myJob:ShaderJob = new ShaderJob(myShader, outputBitmapData);
myJob.start(true);</pre>
<p>Again this assumes we already have a <strong>bitmapData</strong> object named <strong>outputBitmapData</strong> which is ready to receive the finished image (it should be created as the same size as the input image.)  The <strong>true</strong> value passed when calling <strong>start </strong>on <strong>myJob</strong> tells Flash you want to wait until the job is complete before continuing.  It's possible to pass <strong>false</strong> instead and have the shader execute asynchronously, but that brings up a whole lot of other issues and <a href="http://www.saltgames.com/?p=200">a pretty major bug</a>.</p>
<p>Putting this all together into a program that'll actually work:</p>
<pre>package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Shader;
	import flash.display.ShaderJob;
	import flash.display.Sprite;
	import flash.utils.ByteArray;

	public class PrettyShader extends Sprite
	{
		//embed the shader
		[Embed(source = 'TestShader.pbj', mimeType = 'application/octet-stream')]
		private var TestShader:Class;

		//embed an image to test it on
		[Embed(source = 'SomeImage.jpg')]
		private var SomeImage:Class;

		public function PrettyShader()
		{
			//set up the input and output BitmapDatas
			var myBitmapData:BitmapData = (new SomeImage() as Bitmap).bitmapData;
			var outputBitmapData:BitmapData = new BitmapData(myBitmapData.width, myBitmapData.height);

			//set up the Shader
			var myShader:Shader = new Shader(new TestShader() as ByteArray);
			myShader.data.src.input = myBitmapData;

			//create the ShaderJob
			var myJob:ShaderJob = new ShaderJob(myShader, outputBitmapData);

			//and run it!
			myJob.start(true);

			//display the input and output.
			var before:Bitmap = new Bitmap(myBitmapData);
			addChild(before);
			var after:Bitmap = new Bitmap(outputBitmapData);
			after.x = before.width;
			addChild(after);
		}
	}
}</pre>
<p>Remember to set your compiler to target Flash Player 10, and you should end up with something rather like this:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="800" height="300" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="wmode" value="direct" /><param name="src" value="http://www.saltgames.com/wp-content/uploads/2010/02/PrettyShader.swf" /><embed type="application/x-shockwave-flash" width="800" height="300" src="http://www.saltgames.com/wp-content/uploads/2010/02/PrettyShader.swf" wmode="direct"></embed></object></p>
<p>We're actually almost done now!  There are two more things to cover:  multiple image inputs, and parameters.</p>
<p><strong>Multiple images as inputs</strong></p>
<p>The example above just takes one image and fiddles with the colour a little.  You can do much more powerful things if you work with more than one image.</p>
<p>In Pixel Bender all we need to do is add an extra <strong>input</strong> statement for each image we want to sample from.  For example:</p>
<pre>kernel NewFilter
&lt;    namespace : "Your Namespace";
     vendor : "Your Vendor";
     version : 1;
     description : "your description";
&gt;
{
    input image4 srcOne;
    input image4 srcTwo;
    output pixel4 dst;

    void
    evaluatePixel()
    {
        float2 positionHere = outCoord();
        pixel4 fromOne = sampleNearest(srcOne, positionHere);
        pixel4 fromTwo = sampleNearest(srcTwo, positionHere);
        float crossfade = positionHere.x / 400.0;
        dst = fromOne * crossfade + fromTwo * (1.0 - crossfade);
    }
}</pre>
<p>This will sample from both images, and mix them together depending on the horizontal position of the pixel in question.  You might notice that I create a <strong>float2 </strong>variable named <strong>positionHere</strong> to store the result of <strong>outCoord()</strong>, this is simply to save calling the function multiple times when I know it'll give the same result.  Unnecessary premature optimisation or just being tidy?  You decide!</p>
<p>The changes in Flash are just as simple.  Simply assign another <strong>BitmapData</strong> as the shader's second input:</p>
<pre>myShader.data.srcOne.input = myBitmapData;
myShader.data.srcTwo.input = myOtherBitmapData;</pre>
<p><strong>Parameters</strong><br />
Parameters are simply variables that are used within the shader and can be set from within Flash.  Like input images and the <strong><span style="font-weight: normal;">output</span> </strong>pixel, <strong><span style="font-weight: normal;">parameters</span> </strong>are defined outside of the <strong>evaluatePixel</strong> function.  As well as specifying the data type that the parameter should be you give minimum, maximum and default values.</p>
<p>Here is the above shader amended with two parameters:</p>
<pre>kernel NewFilter
&lt;    namespace : "Your Namespace";
     vendor : "Your Vendor";
     version : 1;
     description : "your description";
&gt;
{
    input image4 srcOne;
    input image4 srcTwo;
    output pixel4 dst;

    parameter float middleOfFade
    &lt;
         minValue: -1.0;
         maxValue: 1.0;
         defaultValue: 0.0;
    &gt;;

    parameter int widthOfImage
    &lt;
         minValue: 0;
         maxValue: 5000;
         defaultValue: 400;
    &gt;;

    void
    evaluatePixel()
    {
        float2 positionHere = outCoord();
        pixel4 fromOne = sampleNearest(srcOne, positionHere);
        pixel4 fromTwo = sampleNearest(srcTwo, positionHere);
        float crossfade = middleOfFade + (positionHere.x / float(widthOfImage));
        if (crossfade &gt; 1.0) crossfade = 1.0;
        if (crossfade &lt; 0.0) crossfade = 0.0;
        dst = fromOne * crossfade + fromTwo * (1.0 - crossfade);
    }
}</pre>
<p>In this case we use two parameters, for two quite different purposes.<strong> </strong>You might have noticed that the previous versions relied on a constant value of 400.0 in the calculation of <strong>crossfade.</strong> This was the width of the image in use, but of course our shader should be ready to accept other sized images too so the parameter <strong>widthOfImage</strong> was added.  Secondly the parameter <strong>middleOfFade</strong> is added to allow interactive changes to how the two source images are mixed.</p>
<p>As a side note, Pixel Bender actually includes some built-in functions for determining the size of input images, but they are not available when exporting for the Flash player.</p>
<p>If you test this shader in Pixel Bender it will display some sliders that let you alter your parameters on the fly and see what effect they have.</p>
<p>Passing values to your shader from Flash is again fairly simple, although slightly obscure.</p>
<pre>myShader.data.middleOfFade.value = [0.2];</pre>
<p>Notice that you use <strong>.value</strong> when setting a parameter, but <strong>.input</strong> when setting an input image.  You also have to put your value inside an array first.  It makes more sense if you need to pass values into a <strong>float3</strong> variable:</p>
<pre>myShader.data.someFloat3Variable.value = [0.1, 0.6, 0.3];</pre>
<p><strong>All together now</strong><br />
A working Flash program that uses a shader with two image inputs and parameters.</p>
<pre>package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Shader;
	import flash.display.ShaderJob;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.utils.ByteArray;

	public class PrettyShader extends Sprite
	{
		//embed the shader
		[Embed(source = 'TestShader.pbj', mimeType = 'application/octet-stream')]
		private var TestShader:Class;

		//embed the images to test it with
		[Embed(source = 'SomeImage.jpg')]
		private var SomeImage:Class;
		[Embed(source = 'SecondImage.jpg')]
		private var OtherImage:Class;

		private var myShader:Shader;
		private var outputImage:BitmapData;

		private var count:Number = 0;
		private const twoPi:Number = Math.PI * 2;

		public function PrettyShader()
		{
			//set up the input and output BitmapDatas
			var firstImage:BitmapData = (new SomeImage() as Bitmap).bitmapData;
			var secondImage:BitmapData = (new OtherImage() as Bitmap).bitmapData;
			outputImage = new BitmapData(firstImage.width, firstImage.height);

			//set up the Shader
			myShader = new Shader(new TestShader() as ByteArray);
			myShader.data.srcOne.input = firstImage;
			myShader.data.srcTwo.input = secondImage;

			//set parameters
			myShader.data.widthOfImage.value = [firstImage.width];
			myShader.data.middleOfFade.value = [0.0];

			//display the output.
			addChild(new Bitmap(outputImage));

                        //update every frame
			addEventListener(Event.ENTER_FRAME, perFrame);
		}

		private function perFrame(e:Event = null):void
		{
			//update realtime parameter
			count += 0.05;
			if (count &gt; twoPi) count -= twoPi;
			myShader.data.middleOfFade.value = [Math.sin(count)];

			//create the ShaderJob
			var myJob:ShaderJob = new ShaderJob(myShader, outputImage);

			//and run it!
			myJob.start(true);
		}
	}
}</pre>
<p>Here it is running:<br />
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="400" height="300" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="wmode" value="direct" /><param name="src" value="http://www.saltgames.com/wp-content/uploads/2010/02/TwoImagesShader.swf" /><embed type="application/x-shockwave-flash" width="400" height="300" src="http://www.saltgames.com/wp-content/uploads/2010/02/TwoImagesShader.swf" wmode="direct"></embed></object></p>
<p>I think that is about all for now.  There is plenty more to learn about both Pixel Bender and using shaders in Flash, but this should give you everything you need to get some cool stuff working.</p>
<p>Of course making those awesome shaders is another topic altogether.</p>
<p>As a final note, keep in mind that it is possible to use custom shaders as <strong>BlendModes</strong> or <strong>Filters</strong> directly in Flash.  I have found that doing so ended up being more complex (or at least confusing), didn't allow for the creation of anything that couldn't be achieved through the use of <strong>Shader</strong> and <strong>ShaderJob</strong>, and may even run slightly slower.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.saltgames.com/?feed=rss2&amp;p=207</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Pixel Bender&#8217;s Eccentricities</title>
		<link>http://www.saltgames.com/?p=216</link>
		<comments>http://www.saltgames.com/?p=216#comments</comments>
		<pubDate>Sun, 28 Feb 2010 19:50:11 +0000</pubDate>
		<dc:creator>Salt</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://www.saltgames.com/?p=216</guid>
		<description><![CDATA[Pixel Bender doesn't always play quite right with Flash.  I'm attempting to build up a list of just how it behaves oddly. This is very much a work in progress.  I'm mainly posting it now so I can link to it in other posts.  It is also worth pointing out that these are problems that [...]]]></description>
			<content:encoded><![CDATA[<p>Pixel Bender doesn't always play quite right with Flash.  I'm attempting to build up a list of just how it behaves oddly.</p>
<p><span id="more-216"></span></p>
<p>This is very much a work in progress.  I'm mainly posting it now so I can link to it in other posts.  It is also worth pointing out that these are problems that I have encountered on my particular set up, so it's not at all clear where in the chain these occur. Please do suggest any you find in the comments.  If you can manage to get someone from Adobe to pay attention, that'd be good too!</p>
<p><strong>Comparing vector-type variables</strong></p>
<p>Say you've got two <strong>float3 </strong>variables and want to see if they're identical.  The following should work:</p>
<pre>(one == two)</pre>
<p>This does work when testing in Pixel Bender, but seems to always return false when compiled for Flash.  To get around this, compare the elements of the vector-type variables separately:</p>
<pre>(one.r == two.r &amp;&amp; one.g == two.g &amp;&amp; one.b == two.b)</pre>
<p><strong>Clamp</strong></p>
<p>There's a handy built-in function called <strong>clamp</strong>.  This takes three values: x, min, max.  If x is between min and max it just returns x; if x is smaller than min then it returns min; if x is larger than max then it returns max.  This works fine in Pixel Bender, but can fail (only fails in the case of x &gt; max?) when compiled for Flash.  Get around it by using a pair of simple <strong>if</strong> statements.</p>
<p><strong>Cancelling a save on exit</strong></p>
<p>This isn't really about Pixel Bender for Flash, but a general annoyance.  Upon closing Pixel Bender when it has an unsaved file open, it asks if you want to save it giving options <strong>Save</strong>, <strong>Don't Save</strong>, <strong>Cancel</strong>.  Clicking <strong>cancel </strong>will cause Pixel Bender to close and abandon the file.  The expected behaviour is for <strong>cancel</strong> to cancel the whole quit operation.</p>
<p><strong>Sampling outside of an image</strong></p>
<p>Behaviour varies between Pixel Bender and Flash when a shader attempts to sample a pixel from outside the bounds of an image.  In Pixel Bender, a black pixel is returned.  In Flash a pixel identical to the closest pixel that is within the image bounds is returned.</p>
<p><strong>Normalise function creates artefacts</strong></p>
<p>I don't have this properly pinned down, but I think it's related to the first few pixels of each shader instance being processed in interpreted mode (rather than Just in Time) which causes it to use slightly different math functions.  Artefacts have tended to be black rows of 3 pixels length on the right-hand side of the image.  Such artefacts only appear in Flash.</p>
<p>Change from:</p>
<pre>myVector = normalize(myVector);</pre>
<p>To:</p>
<pre>myVector /= length(myVector);</pre>
<p>Just beware division by zero.</p>
<p><strong>Flash Player crashes with shaders on large images</strong></p>
<p>On certain browser / OS / hardware set-ups the Flash Player will crash when attempting to run a Pixel Bender shader on a large image.  I can't recreate the crash on my machine, but it looks like the size limit is between 1024x1024 and 1500x1500 (the former works fine, the latter causes the crash.)  It is still possible to put large images through a shader, you just need to chop them up into bite-sized parts first then stitch them together again after they've been through the shader.  Exactly how you do that is going to depend on what your shader's doing.</p>
<p><strong>Order of declaring parameters</strong></p>
<p>When declaring parameters for a shader, you should list <strong>float</strong> type values before <strong>float2</strong> type values.  Presumably there needs to be similar ordering for other types, but I've not experimented.  The parameters 'just break' in seemingly arbitrary ways if they're listed out of that order.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.saltgames.com/?feed=rss2&amp;p=216</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>On Not Being Colour-blind Blind</title>
		<link>http://www.saltgames.com/?p=203</link>
		<comments>http://www.saltgames.com/?p=203#comments</comments>
		<pubDate>Fri, 12 Feb 2010 22:01:09 +0000</pubDate>
		<dc:creator>Salt</dc:creator>
				<category><![CDATA[Visual Art]]></category>

		<guid isPermaLink="false">http://www.saltgames.com/?p=203</guid>
		<description><![CDATA[A compilation of links for resources to help in designing games that accommodate colour-blind players. Colour-blindness is pretty common.  Designing a game or other visual experience so that it can be enjoyed by someone with the condition is pretty easy.  So let's do it! An article on Negative Gamer about Bioshock 2 failing to do it. [...]]]></description>
			<content:encoded><![CDATA[<p>A compilation of links for resources to help in designing games that accommodate colour-blind players.</p>
<p><span id="more-203"></span></p>
<p>Colour-blindness is pretty common.  Designing a game or other visual experience so that it can be enjoyed by someone with the condition is pretty easy.  So let's do it!</p>
<p><a href="http://negativegamer.com/2010/02/11/what-bioshock-2s-hacking-looks-like-if-youre-colour-blind/">An article on Negative Gamer</a> about Bioshock 2 failing to do it.</p>
<p><a href="http://wearecolorblind.com/articles/quick-tips/">Concise advice from wearecolorblind.com</a></p>
<p><a href="http://www.paciellogroup.com/resources/contrast-analyser.html">Contrast Analyser</a> - A very neat program that can approximate what someone with particular types of colour-blindness see when they look at a given image.  Use the "select window" option in the Image menu and just point it at whatever you're working on.</p>
<p><a href="http://www.vischeck.com/daltonize/">An interesting colour adjustment algorithm</a> that claims to make coloured areas of images easier to differentiate by those with colour-blindness.  If it does work it looks like the type of thing that could be rather easily made into a shader.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.saltgames.com/?feed=rss2&amp;p=203</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Asynchronous ShaderJobs are Murderers</title>
		<link>http://www.saltgames.com/?p=200</link>
		<comments>http://www.saltgames.com/?p=200#comments</comments>
		<pubDate>Thu, 11 Feb 2010 16:00:35 +0000</pubDate>
		<dc:creator>Salt</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://www.saltgames.com/?p=200</guid>
		<description><![CDATA[A warning of a bug in Flash's handling of asynchronous ShaderJobs. Really I should post this after a nice tutorial explaining all about ShaderJob and custom shaders and PixelBender.  But having spent today finding the bug I feel I should post it. A Rapid Introduction A ShaderJob allows you to apply a shader to an [...]]]></description>
			<content:encoded><![CDATA[<p>A warning of a bug in Flash's handling of asynchronous ShaderJobs.</p>
<p><span id="more-200"></span>Really I should post this after a nice tutorial explaining all about ShaderJob and custom shaders and PixelBender.  But having spent today finding the bug I feel I should post it.</p>
<p><strong>A Rapid Introduction</strong></p>
<p>A ShaderJob allows you to apply a shader to an image (or a 'shader' to a set of data, which is mechanically very similar.)  The nice thing about ShaderJobs is they can be run asynchronously.  This means I can start off a ShaderJob to do a fancy lighting effect, and <em>whilst it's doing that</em> my program can carry on executing and working on AI or whatever.  This is thanks to the ShaderJob executing in its own threads separate from the single thread that all the rest of an Actionscript program executes in.  The performance increase from finally being able to use something close to multithreading (what the shader can actually do is cruelly limited) is significant.</p>
<p><strong>And the Problem</strong></p>
<p>Sadly, it all breaks if you try to run multiple ShaderJobs simultaneously.  Ideally, they should be able to just all run at once - that's kind of the point of multiple threads.  Instead<a href="http://www.adobe.com/livedocs/flex/3/langref/flash/display/ShaderJob.html#start()"> the documentation</a> claims that they're kept in a queue and executed one after the other.  Which is a shame, but isn't actually the problem!</p>
<p>Instead of being kept in a queue, additional ShaderJobs just silently vanish.  Start a ShaderJob to blur an image of a circle, then start a ShaderJob to blur an image of a square.  If the ShaderJob for the circle is set to be asynchronous then the ShaderJob for the square will never execute.  No errors are produced; it just silently fails.</p>
<p>The 'neat' thing is that so long as an asynchronous ShaderJob is running in the background, any further ShaderJobs started (whether synchronous or not) will be silently destroyed.  It is possible to avoid this by tracking when an asynchronous ShaderJob completes and not allowing the creation of new ShaderJobs until then.  But if the execution of significant parts of your program has to wait for an asynchronous process to finish then it rather defeats the purpose of it being asynchronous.</p>
<p>I managed to find <a href="http://forums.adobe.com/message/212775">a report of the issue on Adobe's forums</a> from a year ago, although they didn't seem to discover the full range of the  asynchronous ShaderJob's murderous intentions.</p>
<p><strong>In Summary</strong></p>
<p>Only run a ShaderJob asynchronously if you are certain that no other ShaderJobs will be started until it has finished executing.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.saltgames.com/?feed=rss2&amp;p=200</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Testing out Pixel Bender</title>
		<link>http://www.saltgames.com/?p=191</link>
		<comments>http://www.saltgames.com/?p=191#comments</comments>
		<pubDate>Wed, 27 Jan 2010 18:17:27 +0000</pubDate>
		<dc:creator>Salt</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Visual Art]]></category>

		<guid isPermaLink="false">http://www.saltgames.com/?p=191</guid>
		<description><![CDATA[Just a quick demo of realtime normal mapping made possible with Pixel Bender. Use the mouse to position the lightsource.  This demo's normal map was made by following an excellent tutorial on producing normal maps from photographs by Ryan Clark.  The shader is of my own design but is nothing special at all, and I [...]]]></description>
			<content:encoded><![CDATA[<p>Just a quick demo of realtime normal mapping made possible with Pixel Bender.</p>
<p><span id="more-191"></span><br />
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="700" height="700" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="wmode" value="direct" /><param name="src" value="http://www.saltgames.com/wp-content/uploads/2010/03/SimpleNormalMap.swf" /><embed type="application/x-shockwave-flash" width="700" height="700" src="http://www.saltgames.com/wp-content/uploads/2010/03/SimpleNormalMap.swf" wmode="direct"></embed></object></p>
<p>Use the mouse to position the lightsource.  This demo's normal map was made by following an <a href="http://zarria.net/nrmphoto/nrmphoto.html">excellent tutorial on producing normal maps from photographs</a> by Ryan Clark.  The shader is of my own design but is nothing special at all, and I think it's <span style="text-decoration: line-through;">slightly buggy still</span> working correctly.</p>
<p>On my machine this runs at a capped 50fps, whilst trying to do the exact same pixel calculations 'manually' with bitmapData methods manages 2 to 3 fps.  I would post a SWF of the manual version too but it has a decent chance of timing out the flash plugin.</p>
<p>This is all thanks to the magic and wonder of <a href="http://labs.adobe.com/technologies/pixelbender/">Pixel Bender</a>, which lets you write your own shaders/filters/blendmodes for use in a range of Adobe's products - including Flash.  Basically it lets you write an operation that will be executed on every pixel in a given image.  The good bit is that the execution of that operation will take advantage of the parallel nature of the task and split its operation into threads, so showing a huge increase in performance from the single-thread bound Flash Player.  You may also read about how Pixel Bender pushes its calculations on to the GPU, but it actually doesn't do that when executing in Flash.</p>
<p>Sadly a significant amount of its features are disabled for Flash, and there are still plenty of oddities and <a href="http://www.saltgames.com/?p=216">inconsistencies </a>that even in my brief testing I've come up against.  Despite that, I think it's worthy of investigation simply because of the huge increase in performance it can give - it's also free and works fine without needing to use the Flash IDE.</p>
<p>Once I'm a little more certain that I'm doing things right I'll write up an introduction tutorial for using Pixel Bender in Flash projects. <strong>Edit:</strong> <a href="http://www.saltgames.com/?p=207">Here it is</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.saltgames.com/?feed=rss2&amp;p=191</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>A Bitwise Method For Applying Tilemaps</title>
		<link>http://www.saltgames.com/?p=184</link>
		<comments>http://www.saltgames.com/?p=184#comments</comments>
		<pubDate>Tue, 26 Jan 2010 18:57:21 +0000</pubDate>
		<dc:creator>Salt</dc:creator>
				<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.saltgames.com/?p=184</guid>
		<description><![CDATA[A tutorial explaining a technique for automatically selecting the correct tile from a tilemap. I originally wrote this as a reply to a question on TIGSource and I figure it's worthy of expanding and repeating here. The problem: We have generated a neat platformer level, and want to be able to automatically lay neighbour-sensitive tiles [...]]]></description>
			<content:encoded><![CDATA[<p>A tutorial explaining a technique for automatically selecting the correct tile from a tilemap.<br />
<span id="more-184"></span><br />
I originally wrote this as a reply to <a href="http://forums.tigsource.com/index.php?topic=9859.0">a question on TIGSource</a> and I figure it's worthy of expanding and repeating here.</p>
<p>The problem: We have generated a neat platformer level, and want to be able to automatically lay neighbour-sensitive tiles over it so that they fit properly.</p>
<p><strong>Neighbour Sensitive Tiles</strong></p>
<p>Super Mario's tiles are not neighbour sensitive;  the stone block always looks the same if it's floating alone or if it's part of a wall.</p>
<p style="text-align: center;"><a href="http://www.saltgames.com/wp-content/uploads/2010/01/NES_Super_Mario_Bros.gif"><img class="size-full wp-image-185 aligncenter" title="Super Mario Bros" src="http://www.saltgames.com/wp-content/uploads/2010/01/NES_Super_Mario_Bros.gif" alt="Screenshot of the original NES Super Mario Brothers showing the repeated brick block." width="256" height="240" /></a></p>
<p>That's fine for many games, but can look out of place if you're trying to create a more organic feel in a level, or just wanting to cut down on repeated patterns.  Neighbour sensitive tiles overcome this by matching their appearance to the presence of their neighbours.</p>
<p><strong>A 1-bit Map</strong></p>
<p>Let's imagine that with some clever techniques we have generated a level layout for a platformer game that consists of either stone or empty air at each grid location.  This can be represented as a 1-bit image - that is each pixel's state will be determined by a single bit, so either on indicating rock or off to indicate open air.  Here's a section of such a map, greatly enlarged and with grid lines added:</p>
<p><a href="http://www.saltgames.com/wp-content/uploads/2009/12/filledGrid.png"><img class="aligncenter size-full wp-image-178" title="filledGrid" src="http://www.saltgames.com/wp-content/uploads/2009/12/filledGrid.png" alt="" width="420" height="420" /></a></p>
<p><strong>A Tileset</strong></p>
<p>A tile set is simply a collection of the graphics that may be used to fill in a map.  Mario's tileset is quite small, consisting of just a few different types of block and scenery, whilst ours will have many graphics for the same type of tile:</p>
<p><a href="http://www.saltgames.com/wp-content/uploads/2009/12/tileset.png"><img class="aligncenter size-full wp-image-181" title="tileset" src="http://www.saltgames.com/wp-content/uploads/2009/12/tileset.png" alt="" width="480" height="48" /></a></p>
<p><strong>Valuing Neighbours</strong></p>
<p>To determine which tile should go at each spot on the map, we shall examine that spot's immediate neighbours (for now we'll ignore diagonal neighbours.)  Rather than writing a huge if/else-if statement to handle all the possible combinations of neighbours, we will use a system that assigns values to each direction.</p>
<p><a style="text-decoration: none;" href="http://www.saltgames.com/wp-content/uploads/2009/12/edge-values.png"><img class="aligncenter size-full wp-image-177" title="edge values" src="http://www.saltgames.com/wp-content/uploads/2009/12/edge-values.png" alt="" width="184" height="184" /></a></p>
<p>A value is found for each location by looking at its neighbours and adding up the values for whichever ones have stone present.  So if the spot we're examining has a neighbour above it that is also filled with stone then it is given the value 1.  If it has stone-filled neighbours above and below then the value is 1 + 4, so 5.</p>
<p>You may notice that the values assigned to the directions are the same as the values of the positions in a binary number and this is no surprise; both are ways of representing possible combinations of 4 units which can each be in an on or off (stone or air) state.</p>
<p>Here is the map segment with the value of each tile filled in.  You might like to manually work out the value for a couple of the tiles yourself so you're clear on how it works.</p>
<p><a href="http://www.saltgames.com/wp-content/uploads/2009/12/numberedGrid.png"><img class="aligncenter size-full wp-image-182" title="numberedGrid" src="http://www.saltgames.com/wp-content/uploads/2009/12/numberedGrid.png" alt="" width="420" height="420" /></a></p>
<p><strong>Adding the Tiles</strong></p>
<p>The order in which the tileset is laid out above is not arbitrary; it is laid out so that each tile matches what would be expected of a tile in the map that would be assigned that value.  Once we have a value assigned for each spot on the map we just need to look up that number in the tileset and place the correct tile there:</p>
<p><a href="http://www.saltgames.com/wp-content/uploads/2009/12/floatingIsland.png"><br />
<img class="aligncenter size-full wp-image-179" title="floatingIsland" src="http://www.saltgames.com/wp-content/uploads/2009/12/floatingIsland.png" alt="" width="420" height="420" /></a></p>
<p>Wonderful!</p>
<p><strong>Taking it Further</strong></p>
<p><strong>Part One - Removing Air</strong></p>
<p>Whilst the above works very neatly for platforms floating in air, it doesn't yet fully handle two tile types.</p>
<p>Instead of a platformer imagine we're working on a top-down 2D RTS with two tile types of grass and water.  In such a case we would expect every spot on the map to have a tile graphic present; there's no open spaces like in our platformer.  This means that every spot on the map will need to have a value generated from its neighbours to determine which tile fits there.</p>
<p>We can use exactly the same neighbour valuing system as before, but we now need a way to differentiate between there being grass or water at the spot being examined itself.  This is actually very simply done - just add an extra value for the location itself, following the same 2 to the power of n pattern from the other values:</p>
<p><a style="text-decoration: none;" href="http://www.saltgames.com/wp-content/uploads/2010/01/extendedValues.png"><img class="aligncenter size-full wp-image-188" title="extendedValues" src="http://www.saltgames.com/wp-content/uploads/2010/01/extendedValues.png" alt="" width="184" height="184" /></a></p>
<p>Let's decide that the presence of water means you do add on that position's value, whilst the presence of grass means you do not.  So a grass tile surrounded on all sides by grass would be numbered at 0.  A grass tile with water to the top and left would be 1 + 8 = 9.  A water tile surrounded on all sides by grass would be 16.  A water tile with water on all sides would be 1 + 2 + 4 + 8 + 16 = 31</p>
<p><strong>Part Two - Greater Variety</strong></p>
<p>How do we handle adding additional types of terrain?</p>
<p>Let's say we have three types of terrain in our top-down game: water, grass, and forest.  As well as water and grass meeting, we must now also deal with water and forest meeting as well as grass and forest meeting.</p>
<p>Previously there was two possibilities for each neighbour position (grass or water) so we used a <strong>bi</strong>nary counting system.  There's now three possibilities so we shall use a <strong>tri</strong>nary counting system.  Our neighbour valuing system needs to be adjusted to match the new counting system:</p>
<p><a href="http://www.saltgames.com/wp-content/uploads/2010/01/trinaryValues.png"><img class="aligncenter size-full wp-image-187" title="trinaryValues" src="http://www.saltgames.com/wp-content/uploads/2010/01/trinaryValues.png" alt="" width="184" height="184" /></a></p>
<p>Just as the binary counting system followed the pattern of 2 to the power of n, this follows the pattern of 3 to the power of n.</p>
<p>Using a trinary system each position has three possible states: grass, water, forest; or 0, 1, 2.  When there is grass in a given position, we ignore the value (multiply it by 0).  When there is water in the position we add on the value given (multiply it by 1).  When there is forest in the we add on twice the value (multiply it by 2.)</p>
<p>So if we had a tile that was forest with water above it, water to the right, forest below and grass to the left: 81 * 3 + 1 * 2 + 3 * 1 + 9 * 3 + 27 * 0 = 275</p>
<p>You might notice at this point that you'll need to draw 324 tile graphics to cover all the possible combinations in a three-terrain map.  This is a lot of tiles to draw by hand.  I would strongly advise looking into at least partially automated methods of producing the multitude of tile combinations.</p>
<p>Of course the system can be extended in just the same way for greater numbers of terrain types, but the number of tile graphics you would need would be even more huge.  Instead I would recommend placing some limits on what tiles are allowed to neighbour one-another.  For instance if forest and water tiles are never allowed to directly touch then the above example will need several hundred less tile graphics.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.saltgames.com/?feed=rss2&amp;p=184</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The Start of a Graph</title>
		<link>http://www.saltgames.com/?p=128</link>
		<comments>http://www.saltgames.com/?p=128#comments</comments>
		<pubDate>Mon, 05 Oct 2009 20:19:47 +0000</pubDate>
		<dc:creator>Salt</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://www.saltgames.com/?p=128</guid>
		<description><![CDATA[I've been working on procedurally generating a structured game world. Here I outline the principles of the method I'm using. Firstly, a short explanation of what I'm trying to do:  There are plenty of examples of procedurally generated (or "randomly generated") level content for games, but they often lack a certain type of structure.  Generally [...]]]></description>
			<content:encoded><![CDATA[<p>I've been working on procedurally generating a structured game world. Here I outline the principles of the method I'm using.</p>
<p><span id="more-128"></span>Firstly, a short explanation of what I'm trying to do:  There are plenty of examples of procedurally generated (or "randomly generated") level content for games, but they often lack a certain type of structure.  Generally they are used to produce very open worlds, where the player is free to explore as they like.  I am trying to make something that will create worlds with gated progression.  At its simplest this is Doom with a locked door that needs the red key which is off on a side path protected by monsters.  Less obviously lock-and-key examples would be games like Zelda and Metroid, where you need to gain certain abilities or special items to reach some areas.</p>
<p>Initially I thought to generate a simple world (maybe something like a Roguelike dungeon) and then develop techniques for adding on progression gates over it.  My first breakthrough came with giving up this idea. Instead I worked on generating the gating mechanisms at the same time as I generate the layout of the world.</p>
<p>My second breakthrough was to forget about the physical layout of the world.  What actually mattered was the connections of possible-movement between game areas.  So instead of working on a map of the world, I now work on a graph with the nodes as areas of the world and the edges as pathways between those areas that the player can move along.</p>
<p>Here's a graph representing a very simple world:</p>
<p><a href="http://www.saltgames.com/wp-content/uploads/2009/10/graph01.png"><img class="aligncenter size-full wp-image-129" title="graph01" src="http://www.saltgames.com/wp-content/uploads/2009/10/graph01.png" alt="graph01" width="202" height="173" /></a>The player starts in the node at the red arrow, and wants to get to the node with the chequered flag.  But the pathway is blocked with a lock, so the player must first travel to the node with the key.  Not at all complex, but now the world has some progression structure to it.  This graph's layout was generated by a general purpose "add a goal, and lock it away" function - before that function was called, the graph consisted just of the starting node.  The neat thing is that the same function can be used to place the key, so creating:</p>
<p><a href="http://www.saltgames.com/wp-content/uploads/2009/10/graph02.png"><img class="aligncenter size-full wp-image-130" title="graph02" src="http://www.saltgames.com/wp-content/uploads/2009/10/graph02.png" alt="graph02" width="216" height="243" /></a>When choosing where to add the node containing the key, the algorithm limits itself to picking amongst those nodes that it knows are accessible to a player who can access the lock.  This means that there was no possibility for the cyan key to be locked behind the pink door, as the cyan lock is accessible to a player with no keys at all and so the cyan key must be too.  The placing of the cyan lock now means that the pink lock/key no longer satisfy these requirements, but so long as they satisfied them when they were placed, and all locks placed afterwards satisfy them, it is guaranteed that with some work the player will be able to open the pink lock.</p>
<p>Here's where my world-graph generator is at currently.  The player starts at the red node, and wants to explore the world (there are actually specific 'goal' nodes in the map, but I figure it has enough confusing colours already.)  The player can freely move along the grey lines, but must have the correctly coloured key to travel along the coloured lines.  The nodes that hold keys are coloured indicating what key they contain.</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="600" height="600" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://www.saltgames.com/wp-content/uploads/2009/10/shoot.swf" /><embed type="application/x-shockwave-flash" width="600" height="600" src="http://www.saltgames.com/wp-content/uploads/2009/10/shoot.swf"></embed></object></p>
<p>There's a fair bit going on that isn't covered here, but I'll explain it all eventually.  The main issue I'm dealing with currently is the occasional creation of paths that cross one-another.  I am able to detect when that happens and can just discard the map and try again, but it'd be nice to just not have it happen at all.  I'm also working on making the linearity of the final map more controllable - currently it's just chance if the player can reach all the keys from the start or if they're hidden behind other doors so necessitating a specific order in which the keys can be collected.</p>
<p>That's all for now, I'm sure plenty more to come.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.saltgames.com/?feed=rss2&amp;p=128</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Maggot Blaster 500 Released</title>
		<link>http://www.saltgames.com/?p=111</link>
		<comments>http://www.saltgames.com/?p=111#comments</comments>
		<pubDate>Thu, 17 Sep 2009 14:35:38 +0000</pubDate>
		<dc:creator>Salt</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://www.saltgames.com/?p=111</guid>
		<description><![CDATA[Maggot Blaster found a sponsor on Monday, and now it is released! Check it out.  I hope you like it.]]></description>
			<content:encoded><![CDATA[<p>Maggot Blaster found a sponsor on Monday, and now it is released! <a title="Maggot Blaster 500 on Kongregrate" href="http://www.kongregate.com/games/box10Guys/maggot-blaster-500" target="_blank">Check it out</a>.  I hope you like it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.saltgames.com/?feed=rss2&amp;p=111</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fez Rip-off</title>
		<link>http://www.saltgames.com/?p=54</link>
		<comments>http://www.saltgames.com/?p=54#comments</comments>
		<pubDate>Mon, 31 Aug 2009 00:06:39 +0000</pubDate>
		<dc:creator>Salt</dc:creator>
				<category><![CDATA[Others' Games]]></category>

		<guid isPermaLink="false">http://www.saltgames.com/?p=54</guid>
		<description><![CDATA[There's a lovely game that's been in development by Polytron Corporation for a  bit over two years now, called Fez.  What really captured my imagination was the basic mechanic of the game - so much so I tried copying it. The concept is that the protagonist, Gomez, thinks he lives in a 2D world just [...]]]></description>
			<content:encoded><![CDATA[<p>There's a lovely game that's been in development by <a href="http://polytroncorporation.com/">Polytron Corporation</a> for a  bit over two years now, called Fez.  What really captured my imagination was the basic mechanic of the game - so much so I tried copying it.</p>
<p><span id="more-54"></span>The concept is that the protagonist, Gomez, thinks he lives in a 2D world just like all those other characters in sidescrolling platformers.  But he soon discovers that <em>really</em> the world is 3D but it objects just behave as if they are projected on to a 2D plane, and of course he has the power to change which plane the world is projected to.</p>
<p>From one viewpoint two platforms might appear right next to one another, whilst if viewed from the side you would see they're actually miles apart.  The key to Fez is that when objects are viewed so that they appear to be next to one-another, they actually <em>are</em> next to one-another, and Gomez can easily hop between them.</p>
<p>I really like this attempt to make some sense of the apparently 2D world in which so many games operate.  Because of course almost no "2D" games really are showing us a 2D world.  So long as any elements of the world are allowed to overlap or there's any concept of things being in the background, the game's world must involve a third dimension.  Don't even get me started on two dimensional digestive systems.</p>
<p>I was interested in the challenges and design decisions that would need to be met when implementing the world of Fez, so I had a go myself.  It's pretty rough around the edges, and it's just a movement prototype set in a tiny world; but I think it's quite fun.  It almost goes without saying that I learnt a great deal making this.  I'm not taking this prototype any further; if you want to play it for real go buy Fez when it's released next year!</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="650" height="500" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://www.saltgames.com/wp-content/uploads/2009/08/block.swf" /><embed type="application/x-shockwave-flash" width="650" height="500" src="http://www.saltgames.com/wp-content/uploads/2009/08/block.swf"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://www.saltgames.com/?feed=rss2&amp;p=54</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>On the Intelligence of Maggots</title>
		<link>http://www.saltgames.com/?p=50</link>
		<comments>http://www.saltgames.com/?p=50#comments</comments>
		<pubDate>Sun, 30 Aug 2009 12:08:25 +0000</pubDate>
		<dc:creator>Salt</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://www.saltgames.com/?p=50</guid>
		<description><![CDATA[The pathfinding AI for Maggot Blaster 500 turned out to be the soul of the game. For this post I'll describe how it works, and how it was used for more than expected. Pathfinding is a term used to describe the problem of trying to find the shortest path between two points.  In the case [...]]]></description>
			<content:encoded><![CDATA[<p>The pathfinding AI for Maggot Blaster 500 turned out to be the soul of the game.  For this post I'll describe how it works, and how it was used for more than expected.</p>
<p><span id="more-50"></span>Pathfinding is a term used to describe the problem of trying to find the shortest path between two points.  In the case of Maggot Blaster, I needed to find the shortest path between each enemy, and the player.  Both were constantly on the move, the environment was complex and changing, and there were liable to be a <em>lot</em> of enemies.</p>
<p><strong>The heightmap</strong></p>
<p>Focusing on trying to make the game cope with very large numbers of enemies, I decided to use something like a hive mind approach.  Rather than each enemy work out their own path, a central AI will produce a global "heightmap" that all the enemies will use to find their own path using a much more simple (and fast) algorithm.</p>
<div id="attachment_51" class="wp-caption aligncenter" style="width: 526px"><a href="http://www.saltgames.com/wp-content/uploads/2009/08/chase-heightmap.png"><img class="size-full wp-image-51" title="chase heightmap" src="http://www.saltgames.com/wp-content/uploads/2009/08/chase-heightmap.png" alt="A screenshot showing the usually invisible pathfinding heightmap superimposed over a map." width="516" height="558" /></a><p class="wp-caption-text">A screenshot showing the usually invisible pathfinding heightmap superimposed over a map.</p></div>
<p>Above you can see their heightmap from a very old build of the game.  Hidden under the brightest area you can just about make out the player.  From the player, the light spreads out as you'd expect in open areas but is blocked by walls and instead must find another route to get to those areas.</p>
<p>If you're placed anywhere on that heightmap then you can be guaranteed to find the player if you simply always move towards whatever local direction is brighter.  You don't get the exact shortest route as the heightmap is generated in such a way that implies you can only move in the four cardinal directions, when enemies can actually move in any direction.  However it always turns out "close enough", with the only artefact being a tendency for enemies to want to approach directly along one of the cardinal directions.</p>
<p><strong>From heightmap to movement</strong></p>
<p>Translating the heightmap data to enemy movement is very simple.  Just look at the values of the heightmap in the grid squares directly above, below, left and right of the grid square that the enemy currently occupies.  Using just those values, an acceleration is applied to the enemy split proportionally between whatever directions have the greatest increase in brightness compared to the current grid square.  To put it in less words, you imagine the heightmap is showing the contours of land with the bright areas are lower; then have the enemy slide down the slopes.</p>
<p>The characteristics of this sliding vary between enemies which give rise to some unique movement styles despite them all using the same pathfinding technique.  The basic slower enemies proceed along the heightmap at a reasonable speed and with well controlled acceleration.  Meanwhile the 'crazy purple buggers' (you'll see when you play the game) have a very high top speed but fairly low acceleration, which means they'll get up lots of speed when rushing towards the player but often overshoot their target or appear to skid past doorways they're aiming for.  It really helps give the various enemies their own character.</p>
<p><strong>Suddenly, swarming</strong></p>
<p>A problem with a few hundred enemies all following the same heightmap with the same rules is that they'll tend to all follow the same path and end up constantly overlapping.  Suddenly your amazing feat of producing masses of enemies looks like you've just produced one caterpillar enemy.</p>
<p>Information on how many enemies are in each grid square is already maintained for use in collision detection.  Whilst generating the heightmap I simply darken each grid square based on how many enemies are known to be there.  This has the effect of slightly shifting the paths generated from the heightmap so that they avoid other enemies.  As this alteration to the values take place during the generation of the heightmap they are carried through and keep the overall heightmap consistent: If the player is inside a building with two entrances and one is already filled with enemies then a new enemy approaching from outside will be likely to enter through the other entrance.</p>
<p>Not only did this change keep the enemies from forming boring orderly lines, but it also helped avoid a situation where the player can just stand at one doorway shooting all who come through it; the density of enemies at that entrance will encourage fresh enemies to seek an alternate route to the player even if it is a slightly longer distance.</p>
<p><strong>Unexpected benefits</strong></p>
<p>Now that a heightmap is being maintained for the whole level, I was able to find some other handy uses for it.</p>
<p>Finding ammo crates is an integral part of the game - they force the player to keep moving, and push them into dangerous and tense situations.  However it isn't fun just having no idea where the ammo is to start with.  So when the player is at a low ammo state the heightmap is used to draw a path of dots from the player to the nearest ammo crate.  How do I find which ammo crate is nearest? Simply look at the value on the heightmap where each crate is and compare them.</p>
<p>Similarly the heightmap value is used to determine if the player is close enough to cause maggots to notice them and start chasing.  Probably faster than working out the 'true' distance, and avoids maggots being able to see you through a wall.</p>
<p>Earlier versions of the procedural map generator would occasionally produce areas that were inaccessible.  The heightmap only holds values for areas that are accessible, so I was able to use it to identify these areas and avoid spawning anything in there.</p>
<p>The heightmap is also used when determining where to spawn fresh enemies.  As well as never spawning an enemy in a location visible on the screen I sometimes want to make sure an enemy is at a minimum distance.  For instance that crazy purple one I mentioned earlier has a special scream/roar sound when it spawns, so I want a little delay before it actually reaches the player's screen.  Simply limit spawning to areas with the correct range of values on the heightmap.</p>
<p>This one didn't make it into the final game, but it is possible to simply reverse how enemies react to the heightmap and they'll produce rather convincing fleeing behaviour.  Typically their fleeing would lead them into a dead-end corner of a building where they would sit quivering.</p>
<p><strong>The future!</strong></p>
<p>I'm very interested in using multiple heightmaps, and having entities switch between which they're following depending on what behaviour they should be producing at the time.  A "take cover" heightmap could be produced with areas that are out of line of sight of the player being the most bright.  Each entity could make up its own mind on if it would be best chasing, fleeing, or taking cover and pick the corresponding heightmap to follow.  Imagine hundreds of tiny infantry units scurrying behind cover as the player's mechanical war machine stomps by.</p>
<p>This was actually the plan from the start for what became Maggot Blaster, but such is the way of games.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.saltgames.com/?feed=rss2&amp;p=50</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
