Files
artlegend/SPRINT.md

80 lines
3.8 KiB
Markdown
Raw Normal View History

# ArtLegend — Current Sprint
**Sprint goal:** Hybrid architecture end-to-end. Compose hub → LibGDX `LineCorridorScreen` with live stylus pressure data.
---
## Tickets
### AL-001 — shared/ module compiles [DONE]
- `shared/build.gradle.kts` created (pure Kotlin JVM)
- `ModuleType.kt` created with LINE_CORRIDOR, PRESSURE_RAMP, CURVE_SCULPTOR, VECTOR_SNAP
- `settings.gradle.kts` updated to include `"shared"`
### AL-002 — core/ restructured [DONE]
- `GameHost.kt` replaces `ArtLegend.kt` — accepts `ModuleType`, routes to correct Screen
- `PlaceholderModuleScreen.kt` — stub Screen for unimplemented modules
- `input/StylusFrame.kt` — data class (x, y, pressure, tiltRad, orientRad, isStylus)
- `input/StylusInputBridge.kt` — AtomicReference bridge (GL-thread safe)
- `modules/LineCorridorScreen.kt` — skeleton (dark background, reads bridge)
- `core/build.gradle.kts` updated with `:shared` dependency
### AL-003 — Compose added to android/ [DONE]
- `android/build.gradle.kts` updated: `buildFeatures { compose = true }`, Compose BOM 2024.09.00, navigation-compose, activity-compose, lifecycle
- `gradle.properties` updated with compose versions
### AL-004 — MainActivity + Compose hub [DONE]
- `MainActivity.kt` created — ComponentActivity, sets Compose content
- `ui/theme/ArtLegendTheme.kt` — dark Material3 theme, violet/cyan accents
- `ui/ArtLegendApp.kt` — NavHost with 4 routes (hub, detail/{moduleType}, progress, settings)
- `ui/screens/HubScreen.kt` — LazyVerticalGrid of 4 module cards
- `ui/screens/ModuleDetailScreen.kt` — module info + "Start Training" button
- `ui/screens/ProgressScreen.kt` — stub
- `ui/screens/SettingsScreen.kt` — stub
- `res/values/themes.xml` — Theme.ArtLegend (Material3) + Theme.ArtLegend.Fullscreen
- `AndroidManifest.xml` updated — MainActivity as LAUNCHER, GameActivity registered
### AL-005 — GameActivity + stylus bridge [DONE]
- `GameActivity.kt` created — AndroidApplication, reads ModuleType from Intent
- Stylus OnTouchListener set on LibGDX view post-initialization
- `handleStylusEvent()` extracts pressure/tilt/orient, posts StylusFrame to bridge
- Logs `pressure` + `isStylus` to logcat for verification
### AL-006 — LineCorridorScreen renders corridor [DONE]
- ShapeRenderer corridor: two cyan walls + dashed centerline at random ±25° angle
- Stroke captured per-frame from StylusInputBridge; yellow alpha stroke rendered live
- `isDown` field added to StylusFrame; DOWN/UP edges detected for clean start/stop
- Y-coordinate flipped (Android top-left → LibGDX bottom-left)
### AL-007 — Score calculation [DONE]
- `LineScore(straightness, pressureConsistency, overall)` data class in core/modules
- RMS perpendicular deviation from centerline → straightness (0..1)
- RMS pressure deviation from 0.5 target → pressureConsistency (0..1)
- overall = straightness×0.6 + pressureConsistency×0.4
- Score logged to logcat on stylus lift
### AL-008 — Score returned to hub [DONE]
- `GameHost.onSessionComplete: ((LineScore) -> Unit)?` wired by GameActivity
- GL thread score callback → `runOnUiThread { setResult + finish() }`
- `MainActivity.gameResultLauncher` (ActivityResultContracts.StartActivityForResult)
- `lastScore: LineScore?` state flows through ArtLegendApp → ModuleDetailScreen
- ScoreCard shows Overall / Line / Pressure % on return; button changes to "Train Again"
### AL-009 — End-to-end smoke test [TODO]
- `./gradlew :android:assembleDebug` passes
- App launches to Compose hub showing 4 module cards
- Tap card → ModuleDetail with "Start Training" button
- Tap "Start Training" → LibGDX renders dark background with corridor
- Stylus pressure values visible in logcat
---
## Blocked
_Nothing blocked currently._
## Out of Scope This Sprint
- Local score persistence (Phase 1)
- Difficulty progression
- In-app purchases
- Cloud sync