Skip to content

WS4: recognition robust to tracking noise, zero false triggers, settings apply at once - #6

Merged
karanheart96 merged 1 commit into
competition-hardening-ws3-cold-startfrom
competition-hardening-ws4-recognition
Nov 11, 2026
Merged

karanheart96 merged 1 commit into
competition-hardening-ws3-cold-startfrom
competition-hardening-ws4-recognition

Conversation

@karanheart96

Copy link
Copy Markdown
Contributor

Workstream 4 (P0): recognition accuracy and false triggers

Stacked on WS3 (#5); retargets when it merges.

1. Baseline (recognition lab, in-app pipeline, hold 0.5 s)

Crocodile 60%; all other shapes 100%. Negatives (resting / half-closed hands): 14 false triggers (cup 8, fist 5, dog 1); 70% of negative frames matched some shape. The silhouette method is idle (0%): public/silhouettes/templates.json has no templates until some are recorded on a device.

2. Gating

Confirmed: in the story only the requested shape and its listed alternative count; Free Stage accepts every creature (never cup or fist). Now tested directly (sweep section 5) because the gate lives in src/recognition-rules.ts.

3-4. Fixes, measured with Quest-like noise

New sweep conditions: clean, ±5 mm joint jitter, an occluded finger (jittering ±12 mm or frozen at a resting curl), both; plus 3 s sequences at 72 Hz with 100 ms dropouts.

Before After
Fish (worst condition) 38% 95%+
Swan 53% 100%
Crocodile 8% 98%
Cup (two hands, occluded finger) n/a 95%
All one-hand shapes, all conditions 38-100% 95-100%
Negatives accepted as cup 47% of frames 0.1%
False triggers (320 negative sequences x requests) 197 0
Lab: false triggers on story shapes cup 8, dog 1 0 (5 'fist', never accepted anywhere)

How: joint positions smoothed for recognition only (alpha 0.35, ~26 ms; shadows keep raw joints); templates recalibrated to measured values; a resting-hand reject template; cup needs a closer match; bird/deer need straight fingers and thumbs not bent across; crocodile drops the noisy spread rule; cupped hands need one clear cup plus one cup-like hand.

5. Settings and hints

  • Bug fixed: the assist ladder used to save and restore the player's tolerance, so a Tolerance change mid-request was overwritten or reverted. It now writes its own assistTolerance; verified in the emulator (Forgiving applied at once and kept after the request).
  • One-hand mode already applied the same frame.
  • Nudges: "Almost! Hold it still..." / "Bring your hand into the lamplight." after ~1.2 s near-miss, lingering 1.5 s, never in Free Stage.

Tests

npm test (sweep: all targets met; 17 server; 3 unit) and npm run build pass. Lab after: crocodile 100%, story-shape false triggers 0. Regressions: playtest (perfect, small, shaky, wrong) and live-family pass; a 'wrong' persona result that looked early was traced frame by frame: no false trigger.

Options considered

  • A more robust 'touch' (including the index tip): rejected, resting hands also come close to the curled index.
  • Trimmed scoring (ignore the worst feature): rejected, it lets resting hands pass as cups.
  • Keeping cup one-hand acceptance (as today) rather than requiring two hands: kept, it is the accessible behaviour and false triggers are now 0.

Needs a device

Real-hand accuracy per shape and light (DEVICE-TEST B1-B14), the nudges (B12-B13), cupped hands with overlapping fingers (B14), and optional silhouette templates.

🤖 Generated with Claude Code

…apply at once

Measured first: the recognition lab (in-app pipeline) showed crocodile at
60% and 14 false triggers on resting hands (cup 8, fist 5, dog 1); a new
sweep with Quest-like noise (+/-5 mm joint jitter, an occluded finger,
100 ms dropouts) showed fish 38-63%, swan 53%, crocodile 8-48%, and 197
false triggers.

- Joint positions are smoothed for recognition only (alpha 0.35 at 72 Hz,
  ~26 ms): jitter is zero-mean in position but biases the angle features
  (a jittery straight finger looks bent). Shadows keep the raw joints.
- Templates recalibrated to what each shape measures through that
  pipeline; spread (the noisiest feature) carries little weight; cup leans
  on finger curl and a curled-in thumb and needs a closer match (0.88 at
  Normal); a 'resting hand' template makes relaxed hands count as nothing.
- Two-hand rules: open hands for bird and deer need straight fingers and
  thumbs not bent across (rules out an OK sign); the crocodile drops the
  spread rule; cupped hands need one clear cup and one cup-like hand.
- The request gate, pair rules and hold timer live in recognition-rules.ts
  (pure) and the sweep tests exactly that code.

Result (sweep, all conditions): one-hand shapes 95-100%, two-hand 95-100%,
every shape triggers over time (~0.5 s), 0 false triggers in 320 negative
sequences, negatives accepted as cup 0.1% of frames. Lab: crocodile 100%,
false triggers only 'fist' (never accepted by any story or Free Stage).

Settings: the story's assist ladder now writes its own assistTolerance,
added by the matcher to the player's setting, so changing Tolerance takes
effect at once and is no longer overwritten or reverted mid-request.

Nudges: when a requested shape is nearly there for ~1 s, a small pill above
the caption says 'Almost! Hold it still...' or 'Bring your hand into the
lamplight.'

Tools: scripts/recognition/lab-run.mjs runs the in-app lab headless and
reports per-shape accuracy and false triggers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@karanheart96
karanheart96 merged commit e815dd6 into competition-hardening-ws3-cold-start Nov 11, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant