a stroke of luck

Tweetcoding – 140 characters of actionscript 3

Just over a week ago, Grant Skinner started a competition on Twitter called Tweetcoding. It’s very simple:
#tweetcoding: code something cool in <=140 characters of AS3
By happy coincidence this was just after I’d decided to give Twitter another chance and so I heard about the competition and decided to get involved. The first thing I did was to put together a quick tweetcoding minifier using jQuery – it lets you paste in your (slightly) readable AS3 code and it strips unnecessary whitespace and tells you how many characters you’ve used. Definitely much easier than the find and replace gymnastics I was doing in my text editor to start with!

Next I had big plans for creating a website to allow you to compile your own tweetcodes online. But all three of my approaches failed – I couldn’t trigger Java (and therefore mxmlc) from PHP on my shared host, I couldn’t piggyback on the wonderfl API (they use mxmlc behind the scenes too) and screaming donkey couldn’t handle the DisplayList. Luckily, Robert Cadena had the same idea and managed to execute it wonderfully and produce the tweetcoding compiling robot (I’m not sure what it’s really called!). You can visit that page and check out all of the great entries without compiling yourself.

The next step was to find a way to compile my tweetcoding from FDT – my preferred editor. I tried using Flash but it’s little code window annoyed me quickly and I don’t have CS4 yet so I couldn’t access any of the flash player 10 features. So I set up a project in FDT and created the following class:

   import flash.filters.*;
   import flash.text.TextField;  
   import flash.ui.Mouse;  
   import flash.display.*;

   dynamic public class Tweetcode extends MovieClip

      public var g:Graphics;
      public var mt:Function;
      public var lt:Function;
      public var ls:Function;
      public var m:Class;
      public var r:Function;
      public var s:Function;
      public var o:Object;
      public var i:Number = 0;

      public function Tweetcode():void
         g = graphics;
         mt = g.moveTo;
         lt = g.lineTo;
         ls = g.lineStyle;
         m = Math;
         r = m.random;
         s = m.sin;
         o = {};

         addEventListener("enterFrame", f);

      public function f(e:Event):void
         // 140 characters here!

As you can see, it includes Grant’s gimmie code and space for me to add my code. I’ve added extra imports as I’ve needed them but I’m sure there are more that could be included. And I added some static typing to the variables even though this isn’t necessary – it does means I get a little help from FDT’s code hinting. Then I added ” –strict=false” to the mxmlc command line in my launch target and I was good to go :)

Below are some of my tweetcoding attempts in reverse chronological order (that doesn’t necessarily mean that they get better though!). Make sure you check out all of the other entries as well though – there is some incredible stuff. It is amazing what you can cram into so few characters!

Flickering Flame

A simple flame-like effect. View

g.clear(),o[++i]={x:mouseX,y:mouseY,b:9},filters=[new BlurFilter(4,4)];for each(p in o)a=p.b-=.2,ls(a,3e9,a),mt(p.x,p.y),lt(p.x+a,p.y--+a);


Blow into your microphone to make it spin around!. View

if(i&lt;6.5) q=Microphone.getMicrophone(),q.setLoopBack(),ls(2),x=y=99,mt(0,0),lt(90*s(i),90*m.cos(i)),i+=m.PI/18;rotation+=q.activityLevel/9;

Colourful bondage

The coloured lines want to keep your mouse prisoner. View

g.clear(),Mouse.hide(),o[++i]={x:mouseX,y:mouseY,b:7,c:i< &lt;16+i<&lt;32};for each(p in o)a=p.b-=.3,ls(a,p.c,a),mt(p.x,p.y),lt(mouseX,mouseY);

Stripy wallpaper

Just some nice animating blue stripes. View

g.clear();t=stage,o[++i]={x:300+s(i)*300,b:9,c:9*i};for each(p in o)a=p.b-=.3,ls(a,p.c,a),l=p.a,mt(p.x,0),lt(p.x,t.stageHeight);

Mouse bubbles

Little bubble like particles escaping from the mouse. View

g.clear(),o[++i]={x:mouseX,y:mouseY,a:r()*9-5,b:r()*9};for each(p in o)a=p.b--,ls(2),p.a*=.9,p.b*=.9,mt(p.x+=p.a,p.y+=p.b),lt(p.x+1,p.y+1);

