Why
Mr. Graham asked for a die that picks which track to practice. Rather than baking a die into each practice item, we want one shared die for the whole practice page, "gotten out" when a practice item calls for it. Each practice item then customizes what each side/number of the die represents.
This generalizes the two dice ideas we currently have:
- Today's
dice: boolean shows a rhythm die (src/app/DiceRoller.tsx + data/dice-rhythms.json: 🍕 pepperoni rhythm, 🍦 ice-cream rhythm) — a face means a rhythm to play in.
- The new request is a face meaning which track to play.
Both become the same thing: a practice item declares N faces and what each face does.
Depends on
- Decoupling practice item from a single track (separate issue) — needed for faces that map to tracks, since the item must reference a pool of tracks.
Scope
- One page-level die component, shared across the practice page (single instance), summoned when an item needs it — replaces the per-item
DiceRoller baked into each row.
- Per-practice-item face configuration: for each item that uses the die, the teacher defines what each side/number represents. A face can map to:
- a track (from the item's track pool) — roll picks the track to practice, OR
- a rhythm (the existing 🍕 / 🍦 style) — preserves today's behavior.
- Roll → reveal the chosen face's meaning → render the corresponding track/rhythm + the item's shared tasks.
- Editor support (
PlanEditor) for defining an item's faces.
- Replace/retire the overloaded
dice: boolean flag in favor of the per-item face config.
Open questions (for design)
- Number of faces: tie to a real d6, or N = number of choices? (Virtual die can be any N.)
- Re-roll vs roll-once-per-session.
- How face config is stored per item (e.g.
faces: { face: number; kind: "track" | "rhythm"; ref: string }[]).
Why
Mr. Graham asked for a die that picks which track to practice. Rather than baking a die into each practice item, we want one shared die for the whole practice page, "gotten out" when a practice item calls for it. Each practice item then customizes what each side/number of the die represents.
This generalizes the two dice ideas we currently have:
dice: booleanshows a rhythm die (src/app/DiceRoller.tsx+data/dice-rhythms.json: 🍕 pepperoni rhythm, 🍦 ice-cream rhythm) — a face means a rhythm to play in.Both become the same thing: a practice item declares N faces and what each face does.
Depends on
Scope
DiceRollerbaked into each row.PlanEditor) for defining an item's faces.dice: booleanflag in favor of the per-item face config.Open questions (for design)
faces: { face: number; kind: "track" | "rhythm"; ref: string }[]).