Developers

Characters: your own face for the robot

A character replaces the robot's eyes. Not the idle screen, the whole face: waking, listening, thinking, speaking, going drowsy, falling asleep. The app behaves exactly as it always does. Only the drawing is yours.

{ "mode": "face", "minAppBuild": 26 }

A character needs no permissions at all. It sees no camera, no microphone, no data. It is given what the robot is doing, and it draws.

The whole contract is one event

hairobo.on('state', (s) => {
  draw(s);
});
state idle, drowsy, sleeping, listening, thinking, speaking, smile, happy, tracking, error
mood calm, happy, curious, thinking, sad, excited
gazeX, gazeY −1…1. Where the eyes would look, so your character can follow the person.
idleSeconds since the person last did anything
docked the phone is on the robot
dimmed the screen is dimmed because nobody is there

It arrives on every change and once a second, so subscribing late is fine, and idleSeconds keeps ticking while nothing else happens.

Match the built-in timing unless you have a reason not to: the eyes go drowsy at 45 seconds and asleep at 70.

What the app keeps

The app still draws the listening indicator, the captions, the settings button and the dock badge, on top of you. A character cannot hide or fake them. That is what makes it safe to let a stranger's code be the face.

Your page takes no touches. Tapping the face talks to the robot and a long press opens Settings, both of which belong to the app. Build the character to be watched, not tapped.

You will be taken off screen during games and camera routines, which draw their own screen, and in deep idle, which stops drawing entirely for battery. Do not depend on running continuously.

Speaking and moving

A character may also have manners. With voice it can greet someone; with motor it can nod or turn the head. Both are ordinary permissions, declared in the manifest and approved by the user at install, and the app keeps the motor limits and the speaking rate limit.

Use them sparingly. A face that talks every time it is looked at is charming once and exhausting by the afternoon.

Battery, because a face runs all day

  • Stop drawing when the page is hidden: if (document.hidden) return;
  • Then redraw when it comes back. A hidden page gets no animation frames at all, so nothing redraws it and the last frame you painted is what the user sees on return. The example hit exactly this: it fell asleep, the page was hidden, the state changed, and the sleeping marks were still on screen afterwards. Listen for visibilitychange and ask for one frame when the page is visible again.
  • Animate with requestAnimationFrame, never a busy loop.
  • Do not redraw a still frame. If nothing changed, draw nothing.
  • Keep it to a few shapes. This runs for hours on a phone that is also listening, tracking a face and driving motors.

Anything that stutters or overheats is dropped back to the built-in eyes and can be suspended remotely, without an app update.

Review

On top of the normal checks, a character is looked at for:

  • Flashing and strobing. This is a screen people sit in front of all day. Nothing that pulses hard at a few times a second.
  • Battery over a long idle run.
  • Nothing that imitates the app's own interface, its permission prompts, or the listening indicator.

Try it

character/ in this kit is the example that ships inside the app, called Pip: two eyes, a mouth, and about a hundred lines. Copy it, change the drawing, keep the event handler.

On the phone: Settings, then Plugins, then tap your character in the list. Tap it again to go back to the built-in eyes.

← Previous The hairobo API Next → Commands
Preorder Deskmate dock

Reserve your dock.

Drop your details and we'll email you the moment it ships, with early-bird pricing.