A fully offline daily brain-training game for Android, built with Flutter and Java.
Owner: TharinduX.exe License: All Rights Reserved © TharinduX.exe
BrainForge X gives the user exactly 5 procedurally-generated brain workout challenges every day across five categories: Memory, Math, Pattern, Focus, and Logic. Every challenge has a unique fingerprint (SHA-256 hash) and the game guarantees that the exact same generated challenge never repeats during the install lifetime, no matter how many days the user plays.
The app is positioned as a fun brain exercise, not a medical product. It does not promise cognitive improvement, does not diagnose anything, and does not require an account, internet connection, or any personal data.
- 5 unique daily challenges, procedurally generated from seed
- Hash-based de-duplication — no exact repeat across the install lifetime
- 5 playable mini-games: Memory Grid, Number Sprint, Pattern Matrix, Focus Tap, Logic Path
- Local SQLite storage (sqflite) — install ID, used hashes, results, profile
- Streak / XP / accuracy / total-score tracking
- Per-category accuracy and last-7-days chart on the Progress screen
- 100% offline: no internet permission, no Firebase, no ads, no login
- Neon-futuristic dark UI
Clean separation between UI, game logic, generation, and storage.
SplashScreen ──init──► AppState (Provider)
│
├── DatabaseService (sqflite — challenges, used_hashes, results, meta)
├── InstallIdService (one-time UUID v4 in SharedPreferences)
├── ScoringService (score/XP/streak rules + profile persistence)
└── DailyChallengeEngine
│
├── seed = FNV1a(installId | date | dailyIndex | category | difficulty | retry)
├── generator.generate(seed, difficulty) → GeneratedSpec
├── challengeHash = SHA-256(canonicalJson({c,d,r,p,a}))
└── if hashExists → retry++ (up to 200 attempts)
HomeScreen ──► DailyChallengeScreen ──► GameRouter ──► one of:
MemoryGridGame
NumberSprintGame
PatternMatrixGame
FocusTapGame
LogicPathGame
│
└── onFinish(GameOutcome)
└► ResultScreen
- Provider for state (
AppState) — simple, no boilerplate, fits a single-user offline app. - Hash-based de-dup —
HashUtils.challengeHashSHA-256's a canonical JSON of{category, difficulty, ruleType, parameters, answer}. Any tiny difference produces a different hash; any identical generation collides and gets rejected. - Seed mixing — the seed for slot
ion dateDisFNV1a("$installId|$D|$i|$category|$difficulty|retry=$r"). Even a reinstall on the same date produces fresh challenges because the installId changes; even a retry within the same slot produces fresh challenges becauserchanges. - Append-only
used_hashestable — the de-dup oracle. It is never auto-pruned, so the lifetime no-repeat guarantee holds. - Streak rules in one place (
ScoringService.updateProfileAfterChallenge) — increments only when all 5 of today's challenges are done, never decrements on a miss.
brainforge_x/
├── android/ # Gradle + Java host
│ ├── build.gradle
│ ├── gradle.properties
│ ├── settings.gradle
│ ├── gradle/wrapper/gradle-wrapper.properties
│ └── app/
│ ├── build.gradle # Java 17, compileSdk 34, minSdk 21
│ └── src/main/
│ ├── AndroidManifest.xml # NO internet permission
│ ├── java/com/tharindux/brainforgex/MainActivity.java
│ └── res/values/styles.xml + drawable/launch_background.xml
├── lib/
│ ├── main.dart # Entry point — Provider + theme
│ ├── theme/app_theme.dart # Brand tokens, palette, gradients
│ ├── models/
│ │ ├── user_profile.dart
│ │ ├── brain_challenge.dart # Difficulty enum, ChallengeCategory, BrainChallenge
│ │ ├── challenge_result.dart
│ │ ├── daily_workout.dart
│ │ ├── game_outcome.dart
│ │ └── game_stats.dart
│ ├── utils/
│ │ ├── seed_random.dart # Seeded Random wrapper
│ │ └── hash_utils.dart # canonicalJson + SHA-256 challengeHash
│ ├── services/
│ │ ├── install_id_service.dart # UUID v4 in SharedPrefs
│ │ ├── database_service.dart # sqflite tables + queries + stats
│ │ ├── scoring_service.dart # score/XP/streak + profile persistence
│ │ ├── challenge_generator.dart # Abstract generator + GeneratedSpec
│ │ ├── daily_challenge_engine.dart # Per-day plan + seeded gen + dedup retry
│ │ └── app_state.dart # ChangeNotifier (Provider source of truth)
│ ├── games/
│ │ ├── memory_grid/ (generator + game widget)
│ │ ├── number_sprint/
│ │ ├── pattern_matrix/
│ │ ├── focus_tap/
│ │ └── logic_path/
│ ├── widgets/
│ │ ├── neon_container.dart
│ │ ├── gradient_button.dart
│ │ ├── stat_card.dart
│ │ ├── challenge_card.dart
│ │ └── game_scaffold.dart
│ └── screens/
│ ├── splash_screen.dart
│ ├── home_screen.dart # Visible © TharinduX.exe line
│ ├── daily_challenge_screen.dart # The 5 cards
│ ├── game_router.dart # category → game widget
│ ├── result_screen.dart
│ ├── progress_screen.dart
│ └── about_screen.dart # Required about text + offline note
├── pubspec.yaml
└── README.md
- Flutter SDK 3.10+ (
flutter --version) - Android Studio or VS Code
- Android SDK with API 34
- Java 17 (the Gradle build is configured for Java 17 toolchain)
Because the project ships source files only, a few binary scaffolding
files (the gradle wrapper jar, the mipmap launcher PNGs, the default
strings.xml, etc.) need to be generated by Flutter itself. This is
non-destructive — Flutter will skip any file that already exists.
cd brainforge_x
flutter create . --platforms=android --org=com.tharindux --project-name=brainforge_xIf you see "Skipped: …" messages for AndroidManifest.xml,
MainActivity.java, build.gradle, settings.gradle, that's expected —
those are the customised files we ship and we don't want them touched.
flutter pub getCopy android/local.properties.example to android/local.properties and set
sdk.dir to your local Android SDK path:
sdk.dir=/Users/you/Library/Android/sdkflutter run # debug build on connected device/emulator
flutter build apk --release # release APK at build/app/outputs/flutter-apk/app-release.apk
flutter build appbundle --release # Play Store .aab- App icon — replace
android/app/src/main/res/mipmap-*/ic_launcher.*with your asset, or use theflutter_launcher_iconspackage and add a config block topubspec.yaml. - Splash screen —
android/app/src/main/res/drawable/launch_background.xmlcontrols the native splash before Flutter boots. Change the<color>element or drop in a centered drawable. For a fancier branded splash use theflutter_native_splashpackage. - Theme —
lib/theme/app_theme.dartholds every brand color, gradient, and the typography helper. ChangeappName,owner,copyrightLine, or the palette and it propagates everywhere. - Add a category / game — implement a
ChallengeGeneratorsubclass, register it inDailyChallengeEngine, build a game widget, and add a case inGameRouter. TheChallengeCategory.alllist controls daily rotation.
The de-dup guarantee relies on used_hashes persisting. To survive a reinstall:
- Export — read every row from
used_hashes, write to a JSON file on the user's device storage, share viaShare.shareXFiles. - Import — pick a JSON, bulk-insert into
used_hashes(and optionallyresults).
This is intentionally not wired into the UI yet; the surface area is one JSON file and three DB calls, so it can be added as a single screen later without touching the engine.
BrainForge X is presented as a play-first daily mental warm-up. The genre of brain-training apps has decades of mixed-evidence research behind it, with users frequently engaging with the games "more with enjoyable play activity than interventional engagement" (Rahman & Foxman, 2020). The app deliberately avoids medical framing, does not market guaranteed cognitive improvement, and provides only fun, replay-safe challenges.
All Rights Reserved © TharinduX.exe