A "Simon says" color memory game for Google Pixel Watch (Wear OS).
The watch flashes a sequence of colored quadrants; tap them back in order. Each round adds one more. Wrong tap ends the game.
Built with Kotlin + Jetpack Compose for Wear OS.
Working end-to-end. Installed and playable on both the Wear OS emulator and a real Pixel Watch. No remote configured — the repo is local only.
minSdk30 (Wear OS 3+; covers Pixel Watch 1 & 2)compileSdk36 (extension 1)- Kotlin 2.2.x, AGP 9.x, Gradle 9.3.1
- Android Studio (Koala or newer) installed at
/Applications/Android Studio.app - Wear OS system image (API 34+) installed via SDK Manager
- A Wear OS AVD named something like "Wear_OS_XL_Round" with a round 454×454 profile
- No standalone JDK needed — the bundled JDK at
/Applications/Android Studio.app/Contents/jbr/Contents/Homeis used
Open the project in Android Studio, pick the Wear AVD in the target dropdown, press ▶. That's it.
The gradle wrapper requires JAVA_HOME set to Android Studio's bundled JDK:
export JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home"
export PATH="$JAVA_HOME/bin:$PATH:$HOME/Library/Android/sdk/platform-tools"Build:
./gradlew :app:assembleDebugInstall on emulator (must be running):
./gradlew :app:installDebug
adb shell am start -n com.tgwizard.adamsays/.presentation.MainActivityRun the unit tests:
./gradlew :app:testDebugUnitTestThe Pixel Watch has no USB port — connect via ADB over Wi-Fi.
- On the watch: Settings → System → About → Versions, tap Build number seven times to enable developer options.
- Settings → Developer options → ADB debugging: ON.
- Settings → Developer options → Wireless debugging: ON.
- Make sure the watch is on the same Wi-Fi network as the Mac.
Wear OS rotates the wireless debugging port after reboots / disconnects.
-
Open Settings → Developer options → Wireless debugging on the watch.
-
Note the IP:port at the top of that screen — that's the ADB port.
-
If ADB has never paired with this watch before (or you revoked trust), tap Pair new device — it shows a pairing IP:port and a 6-digit code. Run:
adb pair <pairing-ip>:<pairing-port> # enter the 6-digit code when prompted
-
Connect (using the ADB port from step 2, not the pairing port):
adb connect <ip>:<adb-port>
-
Install and launch:
adb -s <ip>:<adb-port> install -r app/build/outputs/apk/debug/app-debug.apk adb -s <ip>:<adb-port> shell am start -n com.tgwizard.adamsays/.presentation.MainActivity
If adb connect returns Connection refused, the port rotated — re-check it
on the watch.
app/src/main/java/com/tgwizard/adamsays/
presentation/MainActivity.kt # hosts GameScreen
game/
Quadrant.kt # enum + tap-angle → quadrant pure function
GameState.kt # GameState, GamePhase sealed interface, Timing
GameViewModel.kt # state machine; StateFlow<GameState>
ui/
GameColors.kt # dim/lit neon palette per quadrant
WatchFaceCanvas.kt # draws the 4 quadrants + hub + ball of fire
GameScreen.kt # top-level composable; routes taps, drives animations
StartScreen.kt # "ADAM SAYS / tap to start" screen
GameOverScreen.kt # "SCORE / N / tap to play again" screen
app/src/test/java/com/tgwizard/adamsays/
MainDispatcherRule.kt # JUnit rule installing TestDispatcher as Main
game/QuadrantTest.kt # 8 tests
game/GameViewModelTest.kt # 16 tests — full state machine coverage
NotStarted ──onStartTap──► Idle ──delay(PRE_START_MS)──► Showing ──loop flashes──► AwaitingInput
│
┌── wrong ──────────────────┤
│ │
│ ├── correct & final ──► RoundComplete
│ │ │
│ │ delay(ROUND_PAUSE_MS)
│ │ ▼
│ └── correct & mid ──► (advance inputIndex, still AwaitingInput)
▼
GameOver(score, restartable=false)
│
delay(GAME_OVER_LOCK_MS)
▼
GameOver(..., restartable=true)
│
┌───────────┴─────────────┐
▼ ▼
tap to restart delay(auto_restart_MS)
└──────► startNewGame ──┘
- Unit tests drive the ViewModel's
StateFlowwith aStandardTestDispatcher- virtual time via
advanceTimeBy(seeMainDispatcherRule).
- virtual time via
- Tests bias time offsets by ±1ms around
Timingconstants to avoid fragility at exact virtual-time boundaries inkotlinx-coroutines-test. - No instrumented / Compose UI tests (kept minimal for MVP). Visuals are verified manually on the emulator.
- Spec:
docs/superpowers/specs/2026-04-17-wear-os-simon-game-design.md - Implementation plan:
docs/superpowers/plans/2026-04-17-wear-os-simon-game.md(tracks the original TDD walkthrough — useful for understanding the code's evolution; may lag behind current state.)
MIT — see LICENSE.
- Persist high score across launches (DataStore)
- Difficulty ramp (flashes speed up as the sequence grows)
- Sound effects (game is haptic-only now)
- Settings screen
- Watch tile / complication for one-tap launch