Ninja the mouse killing line

Weird title (I guess the tweetcoding had gone to my head) but probably my favourite of my entries. View

g.clear();o[++i]={x:mouseX,y:mouseY,a:o[i-1],b:9};for each(p in o)!p.a||(ls(p.b--),l=p.a,mt(p.x-=(p.x-l.x)/6,p.y-=(p.y-l.y)/6),lt(l.x,l.y));


Short and simple. View

g.clear();o[++i]={x:i,y:99+s(i)*99,a:o[i-1]||{x:0,y:99}};for each(p in o)ls(1,p.x*0x020101),mt(p.x,p.y-=(p.y-p.a.y)/6),lt(p.x,p.y+2);

Marching ants

They follow the mouse and slowly straighten out over time. View

g.clear();ls(2);o[++i]={x:mouseX,y:mouseY,a:o[i-1]||{x:250,y:250}};for each(p in o)mt(p.x-=(p.x-p.a.x)/6,p.y-=(p.y-p.a.y)/6),lt(p.x+1,p.y);

Silly String

Stringy stuff falls from your mouse. View

g.clear();ls(2);o[++i]={x:mouseX,y:mouseY,a:o[i-1]||{x:9,y:9}};for each(p in o)mt(p.x-=(p.x-p.a.x)/6,p.y-=(p.y-p.a.y)/6),lt(p.a.x,p.a.y);

Random Silly String

Stringy stuff gets spread around the screen. View

g.clear();ls(1);o[++i]={x:500*r(),y:500*r(),a:o[i-1]||{x:9,y:9}};for each(p in o)mt(p.x-=(p.x-p.a.x)/6,p.y-=(p.y-p.a.y)/6),lt(p.a.x,p.a.y);

First try

This one is from before there was any gimmie code so it's 140 characters that run by themselves. Unsurprisingly, they do very little! View

var w=x=y=200,b,g=graphics,m=Math,l=g.lineTo,c=m.cos,s=m.sin,i=361;while(i--){g.lineStyle(1,m.random()*0xfff);l(w*c(i),w*s(i));l(0,0);}

Tweetcoding is great fun and seems to be part of a trend to impose constraints to trigger creativity. I've been a close follower of the 25 lines competition and been blown away by what people have achieved there. I'm also really interested in the 4k flash game competition and would love to find the time to put an entry together. It's incredible the amazing results you can get by abandoning anything like best practises and trying to squeeze something interesting out of a constrained situation. Good clean geek fun :D

Interviewed on

Last week I received an email Pablo Parrado of
We’re trying to make a community portal that explores that social aspect of the Flash community and get to know the people behind the names.
He went on to ask me to take part in a series of interviews he is doing. I was honored to be asked and to add my thoughts to those of some leading lights of the flash world (42 in total at the moment). So I completed the interview and yesterday it went live. If you want to read my rambling thoughts about the past and future of flash then please head on over to my interview with actionscript hero. Thanks Pablo!

New This happened website

This happened is a series of events focusing on the stories behind interaction design. Having ideas is easier than making them happen. We delve into projects that exist today, how their concepts and production process can help inform future work.
This happened is an event originally organised by Chris O’Shea, Joel Gethin Lewis and Andreas Müller in London. I’ve been lucky enough to attend a few times and it is always really interesting and inspiring. The fact that the speakers talk about the process and the failures along the way is much more interesting than someone just showcasing their work. And I find the field of “interaction design” really interesting – a world somewhere between computers and the real world and somewhere between art and science.

So when Chris asked if I’d help out with a flickr viewer for the new website I was more than happy to help. I put together a little swf which is used throughout the site. It connects to the Flickr API (using as yet unfinished and unrealeased as3 version of flashr) and grabs photos matching certain machine tags. Depending on where in the site you are the swf displays relevant photos (e.g. from a particular city or a particular event) as a simple slidehow. The thishappened team can easily choose to display any photos that attendees have uploaded to flickr with relevant permissions. And they keep editorial control over the content via a special “auth” machine tag which they can generate through their CMS. It’s all pretty simple but it’s a nice way to bring user generated content to their site easily.

This happened is branching out and encouraging people to host events across the world so keep an eye out for one near you (or even set one up yourself) and if you get the chance make sure you attend.

Happy Christmas and Happy New Year!

