# 7. Rhythm Game Pitfalls
Part of [[MIDI Rhythm Game]]. Prev: [[6. Latency Calibration and Worked Example]].
| Symptom | Cause | Fix |
|---|---|---|
| Notes stutter on the highway | Positions driven by raw `dspTime`, which moves in DSP blocks | Use `RhythmConductor.SongTime` (smoothed, monotonic) |
| Song slowly drifts from visuals | Song position from `Time.time` or summed `deltaTime` | Everything from dspTime ([[2. Conductor and the dspTime Beat Clock]]) |
| First beat late by a random amount | `PlayScheduled` time already in the past, or a streaming clip still opening | Schedule 0.1-0.2 s ahead plus a lead-in; preload; avoid Streaming load type for charts |
| Every hit judged "late" by the same amount | No calibration, or track-mode value used in synth mode | Separate profiles ([[6. Latency Calibration and Worked Example]]) |
| Hits judged by frame | Using "now" instead of `ctx.time` | Timestamped input ([[4. Note Highway Input and Judgement]]) |
| MIDI pad hits feel looser than keys | Minis callback stamped at processing time | Bind Minis controls in actions if the Input Debugger shows usable paths |
| Subharmonicon tempo doubles or wobbles | `MidiClockThread` **and** the sequencer clock both running | One clock source only |
| Mother-32 drones after stop | Note Offs still queued when you cleared, or scene unloaded mid-note | `ChartMidiSequencer.StopAndSilence()` on pause, stop, unload, quit |
| "No MIDI ports" / port busy | Another app (DAW, SysEx tool) owns the port; Windows MIDI ports are exclusive | Close the other app; see [[Eurorack and Unity]] 1.3.6 |
| Notes play in the wrong octave on the Subharmonicon | It treats notes as offsets from C4 | Author the SUB track around MIDI 60 |
| Late-song timing gets sloppy | `float` seconds | Keep `double` until positions |
| Hold notes break randomly | Hold interaction on the lane action delays/changes callbacks | Plain Button actions |
| Players learn to play late | Hit sounds that are themselves late | Visual hit feedback first; optional hit sounds offset by the track-mode latency |
| Pause/resume desyncs | `AudioSource.Pause` but `DspStart` not shifted | `RhythmConductor.Pause/Resume` shifts `DspStart` |
| App alt-tab breaks timing | Expected: dspTime pauses with the app | Nothing to do for OS pause; for in-game pause use the conductor |
## Design pitfalls (Level Up!)
- **Difficulty by speed.** Faster scroll is not harder; denser charts are. Keep scroll speed as a player option ([[Accessibility]]).
- **No rest.** A chart with no breathing room is the rhythm-game version of a level with no safe rooms (Level 9, [[Level Up! (Review)]]).
- **Unreadable patterns.** If two notes in a lane are closer than your Good window, the chart is unfair; catch it with the editor check in [[3. Note Charts and MIDI File Import]].
- **Punishing exploration.** Stray taps cost nothing here on purpose. If you add a penalty, make it an explicit Hard-mode rule.
## Patterns recap
Game Loop (song time vs frame time), Event Queue (the MIDI scheduler), Type Object (charts, windows), Observer (judge events), Object Pool (note views). See [[Game Programming Patterns (Review)]].