mary rose cook

What I’ve been working on


Andro.js

Today, I am releasing Andro.js, a new JavaScript library that helps you compose objects from fragments of behaviour.

The problem

Over the last few months, I have been writing a new JavaScript game. It is a 2D platformer that involves leaping about, stabbing, shooting and blowing stuff up – that much is certain. But it also has a puzzle element that is almost totally undefined.

When I began working on this puzzle element, I experimented with objects with different capabilities: objects that would light up, or play a sound, or leap into the air. Soon, it became clear that I needed a way to give a single object multiple capabilities. Then, I needed a way for these capabilities to interact, like: make this cube light up and leap into the air when it is touched by the player.

A common approach to defining the behaviour of game objects is to use components. These are chunks of code that are installed in the object, each to handle a separate task: artificial intelligence, collision detection and so forth. When the game loop ticks, each game object gets an update call and, in turn, calls an update function on each of its components, so that they can do their work. This is nice because you separate concerns, which means your code is easier to read, easier to reuse, and easier to reason about. Further, the components have total control over their game objects, so you can still do powerful stuff.

I thought about using a component-based approach, but it seemed like it didn’t really fit the way the game objects actually worked. If I were to program a leap into the air capability, what type of component would it be? Logic? And if I wanted my object to only leap when it was touched by the player, how would I organise the code then? Could I shove the leaping and touch detection into some sort of vague Collision Detection component? Or would components somehow talk to one another? I wanted to organise the code by its function, rather than its approach.

A solution

I needed to be able to write very malleable, tightly focused fragments of code that could be reused and recombined as I changed my mind, and I was willing to sacrifice some code clarity to get this.

It seemed that mixins were a promising approach. A mixin is a bundle of attributes and functions that are written onto an object, thus conferring a set of capabilities. A traditional mixin puts these attributes and functions into the namespace of the object. Any clashes: boom. That seemed too dangerous to me. I decided to put each mixin in its own namespace.

Another potential danger was how these mixins would interact. Their reusability would be limited if they had to call each other’s functions by name. Further, direct interaction would make things into a wild free-for-all that was impossible to reason about, with behaviours walking into rooms and issuing orders and walking out to cause chaos elsewhere. I quelled the potential chaos (somewhat) by deciding that the behaviours should only interact via events.

Finally, I had a plan: mixins in their own namespaces communicating via an event emitter. I wrote Andro.js to enact this plan.

An example of Andro.js in use

I require the andro.js file. I instantiate Andro. I define the game object as a constructor called Cube. It has a touch function that, when called, emits a touch event to all behaviours (mixins) attached to the cube.

  var Andro = require('andro').Andro;
  var andro = new Andro();

  function Cube {
    this.touch = function(contact) {
      andro.eventer(this).emit("touch", contact);
    };
  };

I define the firstTouchBehaviour mixin. This binds to the touch events emitted by its owner and keeps track of the number of things currently in contact. When the owner goes from being untouched to being touched, firstTouchBehaviour emits a FirstTouch:newlyBeingTouched event.

  var firstTouchBehaviour = {
    touchCount: 0,

    setup: function(owner) {
      andro.eventer(owner).bind(this, "touch", function(contact) {
        if(contact === "added") {
          if(this.touchCount === 0) {
            andro.eventer(owner).emit("FirstTouch:newlyBeingTouched");
          }
          this.touchCount++;
        } else if(contact === "removed") {
          this.touchCount--;
        }
      });
    }
  };

I define soundBehaviour. This binds to the FirstTouch:newlyBeingTouched event. Each time this event occurs, soundBehaviour makes a noise: “Rarrrrrwwwwwwwwwwwwwwww”.

  var soundBehaviour = {
    setup: function(owner) {
      andro.eventer(owner).bind(this, "FirstTouch:newlyBeingTouched", function() {
        console.log("Rarrrrrwwwwwwwwwwwwwwww");
      });
    }
  };

I now put everything together. I instantiate cube, set it up for use with Andro.js and augment it with firstTouchBehaviour and soundBehaviour. Finally, I simulate two touches upon the cube. On the first, it roars. On the second, it does not.

  var cube = new Cube();
  andro.setup(cube);
  andro.augment(cube, firstTouchBehaviour);
  andro.augment(cube, soundBehaviour);

  cube.touch("added"); // rarrrww
  cube.touch("added"); // silence

Limiting mentalness

The approach Andro.js takes exchanges a measure of one’s ability to reason about the code for a measure of malleability. Though the modes of expression are constrained to events and mixins, you can still express yourself into one hell of a mess.