This Christmas I am living in Canada whilst most of my friends and family are back in England or elsewhere. So I decided to make a virtual Christmas card that I could easily and quickly send anywhere. So here’s one for the reader(s?) of my blog:

You can click on the card to flip it over and read the message on the back but remember to flip back and see how the snow stacks up on the figures in the foreground… It’s not exactly realistic but I like it :)

I managed to put the whole thing together in about a day (which didn’t stop me being about a day late sending it out!) thanks to a bunch of open source projects. So massive thanks to the authors of and contributors to:
  • Papervision for the 3d (although thinking about it, I could have possibly tried to do something this simple using the new “postcards in space” 3d of the flash player 10).
  • Flint particle system for the snow (and I’m hoping to do more with this engine soon – it’s really nicely put together).
  • Pure MVC for holding it together.
  • Code Igniter for the backend (so I can send different cards to different people).
  • GTween for the tweening.
  • And also to Icon Drawer for the icons who are standing in the foreground of this card.
And now it’s time to go out and celebrate the approach of another year! I’m looking forward to lots of cool stuff for next year, both work and play. So Happy Christmas and Happy New Year everyone!! And all the best for 2009 :D

Experiment with Papervision 3D particles and effects

A while back I was prototyping something for a client which involved lots of red dots moving around in 3D space, realised using Papervision 3D. I didn’t end up persuing this route with the client in the end but the effect was pretty cool so I thought I might as well share it here.

The idea is that there is a bunch of particles who are bouncing around randomly stuck within an invisible cube. The effect looked OK by itself but then I decided to try adding effects. I used a BlurFilter and a BitmapColorEffect to give the each of the particles trails. Then I changed the clipping point like in the original borg cube effects demo to give the impression of the particles falling. I like this version the best – if you move your mouse from side to side around the bottom of the demo swf then it starts to look like some kind of flocking is going on (like in my perlin noise experiment).

Click on the image below to see the demo. Click inside the demo swf to give it focus and then you can use the following keys:
  • 1 – Sets the render mode to normal clean particles (the default).
  • 2 – Sets the render mode to particles with trails.
  • 3 – Sets the render mode to falling particles with trails.
  • c – Toggles display of a cube showing the area the particles are contained within.

Particles and effects in Papervision 3D

