This is a submission for the Presage SmartSpectra SDK Challenge

What I Built

Body Radar is a desktop game about how well you know your own body. You guess first, then a webcam shows you what it measured.

Round 1 is a 30-second breath tap. You look away from the screen and press Space at the top of each inhale. Afterward a ring replays your taps in magenta against the inhale peaks the camera found in blue, and tells you how many you caught and whether you tend to tap early or late. Round 2 asks you to guess your pulse with a slider. You lock it in, and the camera shows what it measured.

A small robot called Pip sits beside the ring and reacts to how you did. The game runs in Electron on the Presage SmartSpectra SDK. It gives no medical readings.

Body Radar's Round 1 result: six magenta taps sit beside six blue inhale peaks on a ring, with Pip cheering in the corner

Code

Github URL

The README has the full setup. You need Node.js 20 or newer and a SmartSpectra API key:

npm install SMARTSPECTRA_API_KEY=your_key npm start 

For Practice mode, run npm run build:renderer once and open renderer/index.html in a browser.

How It Responds to Human Signals

Two Presage signals drive the game. Round 1 uses the breathing trace (breathing.upperTrace) and Round 2 uses pulse rate (cardio.pulseRate). The SDK's validation status runs alongside both and tells the app when the signal is poor. The app also requests the breathing rate metric, which the game does not show yet.

The camera is read live during a round, and the game hides the result on purpose until you have committed. In Round 1 the trace arrives while you tap, and the ring replays it when the 30 seconds end. In Round 2 a progress bar fills as each stable pulse reading arrives. The app waits for at least 8 readings (no sooner than 8 seconds, no later than 60), drops the first quarter while the estimate settles, and takes the median. If the SDK reports a problem such as too little light or too much motion, the status chip changes right away and Pip's caption says what to fix.

Diagram: camera preview feeds the SmartSpectra SDK, which outputs a breathing trace, pulse rate and validation status that drive the Round 1 ring, the Round 2 reveal and the on-screen hints

How I integrated the SDK:

  1. The SDK runs in the Electron renderer. Its renderer entry is CommonJS, so I bundle it with esbuild.
  2. The setup screen opens the preview with getUserMedia and hands the same stream to the SDK with useMediaStream. Only one camera stream is open, and you can see it.
  3. The SDK is created with the three metrics I use and with telemetry off:
sdk = new SmartSpectraSDK({ apiKey: config.apiKey, requestedMetrics: [MetricType.CHEST_BREATHING, MetricType.BREATHING_RATE, MetricType.PULSE_RATE], enableTelemetry: false, }); sdk.useMediaStream(stream); await sdk.start(); 
  1. metrics events go through decodeMetrics. Breathing trace timestamps arrive in microseconds, and I map them onto the wall clock so your taps and the peaks share one timeline. Pulse readings count only when the SDK marks them stable.
  2. validationStatus codes map to short hints such as "Too dark. Turn toward a light."
  3. When the window closes, the app stops and destroys the SDK and releases the camera stream.

A few things went wrong on the way. The SDK takes integer MetricType codes, and my first version passed strings. It also ran the SDK in the main process while the preview opened the same camera again, so two things competed for one device. Moving the SDK into the renderer with a shared stream fixed that. My first setup check looked for skin color to find a face, which could block people with darker skin or tinted lighting, so I replaced it with a check on brightness and movement and let the SDK report face position. And a fixed 10-second pulse timer was too short for some people, which is why Round 2 now waits for stable readings.

Prize Categories

I'm entering Most Creative or Delightful Use.

Most body-sensing demos show you a number. I wanted to ask what you think first, because the gap between your guess and the measurement is where the game happens. You see it on a single ring, with your magenta taps next to the blue peaks the camera found.

Pip makes it friendlier to be wrong. The app has light and dark themes and reduced-motion support, and it uses the Atkinson Hyperlegible font. Round 1 plays from the keyboard with Space.

Pip the robot mascot in five poses: waving, holding a magnifying glass, breathing with eyes closed, smiling, and cheering

Round 2 result: the camera measured 63 beats per minute and the guess of 79 was 16 beats high

Consent and Data Handling

The opening screen explains what the app reads and what it does not store before the camera turns on

  • Consent: the opening screen explains what the app reads before anything starts. The camera turns on when you press Turn on preview, and the SDK begins processing only after you press Start camera. The preview stays in the window the whole time, and only the app's own page is allowed to use the camera.
  • Storage: none. There are no files, accounts, database or analytics. Results live in memory until you close the window.
  • Sharing: Body Radar sends no video or results anywhere. The SmartSpectra SDK contacts Presage to check the API key.
  • SDK telemetry: off (enableTelemetry: false). Per the SDK docs, telemetry never includes video frames or vital signs.
  • Retention and deletion: the app keeps nothing, and closing the window clears the results.
  • AI services: none.
  • The API key is read from an environment variable and held in memory.
  • Where the SDK processes video frames: I make no claim about that. Presage's SDK documentation covers it.

Body Radar makes no diagnosis, suggests no treatment and supports no medical decision. It runs only when you start it, and the camera preview is always visible while it does.

Agent Session

I used AI coding assistants for parts of this build, mostly to review my code against the SDK's typings and to draft fixes that I then tested on my own camera.