Skip to content

9 · Onto hardware

The show you just built is finished. Nothing about it needs to change to run on hardware — that was the point of building it this way.

The Studio is the engine compiled to WebAssembly. The same show_loader, the same effect tree, the same statechart, the same expression evaluator. A show that runs in your tab runs on the board, and the file is byte-for-byte the same one.

What the browser cannot give you is the hardware itself: real pins, a real panel, real current through real LEDs. So the things worth checking on the bench are the things the browser was never simulating.

The board. "board": "t-display-s3" is what lets the Studio validate your pins. Point it at whatever you actually have:

The pins. "pin": 16 on the barrel and "pin": 14 / "pin": 0 on the two inputs are this board’s house wiring. Change them and the Live tab’s pinout diagram tells you immediately whether the new ones exist, are output-capable, and are not already claimed.

The screen size. "width": 320, "height": 170 is the T-Display-S3 panel. A different panel means different numbers — and the HUD’s coordinates were all written against those, so the reticle centre (x: 215, y: 85) and the annunciator row move with it. This is the one part of the show that is genuinely resolution-dependent.

The audio pins, if you are fitting a speaker. Those belong in config.json rather than the show, because they are a property of the unit and not of the performance.

brightness. 160 is comfortable on a bench and bright enough to be seen under stage lighting. It is also current: eight WS2812s at full white are about half an amp. Check what your board can source before you raise it.

There are two ways to run a show on a device, and which one you have depends on how the board was flashed:

The short version for a standalone board: Project ▸ Save as… to get show.json out of the Studio, then open the board’s own editor — which is this same page, served from the device — and save it there.

Once there is more than a show file, keep them together:

my-blaster/
show.json the show you just built
config.json this unit's settings: wifi, hostname, audio pins
sounds/ .wav and .mp3 clips that `play` names
fonts/ baked .rfxfont files, if you want something other than 8x8
images/ .bmp / .rgb565 stills for `image`

Project ▸ Open folder… opens the whole thing, so every asset the show names is present and Save writes back into it. Opening only the .json leaves every sound and font missing, and you will spend a while wondering why play does nothing.

When the device disagrees with the browser

Section titled “When the device disagrees with the browser”
  • A show the device refuses is a show that keeps running the old one. The engine validates before it swaps, so a bad edit cannot brick a prop in the field. The reason is written to show.log, and the Console tab shows it.
  • Colours look wrong. Almost always order — GRB versus RGB. The browser cannot know what your LEDs expect, so this is the classic thing that is right in the Studio and wrong in your hand.
  • The screen is rotated or clipped. rotation on the screen device, and width/height set to match it.
  • Buttons do nothing. Check activeLow and pull against how the button is actually wired, then check that the current state handles that event at all.
  • Everything is slower than the preview. A per-pixel paint over a large panel is real arithmetic on a microcontroller. coarse renders it in blocks — coarse: 4 is 16× fewer evaluations — and is the difference between a smooth shader and dropped button presses.

The blaster used about half the engine. Still waiting:

  • paint — a per-pixel expression over the whole screen. One line, and the panel becomes a shader.
  • Sensors — an accelerometer or a range finder declared as data, publishing vars your expressions already know how to read. A blaster that reacts to being raised is a sensors block away.
  • Multi-device — emit with "scope": "peers" sends an event to other props over the radio. Two blasters that answer each other need no new concepts, only that one word.
  • Servos and steppers — move drives them the way set drives an LED.

That is the series. You built a prop without a compiler, and the file you finished with is the file the hardware runs.