The sourcecode for this example is pretty simple. You can see it below or you can download it from here.

   import org.papervision3d.core.effects.BitmapColorEffect;
   import org.papervision3d.core.effects.BitmapLayerEffect;
   import org.papervision3d.core.geom.Particles;
   import org.papervision3d.materials.WireframeMaterial;
   import org.papervision3d.materials.utils.MaterialsList;
   import org.papervision3d.objects.DisplayObject3D;
   import org.papervision3d.objects.primitives.Cube;
   import org.papervision3d.view.AbstractView;
   import org.papervision3d.view.BasicView;
   import org.papervision3d.view.layer.BitmapEffectLayer;
   import flash.display.StageQuality;
   import flash.filters.BlurFilter;
   import flash.geom.Point;      

    * @author Kelvin Luck

   [SWF(width='450', height='450', backgroundColor='#000000', frameRate='41')]

   public class ParticlesCube extends BasicView
      public static const NUM_PARTICLES:int = 300;
      public static const CONTAINING_CUBE_SIZE:int = 500;
      public static const RENDER_MODE_CLEAN:int = 0;
      public static const RENDER_MODE_TRAILS:int = 1;
      public static const RENDER_MODE_FALLING:int = 2;
      private var particlesContainer:DisplayObject3D;
      private var particlesHolder:Particles;
      private var particles:Array;
      private var boundsCube:Cube;

      private var bfx:BitmapEffectLayer;
      private var _renderMode:int;
      public function set renderMode(value:int):void
         if (value == _renderMode) return;
         var clippingPoint:Point = new Point();
         switch (value) {
            case RENDER_MODE_CLEAN:
               // nothing - effects already cleared above...
            case RENDER_MODE_FALLING:
               clippingPoint.y = -2;
               // fall through...
            case RENDER_MODE_TRAILS:
               bfx = new BitmapEffectLayer(viewport, stage.stageWidth, stage.stageHeight, true, 0xffffff);
               bfx.addEffect(new BitmapLayerEffect(new BlurFilter(2, 2, 2)));
               bfx.addEffect(new BitmapColorEffect(1, 1, 1, .9));
               bfx.clippingPoint = clippingPoint;
               throw new Error(value + ' is an invalid render mode');
         _renderMode = value;
      private var _displayCube:Boolean = true;
      public function set displayCube(value:Boolean):void
         if (value != _displayCube) {
            _displayCube = value;
            boundsCube.visible = value;

      public function ParticlesCube()
         super(550, 550);
         stage.quality = StageQuality.MEDIUM;
         particlesContainer = new DisplayObject3D();
         var cubeMaterial:WireframeMaterial = new WireframeMaterial(0x0000ff, 1, 2);
         var materialsList:MaterialsList = new MaterialsList();
         materialsList.addMaterial(cubeMaterial, 'all');
         displayCube = false;
         particlesHolder = new Particles();
         stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);

      public function init(numParticles:int, containingCubeSize:int):void
         var movingParticle:MovingParticle;
         if (particles) {
         particles = [];
         var i:int = numParticles;
         while (i--) {
            movingParticle = new MovingParticle(containingCubeSize);

      override protected function onRenderTick(event:Event = null):void
         // move each particle
         var movingParticle:MovingParticle;
         for each (movingParticle in particles) {
         // twist the container based on mouse position
         // render
      private function clearBitmapEffects():void
         if (bfx) {
            bfx = null;
      private function onKeyDown(event:KeyboardEvent):void
         switch (String.fromCharCode(event.keyCode)) {
            case '1':
               renderMode = RENDER_MODE_CLEAN;
            case '2':
               renderMode = RENDER_MODE_TRAILS;
            case '3':
               renderMode = RENDER_MODE_FALLING;
            case 'c':
            case 'C':
               displayCube = !_displayCube;

import org.papervision3d.core.geom.renderables.Particle;
import org.papervision3d.materials.special.ParticleMaterial;

internal class MovingParticle extends Particle
   public static const PARTICLE_SIZE:int = 10;
   public static const MAX_SPEED:int = 5;
   private var dX:Number;
   private var dY:Number;
   private var dZ:Number;
   private var halfSize:Number;

   public function MovingParticle(containingCubeSize:int)
      var mat:ParticleMaterial = new ParticleMaterial(0xff0000, 1, ParticleMaterial.SHAPE_CIRCLE);
      super(mat, PARTICLE_SIZE);
      var size:int = containingCubeSize;
      halfSize = size / 2;
      x = (Math.random() * size) - halfSize;
      y = (Math.random() * size) - halfSize;
      z = (Math.random() * size) - halfSize;
      dX = Math.random() * MAX_SPEED;
      dY = Math.random() * MAX_SPEED;
      dZ = Math.random() * MAX_SPEED;
   public function position():void
      x += dX;
      if (x > halfSize || x < -halfSize) dX *= -1;
      y += dY;
      if (y > halfSize || y < -halfSize) dY *= -1;
      z += dZ;
      if (z > halfSize || z < -halfSize) dZ *= -1;
// This line is just to stop the code formatter on my blog getting confused! >

New multiplayer papervision game

I’ve just released my entry into the Nonoba Multiplayer API Kick Off competition. It’s a multiplayer take on the old memory cards game where you have to turn over pairs of cards and try to remember what was under each one. The multiplayer aspect makes it much more frantic and fun as other players are looking at the same cards at the same time as you and you don’t want them to steal your pairs!

It will probably make more sense if you try it out yourself so go ahead and click the image below to play multiplayer memory mayhem!
My good friend Leigh Kayley did the designs (including illustrating all of the cool animals) and I built the game using Papervision, PureMVC, GTween and the Nonoba multiplayer API.

While I was building the game I did a little prototype for the score board transitions using papervision which you can see by clicking the image below. Click anywhere in the movie to give a random player some random points (and so maybe rearrange the scores) and press any keyboard key to toggle some mouse following behaviour.

Papervision 3D score panels test

Unfortunately in the game you can’t really see the 3d transitions on the scores so I thought I’d upload this for people to look at. And I’ve also uploaded the source code for anyone who is interested. It’s probably not the best because it was a prototype stuck together quickly but it may be useful to someone…


I’m pleased to say that Multiplayer Memory Mayhem won third prize in the multiplayer kickoff competion on Nonoba… Yay!

Wave Sequencer experiment

A couple of weeks ago I attended the FitC Amsterdam conference which was great fun. One of the most inspiring sessions I saw was Andre Michelle‘s “Making REAL Music Within Flash” where he talked us through generating sound in flash using the infamous flash sound hack and then showed us how he is redefining what should be possible in flash by building the hobnox audio tool.

I travelled to Amsterdam by train and ferry which meant that I had some spare time on the way back to play and luckily Andre and Joa Ebert have released the complex code behind the flash sound hack as part of their popforge open source library.

So I built my Wave Sequencer. The idea is that it loads in a wav file and splits it into 16 equally sized chunks. You can then re-arrange these chunks to create new variations on the beat. Each 16 chunk section is a pattern and you can create up to 16 different patterns by choosing different patterns from the “pattern bank” at the bottom of the screen.

The loop I’m using is the famous Amen break and I’ve sped it up a bit (and given you a slider so you can control the speed yourself). If you play around with it you’ll see you can slice and dice your own old skool jungle riddims :)

Screenshot of Wave Sequencer Experiment

Note: If you are experiencing choppy audio then you are probably running the latest revision of the flash player ( which breaks onSoundComplete. So join the petition and ask Adobe to make some noise. I’ve compiled a standalone version of the app against the older player and you can download the PC standalone version which doesn’t have the audio issues.

Obviously this little experiment is very rough around the edges and there is a lot that can be done to improve it but I’ve been too busy with “real work” to look at it in the weeks since I got back from FitC and I thought it was better to publish it as is than to leave it to get lost on my hard drive…

My code here is really simple, all of the complex stuff is done by the popforge library. So big thanks to Andre for the inspiration and the sourcecode :) Hopefully I’ll find some time in the coming months to take this a lot further and to turn it into an AIR app which is actually useful!

Flash on the Beach and some Perlin Noise

Last week I went to the Flash on the Beach conference and as has been said by many people, it was amazing.

I decided to go for more of the inspirational rather than technical sessions and saw some absolutely amazing speakers including (in order of appearance): Hoss Gifford, Joshua Davis, Brendan Dawes, Craig Swann, Mario Klingemann, Robert Hodgin, Erik Natzke, Chris Allen, Dr Woohoo, Andre Michelle, Marcos Weskamp and Jared Tarbell. Wow!

And as well as all these amazing talks there was the opportunity to meet loads of friends – old and new – and to chat about geeky stuff. And then there was all of the booze and the parties… And a girl in a box!

Anyway, one particular example from Robert got me thinking and wanting to play… He mentioned the PerlinNoise function and talked about how it could be used to simulate flocking. And he showed a slide where a perlin noise image had been used to set the rotation of a set of arrows displayed on top of it. I wanted to play with this and had a little bit of time over the weekend so I managed to come up with this:

My perlin creatures

It’s really simple stuff – you can get the sourcecode and see the process that it evolved through here. The code isn’t beautiful or optimised as I was trying to concentrate on playing rather than doing it right (a concept which seemed to be a recurring theme of the conference).

And I wasn’t the only one who got interested by Robert’s mention of perlin noise. Seb Lee-Delisle posted on Sunday about 3D Perlin Noise in Flash – it looks like a really interesting way to take this further. I can’t wait to see what he comes up with and hopefully to find some more time to play with it myself :)

Flash CS3 trial breaks Juniper Network Connect

It’s been a long time since I’ve posted here because I have been crazily busy working on a massive flex site with a great team over at Tribal DDB London. Hopefully it will go live at the start of next year so I can talk more about it. In the meantime, here is a quick tip for anyone having trouble connecting to a VPN powered by Juniper software’s Network Connect after installing the trial version of Flash CS3.

After installing a trial of Flash CS3 I noticed that I became unable to connect to the VPN. Network Connect would connect briefly and then pop up an alert saying “The Network Connect session terminated. Do you want to reconnect? (”

After a bit of googling I found out that there were complaints about the early betas of CS3 and the Bonjour service that they installed affecting networking. And this is what was causing my problem. If you press Ctrl-Alt-Del and look at your processes then you will find a “mDNSResponder.exe” service running after installing Flash CS3. Ending this process allows you to connect through Network Connect.

You will have to do this every time you have restarted your computer as the process is automatically started with the system. Alternatively you can stop the service which starts the mDNSResponder process.

Go to Start Menu > Run and type in “services.msc” to open the services configuration panel. Look for a service with a name something like “##Id_String1.6844F930_1628_4223_B5CC_5BB94B879762##” (I think the bit after the dot will change on each computer). To confirm it’s the correct service double click on it and look at the “Path to executable” – it should be “C:\Program Files\Bonjour\mDNSResponder.exe”. If it is then change the “Startup type” to “disabled” and press the “Stop” button. You should now be able to connect to your VPN.

As far as I can tell, neither of these solutions have had a detrimental effect on my trial install of Flash so I think that they are safe changes to make but no guarantees! Hopefully the information will save someone the time it took me to find the answer.

Flashconference rocked!

At the end of last week I visited Stuttgart, Germany for FlashConference and I have to say it was wicked! A week later I’ve finally found the time to write a quick overview of the conference…

First up a massive thanks to Mario for getting me on the guest list and motivating me to make the journey – it was definitely worth it. A top notch list of very inspiring speakers – if I had any complaints it would only be that they tried to fit so much into one day so there was no space between the sessions (not even for lunch!).

The day started with a bit of an infomercial from Adobe, nothing particularly new although I’d never seen Scout before and it was a pretty nifty apollo sample app (basically a web browser with some of the features from Firebug and the web developer toolbar built in).

Then Ilias Sounas gave a talk showing how he had made some of his animations in Flash and talking about the importance of telling a good story. He also screened some of his animations – Circle of life was my favourite.

Next up Peter Elst gave an insight onto developing Flash for alternative devices. Everything from PSPs and Nintendo Wiis to Chumbys and other strange devices. Very interesting stuff and an area I definitely want to find some excuses to do some work in. Luckily Peter also had a bunch of ideas for how to convince your clients that building flash stuff for these devices is a good idea so maybe I’ll be able to use those ideas to convince some clients…

Then Claus Wahlers gave a talk about the Flash CS3 components which he helped to build. They definitely look like they are a major step forwards from all the previous ones especially in terms of how easy they are to extend and skin. I’m looking forward to getting my copy of CS3 and playing with them…

I skipped the next session (“Mercedes-Benz E-Class Experience Paris-Beijing”) because I needed to get some lunch! So did quite a few other people and so I got to meet up with Ralph, Asger, Martin, Peter, Claus and Wouter.

After lunch rushed back in for Mario’s session: “The blind Sketchmaker” – Artificial Creativity and Evolutionary Art in Flash. He started by discussing whether computers could create Art. After deciding that this wasn’t the case (as Art is more than just a picture – it’s a complete belief system around it) he went on to prove that he certainly could! He wrote an AS3/ Apollo app which could analyse pictures by many different criteria and learn rules about what makes a “good” picture. The program could then evolve it’s own pictures applying these rules to decide which direction to evolve in. He then got some of these generated pictures painted as full size oil paintings courtesy of a company in China who sent him some spam. Amazing, inspiring stuff – check out the finished artworks on flickr.

Then came Marcus Weskamp who talked about his experience building Wieden and Kennedy’s site. This site needed a way to display the hundreds of jobs this advertising agency has done and Marcus put his data visualisation skills to good use creating a timeline and 3d nodemap showing how all the projects, offices, people and clients were related to each other. Especially interesting was how the idea for the site evolved as a result of meetings between Marcus and his client.

Next Holger Eggert gave an insight into creating animated films in Flash. He gave an insight into how to construct a good story and use Flash/ Photoshop/ After Effects to make it real and he showed some of his work (and work in progress).

Finally, Andre Michelle gave an overview of advanced audio programming in Flash together with a hack which makes it possible to basically write your own samples in Flash and play them back. He demo’d a bunch of little apps he’s built from 303 simulators to little drum machines to .mod file players and tested the conference sound system while he was at it! Again, amazingly inspiring stuff, I need to find some time to play with all of this!

After that we all managed to get into the speakers dinner/ drinks and thus started a big night in Stuttgart… But that’s a different story!

As I said, the conference was really inspiring and it was great to get to meet all of the people involved too. Now that the hangover has died away I’m looking forward to finding some time to play with some of the new ideas I’ve got and looking forward to next years conference!