RiverKing is a Telegram-first fishing game with a Kotlin/Ktor backend, a shipped Telegram Mini App frontend, Telegram bot flows, progression systems, tournaments, quests, clubs, referrals, and Stars-based monetization. The repository now also includes an Android client subtree that reuses the same backend and player data model.
It is built as a working product rather than a thin game prototype: the repository already includes session-authenticated Mini App flows, real gameplay systems, persistent progression, background jobs, operational metrics, moderation rules, and admin-side bot tooling.
What it does
- Delivers a Telegram Mini App fishing experience with cast, hook, and catch gameplay.
- Tracks progression across locations, rods, lures, fish discovery, achievements, quests, tournaments, and clubs.
- Connects the game backend to Telegram bot commands, referral flows, Stars payments, coin purchases, auto-casting, and operational metrics.
- Includes an Android nested project under
mobile/android-appwith shared-backend auth,play/directflavors, real Google Play Billing for theplayflavor, and a parity-focused mobile shell.
Why it is technically interesting
- Hybrid Telegram product surface: Mini App frontend plus bot commands and admin flows in one codebase.
- Shared identity foundation: Telegram cookie sessions for the Mini App plus bearer-token mobile auth with Telegram sign-in/linking against the same gameplay API.
- Product-minded backend, not only a game loop: progression, retention systems, economy, moderation, payments, analytics, and scheduling.
- Clear Kotlin layers for Ktor routes, gameplay services, Exposed persistence, shipped frontend assets, and an isolated Android project.
Stack
Kotlin Ktor Netty Exposed SQLite Telegram Mini App Telegram Bot API Android Jetpack Compose TG Analytics Gradle
Quick links
- Mini App: t.me/river_king_bot/app
- Bot: t.me/river_king_bot
- Product overview: docs/product-overview.md
- Android release guide: docs/android-release.md
- Architecture: DOCUMENTATION.md
- Agent guide: AGENTS.md
| Fishing | Tournaments |
|---|---|
![]() |
![]() |
| Achievements | Clubs |
![]() |
![]() |
Human-facing repository docs live in this file and in docs/product-overview.md. AI-oriented repository context lives in AGENTS.md, DOCUMENTATION.md, and the package READMEs under src/main/kotlin/**.
- A Telegram Mini App with a fishing-first gameplay loop and a shipped asset-driven frontend.
- Ktor API routes for Telegram auth, profile state, fishing actions, guide data, ratings, tournaments, clubs, quests, shop, referrals, and prizes.
- Provider-neutral auth tables and routes for Telegram, Google sign-in, password auth, refresh sessions, and shared bearer access.
- Product systems for progression, achievements, quests, tournament prize logic, club competition, referral rewards, and in-game economy.
- Telegram bot integrations for commands, auto-casting, prize flows, payment-support flows, and admin operations.
- Exposed-backed persistence, startup restoration logic, background schedulers, TG Analytics integration, and Prometheus-style metrics.
- A nested Android project with its own Gradle setup, Telegram/password/Google auth flows, nickname gate, shared-API main shell, and real Google Play Billing verification for the
playflavor. - Public Android-compliance surfaces for privacy, support, terms, and account deletion, plus an authenticated account deletion endpoint for mobile users.
flowchart LR
A["Telegram client"] --> B["Mini App frontend"]
A --> C["Telegram bot / admin flows"]
I["Android app"] --> D
B --> D["Ktor API"]
C --> D
D --> E["Gameplay services"]
D --> J["Account / session layer"]
E --> F["Exposed + SQLite"]
D --> G["Metrics / analytics"]
E --> H["Schedulers / reward distribution"]
src/main/kotlin/app/owns bootstrap, sessions, Telegram auth, HTTP routes, bot webhook handling, and schedulers.src/main/kotlin/service/contains gameplay systems such as fishing, tournaments, quests, clubs, referrals, achievements, and shop/payment logic.src/main/kotlin/db/defines tables, schema creation, seed data, and data migrations.src/main/resources/webapp/contains the shipped Mini App frontend and visual assets.mobile/android-app/contains the nested Android client project and its separate Gradle build.
Fishing loop: cast -> hook -> catch with timing, catch presentation, and recent catch history.Progression: locations, rods, lures, fish discovery, unlocks, and recommendation logic.Retention: daily rewards, quests, achievements, daily ratings, and tournament participation.Social loops: clubs, member roles, weekly contribution boards, and club chat feed.Economy: Stars purchases, coin purchases, referral rewards, and prize distribution.Operations: profanity filtering, metrics, TG Analytics hooks, startup recovery, and scheduled background jobs.Bot automation: command flows, auto-casting, admin tournament tooling, and payment-support operations.
- docs/product-overview.md: product-facing overview of game loops, economy, and operating model.
- DOCUMENTATION.md: engineering architecture and package map.
- AGENTS.md: repo-level guide for coding agents and review tools.
- Package READMEs:
Admin-side tooling exists in the codebase and bot flows, but it is intentionally excluded from the public screenshot set.
- JDK 17+
- Telegram bot token for real Telegram integration
- A writable SQLite path or another configured database target
- Android SDK, if you want to build the nested Android client
-
Copy the example config into the runtime location:
cp config.example.properties src/main/resources/config.properties
-
For local development, at minimum keep these values:
BOT_TOKEN=TEST BOT_NAME=river_king_bot PUBLIC_BASE_URL=http://localhost:8080 DEV_MODE=true
-
Start the app:
./gradlew run
-
Open the Mini App locally:
With DEV_MODE=true, the Mini App can boot without a real Telegram session and the API falls back to the local development user.
With DEV_MODE=false, opening /app in a regular browser keeps the Mini App blocked until valid Telegram initData is present.
To work on the Android client, use the nested project described in mobile/android-app/README.md.
Use config.example.properties as the starting point. Current keys used by the app:
BOT_TOKENBOT_NAMEPUBLIC_BASE_URLDATABASE_URLDATABASE_USERDATABASE_PASSWORDPORTDEV_MODEADMIN_TG_IDPROVIDER_TOKENTELEGRAM_WEBHOOK_SECRETAUTH_TOKEN_SECRETAUTH_ACCESS_TOKEN_TTL_MINUTESAUTH_REFRESH_TOKEN_TTL_DAYSGOOGLE_AUTH_CLIENT_IDGOOGLE_PLAY_PACKAGE_NAMEGOOGLE_PLAY_SERVICE_ACCOUNT_FILETG_ANALYTICS_TOKENTG_ANALYTICS_SCRIPT_URLTG_ANALYTICS_APP_NAME
Build the application classes:
./gradlew classesRun tests:
./gradlew test