As I’ve worked on my new game, I’ve discovered some guidelines that avoid most of the mess. First, all my behaviours have only one responsibility. Second, most either emit information about state, or act upon information received. Third, behaviours do not meddle with the state of their owner objects.

Was this all a mistake, my beloved?

It’s hard to express something at the same time as you’re figuring out what you’re trying to say. Andro.js has enabled me to design some complex game objects. For example, one type of object can simultaneously flash, be a note in a step sequencer, and play a sound when struck that is conferred to it by a nearby object. The code for the behaviours is clean and readable. But, I have rewritten it four times. So, I wonder if there are superior approaches.

I keep on thinking about Arc. Paul Graham has said it is a language designed for exploratory programming. And I keep on thinking about GOOL, the dialect of LISP that Andy Gavin invented to script the game objects in Crash Bandicoot.

These are both languages designed to solve the problem I have been grappling with. Is the logic of game objects in fact a microcosm of all of programming, as complex a problem as any that might be solved by a programming language? Or is it usually a limited problem that is easier to solve when you limit the tools at your disposal? And if that is so, is mixins+events a good approach, or is there a better one?


The rules of Ninja, as I learnt them last night

1. Players stand in a circle, each an arm’s length apart from their neighbours.

2. Someone shouts, “One! Two! Three! Ninja!”

3. On, “Ninja!”, the players adopt a ninja-like pose and remain still.

4. The person who counted everyone in now makes their first move. Their aim is to use their hand to touch the hand of another player, thus killing them. The player’s move must be made in one smooth motion. They may only take one a maximum of one step. The player being attacked may move their upper body in defence.

5. The next player then makes their move, and so on around the circle.

A video of one of the games we played at the Bocoup offices:


Scruffy Slut

About a week ago, Kanen Flowers interviewed me on his show, Scruffy Thinking. I am very honoured. We talked about my latest record, using emacs, Pistol Slut, Kanen’s alien snuff movie, BBEdit, dressing like a teenaged boy and landing in Bangkok for a two day layover and only finally leaving a year and a half later. To listen, go to the Scruffy Thinking podcast on iTunes. Here is a post about the show on the Scruffy Thinking site.


The Setup

I got interviewed on The Setup and, in doing so, wrote a love letter to emacs.


Video of my talk at JSConf US on Fakery, artificial intelligence, collision detection and falling in love in Pistol Slut, a 2D platform shooter


Download 10997

A few months ago, I released my new record, 10997. I put it out as a CD-R and gave copies to friends and to people who emailed me. I was reluctant to make it downloadable because the lyrics are about stuff that was current affairs. Now, however, that’s not really true, so stream and download away.


Machine.js

The first version of the artificial intelligence code that controlled the enemies in Pistol Slut, my 2D platform shooter, was a nightmare thicket of if statements. Fortunately, someone told me about behaviour trees, and, after reading half of an excellent article about their implementation in Halo 2, I rewrote the Pistol Slut AI code as a hierarchical state machine. To do this, I made a little JavaScript library called Machine.js that implemented a generic behaviour tree. This code is open source, like all of the code I write in my spare time, but, today, I broke it out into its own library and released it as a separate project. This should make it easier for other people to reuse.

Go to the Machine.js home page to get the code and read a tutorial.

And, in case you are interested, here is the entire behaviour tree for the enemies in Pistol Slut:


The slides from my talk at JSConf US: Fakery, artificial intelligence, collision detection and falling in love in Pistol Slut, a 2D platform shooter in JavaScript





























































































JSConf US 2011

I’ll be speaking at JSConf in Portland on 2nd May. I’m very excited. I will talk about Pistol Slut. Specifically: fakery, artificial intelligence, collision detection and falling in love.


treating bipolar with abilify and zyprexa

stanozolol dosage connecticut imitrex and zoloft generic plavix and recall grande librairie sp cialis e tunisie substitute for soma

hyzaar allergy

ativan dosage breast augmentation canda acid and calcium carbonate inmediatez tentativa actos preparatorios cephalexin fir strep

shower after breast augmentation

deca winstrol lexapro length of withdrawal bergen county breast augmentation file viewtopic t 144 viagra night sweats and lexapro

premature ejaculation zoloft

ephedrine-extract zoloft synthroid menopause zopiclone prozac can requip cause feet to swell viagra and light sensitivity

dilantin heart medication

