Tuesday, 3 August 2010

Making Of Dinosaurs

If you have $20 million dollars, here's how you'd go about making dinosaur costumes.









Friday, 30 July 2010

A Tale of Two Dinosaurs

As soon as I saw this video (below), I knew what I was going to try to do for Hallowe'en.



These are two of the smaller, one-person dinosaurs from the live-action Walking with Dinosaurs show. That reportedly had a R&D budget of $20 million, so there's no way I'm going to come up with anything as good as this.

What I'd really like to hit is the puppetry of them, which is masterful. To explain what I mean, compare with this video:



In some ways, this second dinosaur is better - the actor's legs and ass aren't hanging out, for one thing. But the movement is so unnatural that it's almost comical. The actor's hips cause the dinosaur's legs to bend mid-thigh, causing an unsightly wrinkle of rubber. The head and neck are so stiff they make batman look agile. The whole thing screams man in rubber suit.

But How?

The 'making of' videos are informative - actually jaw-dropping. From what I can tell, these suits are built as follows:
  1. There's a full-length structural skeleton, supported by a backpack-like harness worn by the actor.

  2. The skeleton is supplemented by a few rigid sections, like the ribcage and skull.

  3. The tail is segmented, made from concentric cross-sections of sturdy foam.

  4. The skeleton is augmented with "muscles". As with so-called 'fat suits', these are overlapping, muscle-shaped bags filled with polystyrene foam beads. As the skeleton moves, these muscles squash and bulge the way solid tissue would, preventing the skin from folding unnaturally.

  5. A highly textured skin is attached, in sections, and fastened on with Velcro.

Neckosaurus

I'm not worried about the legs - they're gorgeous pieces of art, but the basic principle is the same as the spider's legs. But the neck..

The head of this creature makes up so much of its personality. If you watch the video carefully, you can see there's tremendous range of motion - the neck can stick straight forward, be nearly right-angles to the body. The head can turn side to side, look up and down, and can even cock to one side like a curious dog.

All of this is amazing when you consider that all of this is happening well out of the actor's reach. What does the head control mechanism look like?

I'd designed something on a scratch pad, but I realized it wouldn't be nearly expressive enough. This is my current thinking:


The upper, diamond-shaped plate is in the head of the monster, and is the platform for building out the skull. Below, there's an identical plate. The two plates' orientations are locked together by a series of rigid rods, affixed with ball- or universal joints. This creates a sort of 'voodoo' mechanism - rotating the lower plate causes an identical rotation in the upper plate.

But.. I've never built anything like this mechanism. Looks to me like there would be tremendous stress on the spine-neck connection. Also, where do I get little ball joints like that? Can I solder copper pipes together, or would the solder just crack apart the first time I bark at an impudent kindergarten Spiderman?

Thursday, 29 July 2010

No Mad Rush

Well, at the risk of eating my words, I'm starting my very ambitious Hallowe'en costume early this year - very early. Last time it was a mad rush, so intense that in the last week I had to resort to an quick 'n' dirty project plan complete with time estimates, the cutting of low priority items, etc.

But this year, it's going to be smooth sailing. No all nighters for me, oh no. Nope. So I figured I'd start early.. like.. July. That gives me three months! What could go wrong?

Tuesday, 13 July 2010

The Value of Iteration

I stumbled on a simple thought experiment that nicely illustrates the value of iteration.

Imagine a well-intentioned but flawed device, perhaps a homely little robot, trying to navigate its way on a nighttime trip to the gas station for a midnight snack.


To do this, it navigates using the stars. Whenever it sets out, it takes a photo with its upwards-pointing telescopic web cam, then compares the result with an internal clock and a star map. Using this, it deduces where it is, and which direction it ought to speed off in.

Unfortunately, the web cam takes only grainy photographs. Not only this, sometimes the stars are partly occluded by overhanging trees, a plane inches across the frame, or the robot is totally unlucky and captures a street light.

As a result, half the time it draws the wrong conclusion entirely about which direction it should travel, and heads off in a completely random direction. It only picks the right direction of travel half the time.

With this level of accuracy, our robot's journey is fraught with danger. There's only a fifty percent chance it will reach its destination at all, and even if it makes it, it faces the same risk on the way back. The odds of a successful round trip are only one in four.

Iterate!

Accordingly, we make one tweak to the robot - instead of checking its starmap only at the beginning of each leg of the journey, it checks repeatedly, perhaps every five minutes. This is done in the crudest possible way: by jumping to the top of its simple little navigation program.

This one tweak has an amazing effect on its accuracy. Even though it has no memory, no ability to decide stay on course if it takes a bad photo, the robot's arrival is now a practical certainty.

Why is this?

Assuming the time between checks is small compared to the length of the journey, the refined robot will spend an average of half the time driving towards its target. The rest of the time will be spent travelling in a random direction.

Importantly, these random, off-target jaunts aren't all in the same wrong direction - they form a random walk.

Inevitable

Some of the time, the robot will be travelling in exactly the wrong direction, cancelling out whatever progress it has already made.

That will happen only rarely, however. Most of the time it will be off-target by a lesser degree. Even when it's headed almost directly away from its target, it will still be increasing the distance to its target at less than its full drive speed - a problem which is more than compensated for by the half of the time it does drive the right way. On average, it will simply be wasting time, heading perpendicular to the direction it should be.

