Smell
How a student smells a sample. Unlike the microscope or magnifying glass — where a lab object is the instrument and a gesture moves it — smell has no instrument: the camera close-in is the affordance, and a short authored line on the widget bar carries the description. The student reads, presses Continue, the camera and widget return to baseline.
A · The conceptual model
Smell breaks the lab-object pattern that microscope and magnifying glass follow. There is no "smell instrument" on the desk — nose, nostril, sniffer — because there's nothing to model. The chemistry of olfaction is not in Unity, not in the simulation backend, and not on a teacher's roadmap. The author writes what the sample smells like directly, and the kit treats that line as the user-facing copy.
Mechanically, smell is a step decoration rather than an interaction. The same step that composes a close-in camera framing also mounts a chrome-copy widget on the widget bar; the widget's body is the smell line. The student's only action is to press Continue when ready — the camera close-in is the visual cue ("this sample is in your face, take it in"), and the widget bar carries the verbal payload.
This makes smell the simplest of the observation surfaces by some distance: no new lab object, no new operation, no new gesture, no telemetry binding, no PiP panel. Two existing step-level keys (camera_ui: and widget:) plus one new key (widget_text:) compose the entire feature.
B · What the student does
-
1
The step begins; the camera closes in on the sample.
At step entry the kit lerps the camera to a
phenomenonframing on the named sample — close on a single science object with no meter in frame. This is the only "this is what you smell" visual cue: the camera puts the sample in the student's face. -
2
The widget bar mounts with the smell description.
On the same step entry, the kit's
WidgetBinderreads the step'swidget: text+widget_label:+widget_text:and mounts<lab-widget-text>on the widget bar. Two author-controlled fields: the eyebrow (the "measurement type" —"Smell"in this case; would be"Taste"or"Sound"elsewhere) and the body (the description, capped at 200 characters, wraps to two lines inside the fixed 56 px bar height). -
3
The student reads, then presses Continue.
No gesture, no widget interaction — the student's only action is to advance the step. The Continue button (or the wrapper's next-step affordance) commits; the kit fires
orchestrator-step-changed; the binder unmounts the widget; the camera lerps back to whatever the next step's framing asks for.If the next step has no
widget:or nocamera_ui:, the widget bar empties and the camera returns to the persistent orbit baseline. The smell line is gone — there is no "smell history" or "re-sniff" affordance. A second sniff on the same sample is just another step with the samewidget_text:.
C · How the author writes it
One step. Two existing decoration keys (camera_ui: + widget:) plus two per-step body keys (widget_label: for the measurement type and widget_text: for the description). No pip:, no operation: on a smell-specific surface — smell rides the existing observe operation.
- step: 5
description: "Bring the beaker close and sniff the contents."
operation: observe
duration: 4
ui: button
camera_ui:
role: phenomenon
object: beaker_vinegar
widget: text
widget_label: "Smell"
widget_text: "Sharp, vinegary smell — pungent acid bite."
Why two fields, not one
The dev-team framing: measurement type (widget_label: — Smell, Taste, Sound) and measurement description (widget_text: — the prose). One widget renders any sensory observation; the author picks the type per step. v1 had only widget_text: and a hard-coded "Smell" eyebrow in the binder — that hard-coding is gone (v1.5). Substance-level resolution (both fields pulled from the focused instance's contents) is the Phase D direction; for now both fields are author-controlled per step.
Why camera_ui: and not zoom_in:
zoom_in: and its yellow zoom-in button are product-deprecated. The close-framing semantic is preserved by attaching the same role: phenomenon recipe to camera_ui:, which auto-fires on step entry — the camera closes in as the student reaches the sniff step rather than waiting for an extra button press, which is the pedagogically correct moment for an olfactory cue.
What the author does not write
- no instrumentThere is no smell-instrument lab object on the desk. The sample's own close-up is the surface.
- no gestureNo
ui: drag/click_target/preset. The step is observe + button; the student reads and advances. - no
pip:Smell is chrome copy on the widget bar, not picture-in-picture content. No PiP panel mounts. - no telemetry bindingNo
widget_telemetry:. The widget is a control entry in the telemetry registry — never auto-matched, only mounted via the explicitwidget: texton the step.