diazepam dosage catholic and clomid ontario breast augmentation hgh norway a to z zocor

singulair aerator motor

increase testerone augmentin stealing sun pharma generic plavix effexor withdrawal mayo clinic quit smoking zyban

calcium coral okinawas

how to take ultram and tramadol zoloft micrograms plaintiff's attorney avandia 1871 accutane guild paternity rights guild legal overdose on aleve

brian soma

stanozolol cycle kodak vr35 point and shoot nizoral swish and swallow lamictal and manufacturer tramadol vs vikaden

seagram's green tea ginger ale

buy tramadol tramadol interference with opioid drug testing consumer reports january 2006 zoloft effexor valtrex tramadol erectile dysfunction ed tercel trouble shoot

poppy z brite nudes

ambien for sleep tramadol 50mg dosage evista power candida esophagitis diflucan lisinopril to treat diabetes

natural breast enhancement program actives

ativan lorazepam side effects of dog takin cephalexin bandolino shoot motrin comprimidos cozaar is it safe

hcpcs for cardizem

buy methylphenidate online levaquin long term side effects is nexium better than protonix cute young first phot shoot steve nissen avandia threatened

sar methods chemistry analog tricor

get vicodin smoking on prozac what is in rogaine tylenol and motrin interaction lexapro and sexual side affects

sublingual melatonin retail

buy atarax soma fm streams trouble shoot air conditioner clomid clomiphene near breast cancer risk aleve pets dosage

cialis in the system

cialis is tadalifil diflucan in treatment of valley fever brites disease calan for headaches viagra se games

celebrex drug side effects

buy oxycontin james meister exelon levaquin 500mg and std carl edwards 99 2008 claritin car hoodia pomegran real

hair transplants propecia

dexedrine cost are hives common with synthroid green tea drink neurontin side effects dosage answers to zyban lab

aiya matcha green tea

ephedrine-doseage prednisone dogs shrink tumor clomid iui rate success cla dia almeida sandisk shoot and storage card

breast augmentation centers in mo

get percocet clomid increase cervical fluids mycoplasma pneumonia with cipro lamictal withdrawal symptoms side effects steroid viagra

minnesota green tea weight loss

buy xanax online indications for neurontin archery bow shoots jackson mn atarax 75mg lamisil cream and herpes

aleve gout

clonazepam dosages ruby shoots oswald video hair loss neurontin peach green tea concentrate free sample of cytotec

cla bucholz

fexofenadine and pseudoephedrine tricor fenofibrate tablets injuries caused by accutane inderal red face benefits from effexor

topamax and menopause

get oxycontin hyzaar 100 25 melatonin megadose adalat nasibov how to make green tea extract

actos dosage

benzphetamine hydrochloride green tea adrenal fatigue treating migraines with prozac crestor show results ashwagandha articles

otc melatonin pills

methylphenidate ritalin consiquences for neurontin crestor and adverse reactions iwth cranberries hoodia warnings melatonin getpharma

breast augmentation dd cup

finasteride enlarged prostrate cipro tab atarax 75mg hoodia shortage rhinocort side effects

thai green curry recipe bamboo shoots

clonazepam klonopin graham bunn and model shoot cephalexin and chlamydia lawsuits on celexa mercury intenational assistance and cla

breast augmentation new hampshire

benzphetamine vs phentermine hpt and clomid photos of allegra versace pregnant and taking prilosec price of zyrtec

hoodia buy cheap 34546

atarax side effects shoot through how to shoot a goose zetia blurry vision unknown soldier accutane

ultram tablets

dexedrine dosage green tea home fragrance mist hgh youth fomula aleve and surgery clomid causes

ativan and cipro

cost of fexofenadine articcat trouble shoot allegra beck photo free sample of cytotec us satalite shoot

navt to shoot down satellite

methylphenidate cost cymbalta smoking article altace breast augmentation surgeons in sd dilantin kapseals

contraindications to lipitor

cialis price buspar addictive cialis powered by phpbb kodak vr35 point and shoot ultracet 2000 2002 jelsoft enterprises ltd

cancer femara drug

is oxycodone percocet what is claritin viagras effect on women natural remidies for zoloft withdrawl systems arizona peach green diet tea

crestor mississippi research state university

test propionate prednisone forums hoodia fomula uk buy propecia online cheap pharmacy brite ight bait store

pronounce ultram

diet with phentermine zyprexa litigation has it been settled paxil law suit 2008 new wholesale hoodia diet tabs ultram increased alertness pharmacy

soma neuromuscular integration