Overall, the tweaked robot will make an average rate of progress of half its best speed, jigging and jogging this way and that, but heading inevitably towards the gas station. And they said that GOTO was considered harmful.

Thursday, 10 June 2010

Command-lines in games

Over at Emily Short's blog, she has an interesting post on whether interactive fiction games really need parsers.

One of the things that makes command-lines powerful in computer interfaces is the ability to chain together commands in novel ways (e.g. in Unix, listing files, and piping the results through a filter).

Guess-the-verb still exists (because nobody knows every possible command), but the user can (theoretically, at least) develop facility with all of them independently – anything can be filtered. There aren’t any special cases where the commands suddenly behave differently. All of the possible outcomes emerge naturally from combinations of commands.

The game-world analogue for this is a physical simulation – given a number of universally available options (walking, lifting things, letting things go, throwing things), and all outcomes emerge from combinations of these, in the context of the universal world rules (e.g. mass, gravity, the rigidity of objects, friction).

A given puzzle (e.g. press a button high up on a wall) might have many solutions – stack some boxes, throw a ball at it, etc., and perhaps only one or two of them were anticipated by the scenario author.

Once you get to a certain level of facility (e.g. you’re no longer trying to pick up the air, or ‘throw’ when you’re not holding anything), every sequence of actions does at least have an outcome. (Though you might not like it!)

In CDLIB (MUD software – I’m not sure how this compares with Inform), the situation is quite different.

While there are global verbs, like ‘north’ – many verbs are made available to the player by relevant objects. I can’t ‘smoke’ anything except a cigarette – I can’t ‘smoke twig’. (Unless I’m carrying a cigarette, in which case I might be told ‘You can’t smoke that.’) I can load my sling with pebbles, but not a stick of chalk.

Successful smoking and sling-loading are special cases, outcomes that were pre-planned. Many attempts to invoke these concepts result in no outcome at all.

Pocket interactive fiction occupies a very awkward position, to my mind. Immersion requires the promise that you could do anything, but specifying the flammability of every object in the game world is a crazy investment when all you want to do is let the player enjoy a post-coital toke in scene six.

One complicating factor is that a lot of the actions we wish to support in IF are very high-level. Smoking consists of numerous small actions (open packet, get cigarette from packet, put cigarette in lips (not mouth!), get match from matchbox, rub match on matchbox, touch cigarette with match, shake match).

Another complicating factor is the highly idiomatic nature of language – it only makes sense to ‘smoke’ a handful of things, but it’s immersion-breaking if we simplified and forced users to type ‘consume cigarette’.

So we resort to writing special cases needed to make the game go… but then we’re left repairing the immersion by writing endless witty no-outcome responses to unsupported actions like ‘smoke chalk’.

Thursday, 3 June 2010

Three Year-Old Magic

This morning at breakfast, my three year-old, Leah, performed an incomprehensible magic trick. She's holding her hands behind her back, waving them around, then she's shouting "Ta-Da"! I have no idea what was going on in her mind, but she seems pretty pleased.

"Honey, you need to explain what you're doing so people can understand your trick."

To demonstrate, I make a fist and hold it up. "There's a penny in my hand, and I'm going to make it disappear!" I hadn't anything in my jeans pockets, so I'm just pretending - my fist is empty. Maybe I'll get a laugh out of it.

Morgan, my six-year old, perks up.

"Show me the penny! There's no penny in there."

After years of my lame daddy-magic tricks with pennies, Morgan now questions every step of the way. There's no way she's going to believe there's a penny in there unless she sees it first.

"You're right, Morgan," I say, "there's no penny in my hand. See, Leah, people need to understand what you're doing and believe it, otherwise the trick doesn't work."

I'm not going to fool anyone, but now I'm in the mood so I continue with my impromptu routine.

"Look, Leah, I'll make it disappear!" I say, holding up my still unopened fist. "I'm going to squeeze it down to nothing!" Loosening my grip, I poke my finger in one side, then in the other, ostensibly pressing the penny down to dust-speck size.

"Now that it's too tiny to see, I'm going to blow it out like dust!" I hold my fist to my mouth, blow through it, then theatrically fan open my fingers, showing my empty hand.

"Where's the penny?" I ask.

Leah thinks for a second. She wasn't born yesterday. She's turning four in a week, she's been around the block a few times now. She's seen this sort of thing before.

"It's in your ear!" she exclaims!

Wednesday, 19 May 2010

Spring: Inject My Bean

A few weeks ago I was wondering how you get Spring to inject an existing bean that I'd instantiated myself.

I'm trying to integrate our JUnit concurrent test runner with Spring's SpringJUnit4ClassRunner, and while plumbing the depths of the relevant spring code, I came across this:


public void inject(ApplicationContext context, String beanName, Object bean, int autowiringMode) {
   AutowireCapableBeanFactory factory = context.getAutowireCapableBeanFactory();
   factory.autowireBeanProperties(bean, autowiringMode, false);
   factory.initializeBean(bean, "bean name");
}

inject(bean, "myBean", appContext, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME);

Simple!