The only cricket scoring app built for gully cricket. Kotlin + Jetpack Compose. Designed to end arguments before they start.
Most cricket scoring apps were built for stadiums.
Score247 was built for the street.
No WiFi. No umpires. No fixed rules. Just two teams, a tape ball, and someone's phone on the boundary line.
Score247 lets you define the rules before the match starts — so there are no fights during it.
"Wide pe run hai ya nahi?"
"Last batsman akela khelega?"
"No ball dobara hogi?"
Set it before the toss. Lock it in. Play.
Score247 is built on a simple idea:
Clarity before action.
In street cricket, most problems don’t come from gameplay.
They come from disagreement.
So instead of controlling the game, Score247 controls the ambiguity.
Define the rules once.
Play without interruption.
| Feature | Description |
|---|---|
| Custom Rules Engine | Wide runs, no-ball re-bowls, last batsman rule — all configurable per match |
| Fair Coin Toss | Animated, randomised, transparent — ends all "dubara karo" |
| Ball-by-Ball Scoring | Runs 0–6, extras, wickets — one tap per ball |
| Undo Last Ball | Mistake on last ball? Rebuilt from event log — no state drift |
| Session Persistence | DataStore-backed — match survives app kill, rotation, reboot |
| Full Scorecard | Batting, bowling, RR, economy, Player of the Match |
| Offline Only | No internet. No accounts. No ads. |
Match Setup → Toss → Player Names
│
Live Scoring
│
┌────────────┴────────────┐
│ Ball-by-ball input │
│ Undo / Extras / Wkt │
└────────────┬────────────┘
│
Over complete? → Rotate strike
Wicket? → Next batter
Target chased? → Innings over
│
Innings Break
│
2nd Innings
│
Final Scorecard
Score247 wasn’t built in one go.
It evolved the same way real systems do — through iteration, failure, and rebuilding when needed.
The first version answered a simple question:
Can defining rules before a match actually prevent arguments during it?
Built quickly, with minimal structure.
Functional, but rough.
It worked.
That was enough to continue.
The second version focused on usability.
Improved layout, clearer flow, better interaction during live scoring.
Less friction. More clarity.
Not a redesign — a correction.
At this point, the limitation wasn’t features.
It was the foundation.
So the app was rebuilt entirely.
From Python/Kivy → Kotlin/Jetpack Compose.
From mutable state → event-driven architecture.
From working → reliable.
Undo became deterministic.
State became predictable.
The system became stable.
Not just the code.
The thinking behind it.
- From building features → designing systems
- From making it work → making it reliable
- From solving a problem → building something others can depend on
Single ViewModel. Single StateFlow. No surprises.
app/
├── ui/
│ ├── screens/ # HomeScreen, SetupScreen, TossScreen,
│ │ # BattingSetupScreen, ScoringScreen,
│ │ # InningsBreakScreen, SummaryScreen
│ ├── components/ # PrimaryButton, RunButton, AppCard, NumberStepper...
│ └── theme/ # Color.kt, Type.kt, Theme.kt
├── viewmodel/
│ └── MatchViewModel # Single VM, StateFlow-driven, undo by event replay
├── data/
│ ├── model/ # MatchState, Innings, Player, BallEvent (sealed)
│ └── datastore/ # MatchDataStore — JSON via kotlinx.serialization
└── navigation/
└── AppNavigation # Single-activity, composable nav
Key design decisions:
- Undo by replay —
undoLastBalldrops the lastBallEventand replays all prior events from scratch. No reverse mutations. No state drift. Crash-proof. - DataStore over Room — match state is one JSON blob. One key. No schema migrations.
runCatchingon all serialization — a corrupt save never crashes the app. Silently ignored.- Reactive navigation — screens navigate via
LaunchedEffectwatchingStateFlow, not callbacks. Eliminates race conditions.
The UI is built around one principle: clarity under pressure.
- Warm off-white backgrounds (
#F9F9F7) — easy on the eyes in sunlight - Single green accent (
#2E7D4F) — field green, desaturated, calm - Dark score header (
#1A1A18) — maximum contrast for the live score - System fonts only — no downloads, crisp on every device
- Adaptive icon — field green background, white bat + ball
- Kotlin 2.0 + Coroutines + Flow
- Jetpack Compose (BOM 2023.10) + Material 3
- Android DataStore — async preferences
- kotlinx.serialization — JSON encoding with
@SerialNamediscriminators - Compose Navigation — single-activity
- MVVM —
AndroidViewModel+StateFlow - SplashScreen API —
core-splashscreenfor branded launch
From Releases:
→ github.com/waleedahmedja/Score247/releases
Download the .apk, enable "Install from unknown sources", install.
Build from source:
git clone https://github.com/waleedahmedja/Score247.git
cd Score247
./gradlew assembleDebugRequires Android Studio Hedgehog or later, JDK 17+.
Read CONTRIBUTING.md before opening a PR.
Score247 has a clear design philosophy and a strong offline-first constraint. Contributions that add internet dependencies, analytics, or unnecessary complexity won't be merged. Keep it simple. Keep it fast. Keep it for the street.
Score247 Community Source License (SCSL) v1.0 — free to use, study, modify. Attribution required. Public changes stay public. No reselling or rebranding.
Score247 collects nothing. Stores nothing outside your device. Has no internet permission. See PRIVACY_POLICY.md.
Built for that dusty pitch. That taped tennis ball. That one match everyone still argues about.
— waleedahmedja