A beautifully crafted Fate RPG dice roller for Android โ fully built with Jetpack Compose.
Originally developed with XML layouts, now modernized with a declarative UI architecture.
| ๐ฒ Main Screen | ๐ Roll History |
|---|---|
![]() |
![]() |
| Roll four Fate dice with a single tap | Full session history in a slide-up bottom sheet |
Fate Core is a narrative-driven tabletop RPG by Evil Hat Productions. Instead of d20s or percentile dice, Fate uses its own special Fate Dice (dF) โ each face shows one of three symbols:
โโโโโโโโโโโโโฌโโโโโโโโโโโโฌโโโโโโโโโโโโ
โ [ + ] โ [ ] โ [ - ] โ
โ โ โ โ
โ Plus โ Blank โ Minus โ
โ +1 โ 0 โ -1 โ
โโโโโโโโโโโโโดโโโโโโโโโโโโดโโโโโโโโโโโโ
You roll 4 dice simultaneously and sum the results. The total ranges from -4 to +4, compared against a skill level or opponent roll to determine the narrative outcome.
| Result | Ladder Rank | Narrative Meaning |
|---|---|---|
+4 |
๐ Legendary | Beyond extraordinary โ a moment for the ages |
+3 |
โจ Fantastic | Things go spectacularly well |
+2 |
๐ Great | Clear, clean success |
+1 |
๐ Good | Success, but with a small twist |
0 |
๐ Fair | Neutral outcome โ something happens |
-1 |
๐ฌ Average | Minor setback, minor cost |
-2 |
๐ Mediocre | Failure with consequence |
-3 |
๐จ Poor | Bad failure |
-4 |
๐ Terrible | Catastrophic โ the story just got dramatic |
๐ง Learn more at faterpg.com
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
โ ๐ฒ 4-Dice Roll Roll all four Fate dice simultaneously โ
โ ๐ Roll Animation Rapid dice shuffle before final reveal โ
โ ๐ฅ Score Bounce Spring animation on result display โ
โ ๐ Roll History Slide-up bottom sheet with session log โ
โ ๐จ Custom Dice Art Hand-designed dice imagery via Figma โ
โ ๐ข Custom Button Distinctive branded "ROLL THE DICE" UI โ
โ ๐ Indigo Theme Calming, immersive color palette โ
โ โพ๏ธ Infinite Sessions No roll limit, persistent history โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The dice faces, roll button, and screen layouts were all designed from scratch in Figma before being implemented in Compose.
The Figma file contains:
- ๐ฒ All three Fate dice face variants (
[+],[ ],[-]) with 3D styling - ๐ข The custom "ROLL THE DICE" button graphic
- ๐ Full screen layout compositions and spacing guides
- ๐จ Color tokens: indigo/periwinkle palette (
#A5B4FC,#2D3748,#4A5568)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ UI LAYER โ
โ DiceScreen.kt โ
โ (Jetpack Compose) โ
โ โ
โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโ โ
โ โ DiceImage โ โ RollButton โ โ ModalBottomSheet โ โ
โ โ @Composable โ โ @Composable โ โ (Roll History) โ โ
โ โโโโโโโโฌโโโโโโโ โโโโโโโโฌโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโผโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ collectAsState()
โโโโโโโโโโโผโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ VIEWMODEL LAYER โ
โ DiceViewModel.kt โ
โ โ
โ diceFaces: StateFlow<List<Int>> โ
โ isRolling: StateFlow<Boolean> โ
โ rollHistory: StateFlow<List<RollRecord>> โ
โ โ
โ startRolling() โ stopRolling() โ updateDice() โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Kotlin Coroutines
โโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ LOGIC LAYER โ
โ generateRandomDice() โ random pick from [-1, 0, 1] โ
โ RollRecord(id, total) โ prepended to history list โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
| Layer | Technology |
|---|---|
| Language | Kotlin |
| UI Toolkit | Jetpack Compose |
| State Management | ViewModel + StateFlow |
| Async / Animation | Kotlin Coroutines |
| UI Components | Material 3 (ModalBottomSheet, Surface) |
| Animation | animateFloatAsState + Spring spec |
| Build System | Gradle KTS |
| CI/CD | GitHub Actions |
| Design | Figma |
This project was originally built using classic Android XML layouts and has since been fully refactored to Jetpack Compose.
BEFORE (XML Views) AFTER (Jetpack Compose)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
activity_main.xml DiceScreen.kt @Composable
res/layout/*.xml files Composable function hierarchy
View Binding / findViewById State-driven recomposition
AnimatorSet / ObjectAnimator animateFloatAsState + spring()
LiveData + Observer pattern StateFlow + collectAsState()
RecyclerView + Adapter LazyColumn + items { }
Fragment transactions Direct composable calls
Manual lifecycle management LaunchedEffect + ViewModel scope
Result: ~60% less boilerplate, dramatically smoother animations, and a far more maintainable codebase.
User taps [ROLL THE DICE]
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโ
โ startRolling() โโโโบ isRolling = true
โ ViewModel call โโโโบ UI shows "Rolling..." text
โโโโโโโโโโโโฌโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ LaunchedEffect(isRolling) โ
โ Coroutine launches on main thread โ
โ โ
โ repeat(10): โ
โ updateDice(generateRandom()) โโโโผโโ visual shuffle
โ delay(50ms) โ every 50ms
โโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ stopRolling(finalFaces) โ
โ diceFaces updated โ
โ isRolling = false โ
โ rollCounter++ โ
โ RollRecord prepended to list โ
โโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ UI recomposes automatically โ
โ Score shown with sign (+/-) โ
โ Spring bounce animation fires โโโโบ scale 1.0 โ 1.2 โ 1.0
โ History list instantly updated โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Fate-Dice-Roll/
โโโ .github/
โ โโโ workflows/
โ โโโ android.yml # CI/CD pipeline definition
โโโ app/
โ โโโ src/main/
โ โโโ java/com/stargazer/fatediceroll/
โ โ โโโ MainActivity.kt # App entry point
โ โ โโโ ui/
โ โ โ โโโ DiceScreen.kt # All UI composables
โ โ โโโ viewmodel/
โ โ โโโ DiceViewModel.kt # State + business logic
โ โโโ res/
โ โโโ drawable/ # Dice images & button graphics
โโโ build.gradle.kts # Module build config
โโโ settings.gradle.kts
Every push to master triggers the Android CI workflow via GitHub Actions:
Push to master / Pull Request
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ GitHub Actions Runner โ
โ โ
โ 1. โ
Checkout repository โ
โ 2. โ
Set up JDK 17 โ
โ 3. โ
Cache Gradle packages โ
โ 4. โ
./gradlew build โ
โ 5. โ
Run unit tests โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
Build artifact + status badge updated
Latest run: Android CI #1 โ โ passed in 3m 54s
| Requirement | Minimum Version |
|---|---|
| Android Studio | Hedgehog (2023.1+) |
| JDK | 17 |
| Android minSdk | 24 (Android 7.0) |
| Android targetSdk | 35 |
| Gradle | 8.x |
# Clone the repository
git clone https://github.com/berat-karabuga/Fate-Dice-Roll.git
cd Fate-Dice-Roll
# Build debug APK
./gradlew assembleDebug
# Run unit tests
./gradlew testOr open in Android Studio and press
Contributions, bug reports, and feature ideas are all welcome!
# 1. Fork the repository
# 2. Create your feature branch
git checkout -b feature/your-feature-name
# 3. Commit with a clear message
git commit -m "feat: describe your change"
# 4. Push and open a Pull Request
git push origin feature/your-feature-nameThis project is open source and available under the MIT License.
Made with โค๏ธ for the Fate RPG community
"In Fate, you are the author of your own story โ the dice just add the drama."
โญ Star this repo if you find it useful! ย ย |ย ย ๐จ View Figma Design

