Form feedback
How form cues you author in the Studio flow through to the consumer app’s UX.
What you author
Every condition row in the Conditions panel has an optional cue editor:
- Cue text: short string the host UI surfaces.
- Trigger:
onViolation(default),onCompliance, oralways. - Severity:
info/warning/error.
Leave the cue text blank and the condition still gates the phase transition + contributes to the form score, just without an explicit message.
What happens at runtime
When the form service evaluates a rule and its trigger fires, the
tracker emits a FormFeedbackEvent on onFeedback:
class FormFeedbackEvent { final String ruleId; final String trackingPoint; final double currentValue; final String message; // your authored cue text final FormRuleSeverity severity; final FeedbackTrigger trigger; final String? audioCue; final String? hapticPattern;}The host UI subscribes to that stream and decides what to do , toast, audio cue, haptic burst, score badge, post-rep summary.
In the Studio test player
The Studio surfaces feedback as a toast deck at the top of the camera view (just below the top bar). Each event renders as a short pill with the cue text, an icon for the severity, and an auto-dismiss timer (~2.8s). At most 3 toasts stack at once; newest pushes oldest off.
Colour signals severity:
error→ redwarning→ amberinfo→ blue (primary tint)
Filtering during authoring
While testing in the Studio, you can filter the toast deck:
- Open the Overlays panel.
- Find the Form feedback section.
- Show feedback toasts master switch + per-severity filter chips.
Hide info if you only want to see real issues during testing.
Turn the master switch off entirely when you just want to verify
rep counts.
This is a Studio-side display filter only, it doesn’t change
what the .pose file emits at runtime in the consumer app.
Throttling
The form service throttles rapid-fire events. A rule won’t re-fire within 800ms of its last event for the same trigger. So a wobbly knee during the down phase doesn’t generate 20 cues per second.
Authoring tips
- Use
onViolationfor corrective cues: “Don’t let your knees collapse inward.” - Use
onCompliancefor positive reinforcement: “Great depth!”. Sparingly, too much praise becomes noise. - Reserve
errorseverity for catastrophic form: knee buckling under load, back rounding hard.warningis the right default for most cues. - Use
infofor measurement readouts: “Stance: 0.45”. Triggeralways+ severityinfogives the host a stream of values to render as a chart or live label without alarming the user. - Keep cue text under 40 chars: the toast renders on one line; longer text truncates.
Audio + haptic cues
The FormFeedback payload optionally carries audioCue and
hapticPattern strings. These are asset reference identifiers
that the host resolves, the Studio doesn’t bundle audio or
haptic assets.
A typical wiring:
tracker.onFeedback.listen((event) { // Toast showToast(event.message, severity: event.severity);
// Audio cue if (event.audioCue != null) { audioPlayer.play(event.audioCue); }
// Haptic if (event.hapticPattern != null) { haptics.play(event.hapticPattern); }});The Studio doesn’t currently expose audio/haptic fields in the cue
editor, they ship in the .pose file when authored
programmatically (via the converter script’s preset mapping or by
hand). A future Studio release will add them to the cue editor.
Per-bucket cues
When you author bucket-specific bands (see camera buckets), the same condition can fire different cues per bucket implicitly because the bands are different. The cue TEXT stays the same across buckets, the cue fires whenever the bucket-appropriate band is violated.
If you need different cue text per bucket, author multiple
conditions with the same channel + different appliesToPhase
scopes that map to different bucket-overrides. Rare in practice.
Suppressing form at the host level
Some UXs render only the rep count and intentionally hide form feedback, competitive flows, headless scoring backends, minimalist in-game overlays. The tracker still emits every form event for the loaded movement; your host code just ignores them.
This is a host-side UX policy, not a Studio-side concern. Studio always emits the form rules, it’s up to the host whether to surface them.
Read next
- Conditions, author the cues.
- Form analysis concepts, what the form service does.
FormRulemodel.FormFeedbackEventmodel.