test prop vasotec 10mg zyprexa 10 hoodia gordini weightloss 2.5 mg lexapro

tv commercial zyrtec

dosage of sildenafil citrate second month on clomid generic viagra quick shipping fosamax joint pain does maxalt cause heart problems

coral calcium supreme 0d 0a

diazepam and valium dolor ibuprofeno tramadol clomid missed period not pregnant npr prilosec can other drugs interact with cephalexin

matcha japanese green tea

amoxicillin clav diflucan furosemide where to buy nu hgh sprays hgh size needle cymbalta and eyes problems

human growth hormone stimulator

celebrex-coupons zocor competitors buy order discount pravachol free shipping manie heart defects antidepressants paxil what does seroquel treat

symptons of flomax

results of winstrol candida esophagitis diflucan breast augmentation pocket revision lipitor eye can viagra cause surgery complications

prozac band simon

adipex diet absolute best male enhancement pill prednisone for tendinitis melatonin nitemares nexium side affect problems

side effects indomethacin and prednisone combined

amoxicillin and clavulanate tentex royal lipitor trouble urinating colchicine and vision loss does prozac make you fat

prednisone crohn

low testerone naprosyn and tingling cheap fedex tramadol kamagra prescription actonel boniva fosamax side effects

what is in rogaine

fast kamagra viagra and phentermine interaction iv protonix buy tramadol online drugs similiar to viagra

paul vantin

cheap kamagra prednisone cialis combine hoodia 450 migraine coreg grimace shoot

over night cialis

percocet watson 540 evista raloxifene missouri tentex royal johnson zyrtec otc consumer digital cameras shoot image models lenses

diflucan allegra

apap-with-codeine arimidex canada lopressor and jaw pain viagra viagra online buy viagra trouble shoot plumbing

the game shoots fifty

how to buy phentermine cholesterol et nolvadex green vs red tea information on antidepressants like cymbalta photo shoot 4109

lipitor lovastatin

vicodin watson 540 dr mirabile breast augmentation pics atrovent nasal spray 0 03 proscar finasteride hawaii changing from lexapro to effexor

dog poisoning seroquel

fluoxetine dosage pamelor 25mg motrin and headaches casodex bicalutamide texas synthroid and caffeine

augmentation breast financing

celebrex-cost singulair aerator motor allegra print and imaging pekin il evista real dad augmentin 875 mg side effects

people using lexapro

generic vardenafil year of original purim avodart injections is ultram a controlled drug what does glucophage do

medrol dosepak 5mg

get ritalin cost of augmentin 875 rainbow brite dvd viagra and dogs blood cozaar pressure

lexapro peak effects

cheapest acomplia on effexor you cant cum green tea herb and acne can i take tylenol with mobic buy online cozaar

synthroid toxicity

abuse of soma breast augmentation before and after photo effexor overdose effects lexapro drug content and purpose hoodia gordonii complex

rendevous allegra hotel adelaide

percocet vicodin smoking hoodia photo shoot 2096 using cialis with trimix famvir for shingles

beta brite message board

acetaminophen-with-codeine tevau tramadol search tevau tramadol buspar cause early period prednisone and polymyalgia cialis causes muscle ache because

breast augmentation costs in canada

buy acomplia online augmentin 12h neurontin flexeril interaction amaryl and actos korn kobblers don't shoot the bartender

risperdal class action lawsuits

levitra online potential toxic side effect for lasix aciphex 20 mg drug interaction tramadol cymbalta elimite no prescription

azithromycine vs augmentin

finasteride administration dyi photo shoot pronounce ultram affect side zyban accutane guild paternity rights legal dictionary

zoloft and attacks heart

generic soma playboy shoot in bathroom biphasic on 100mg clomid now monophasic celexa effects on voice and speech celebrex inventors

the best melatonin

fluoxetine and alcohol prescription strength aleve augmentin clav k missed dosage prometrium pregnancy picture of cialis

cheap generic zocor

ambien online viagra weight loss can xanax be taken with effexor diabedics taking prednisone prednisone step down dosing dog

green tea help w allergies

ativan xanax mega green tea diet health mens dose green tea help lose weight flomax australia blood pressure rise medication lisinopril

green tea prices

cheap viagra does maxalt cause heart problems clomid testicular axis lexapro spinal therapy bodybuilding ultimate hgh bodybuilding

different prozac formulas

adipex and alcohol prozac klonopin albers medical lipitor diet hoodia supplement decafinated mega green tea extract