Doug

He is a cube with a face, he lives in the corner, and he watches your pointer. This is the page about why that took a while.

-2°
12°
18°
24°

The same face at five head yaws. Nothing else changes across the row: the eyes and the mouth are identical in all five, so it is a turn rather than five moods. The angles are one-sided because he is: standing in the left corner, the far edge of a 1440px screen is 22.6 degrees to his right and 1.4 to his left, so a symmetric row would have been three drawings nobody could ever see.

happyyou point at him
surprisedyou click him

He is a definition, not a drawing

Doug is a JSON file. His body, his eyes and the way he moves are parameters read by a renderer, so there is no artwork anywhere to open in an editor, and there are six of him: a sphere with feet, a cone, a speech bubble, a capsule with an antenna, a diamond, and the rounded cube on this page. The cube is called chip in the pack. He is on the site because the sphere ones looked like every other assistant mascot and the cube did not.

The first five versions were hand-rigged SVG, and each one could hold exactly the poses somebody had drawn by hand. Moving to a definition is what made 19 expressions and 13 animations possible without drawing 19 of anything, since the renderer gets head yaw, pitch and roll, surface-mounted eyes and blinking for free.

The cube and the diamond are the same shape

Both are superquadrics, which is one equation with an exponent on it. Below 2 you get the diamond, above 2 you get the cube, and at exactly 2 you get a sphere, so the two meet perfectly in the middle: at that value you can swap the label from diamond to cube and nothing on screen changes. The morph runs in plain SVG and needed no WebGL.

The one thing worth knowing if you ever build the slider: drive it by the exponent and not by roundness. The cube's roundness curve is steep enough at one end that most of the travel does nothing at all, which reads as a broken control rather than a subtle one.

The face was the hard part

The first Dougs got the note "looks like grok bot", and the reason turned out to be specific. All six had distinctive bodies and an identical face, and a symmetric pair of pale rounded rectangles on a solid shape is the genre signature. Every asymmetry had gone into feet, ears and antennae, which is where it reads least. The fix was six lines: the right eye is about 0.55 of the left one's height and 0.86 of its width. Expressions are multiplicative on the neutral pose, so those six lines propagate through all 19.

He also has a mouth, which the renderer does not support. A face there is two eyes on a surface and nothing else, so the mouth is a second pass through the eye pipeline: one "eye" is the mouth shape and the other is a body-coloured mask sitting over it. Mask on top gives a smile, mask below gives a frown, and no mask gives an open O. It costs about double to draw, since the second pass recomputes the same silhouette and throws it away.

Two failures worth recording. He looked like he had a tremor for a while, because the ambient motion seeds its noise from the pose's own head angles, and feeding it a pose that tracked the cursor reshuffled that seed every frame. Pinning the seed to the neutral pose took eye direction reversals from 116 frames out of 178 down to 6. And he looked depressed when he danced, which was not the dance: it was half-closed eyes with no mouth, which is ambiguous, plus a dance loop that dropped to a neutral face for a third of it.

What is on this page, and what is not

The renderer is AGPL-3.0. Serving it here would make this whole site a network-offered AGPL work, so it is not here. What ships instead is seven poses exported as flat SVG, which carry no engine code: five head turns and two reactions. He can follow your pointer because a turn is a pose, but he cannot morph into the diamond, he cannot blink, and the other expressions live in the lab where the licence does not reach the public.

Five positions is not a head turning, so the gap is covered by leaning his whole body toward the pointer on a transform. The pose gives the head its direction and the lean gives the movement somewhere continuous to live, which is what makes six drawings read as one head. The lean stops at about six degrees, since past that he is not looking at anything, he is falling over.

The tracking is sprung rather than direct, and that is the second time the same mistake has been made here. Pointer coordinates written straight onto head angles read as a tremor, not as attention, so the pointer sets a target and a spring chases it: a flick of the mouse turns his head over about a fifth of a second. The pose also refuses to change until the angle is 2.5 degrees past the boundary between two of them, because a pointer parked exactly between two poses would otherwise alternate every frame, which is the same twitch wearing a different hat.

His colour is two tokens rather than a palette. The body takes the site's accent and the face takes the paper, so on the light half he is #2F5D7E on cream and on the dark sections the same two tokens resolve to #79B8D8 on near-black. That reversal is not decoration: a dark-bodied Doug is invisible on a dark ground, and doing it with the tokens means he can only disappear if the section's own text disappears first.

What is left

The 19 expressions compile to 95 poses, but the ones between the authored poses are extrapolated from the two either side rather than drawn, so some of them are probably wrong and nobody has looked at all 95. Six live Dougs will not fit in a frame: a cube with a mouth costs 8 to 11 milliseconds to draw, so a gallery has to wake one at a time. And the decision about whether the engine ever ships, under what licence, has not been made.

The name tag is the only part of him that goes anywhere. Clicking Doug makes him jump.

Bring your last three experiments.

A conversation about your last three experiments and where the work gets stuck.