Data Model
This page covers the key entities in the system, how they relate to each other, and where they're stored across the three databases.
Entity Relationship Overview
erDiagram
User ||--|| GameState : "has"
User ||--o{ UserCard : "owns"
User ||--o{ UserQuest : "progresses"
User ||--o{ TournamentResult : "competes"
User ||--o{ PlayerItem : "holds"
User ||--o{ FriendReferral : "invites"
User ||--|| PlayerRank : "has"
User ||--o| PlayerWallets : "connects"
Card ||--o{ UserCard : "owned by"
Card }o--|| CardCategory : "belongs to"
Card ||--o{ CardLevel : "has"
Game ||--o{ Tournament : "hosts"
Tournament ||--o{ TournamentResult : "tracks"
Tournament ||--o{ Prize : "awards"
StoreItem ||--o{ StoreListing : "priced as"
StoreItem ||--o{ PlayerItem : "instance of"
Raffle ||--o{ RafflePlayer : "tracks"
Core Entities
User
The central entity linking everything together. Created when a player first opens the Telegram Mini App.
Table: lucky_funatic_users (MySQL)
| Field | Description |
|---|---|
| ID | Internal user ID |
| TelegramID | Telegram user identifier |
| PlatformID | Funtico platform user ID (linked externally) |
| Username, FirstName, LastName | Telegram profile info |
| GameStateID | FK to the player's game state |
| FunzIncomeMultiplierLevel | Current multiplier progression |
| RankLevel | Current rank tier |
| ReferralTelegramID | Who referred this player |
| MarketingCampaignName | How the player found the game |
| TON Wallet Address | Connected TON wallet (if any) |
| CreatedAt, UpdatedAt | Timestamps |
EVM wallet addresses are not stored directly -- they're fetched from the Funtico Platform via the social connections system.
Game State
The player's live game data -- currencies, energy, taps, and all mutable stats. This is the most frequently read and written entity in the system.
Primary storage: Redis (hash key {user:{userID}}:gamestate)
Persisted to: lucky_funatic_user_game_states (MySQL) every 60 seconds
| Field Group | Fields |
|---|---|
| Funz | Balance, total collected, income per second, income multiplier, multiplier level, per tap |
| Energy | Current balance, max balance, regen rate per second, cost per tap |
| Jokers | Balance, total won, won from tapping, won from rank ups, won from friend quests, won from level ups |
| Tickets | Mini ticket balance, Maxi ticket balance |
| Premium currencies | Lady Joker balance, Baby Joker balance |
| Friends | Friends invited, friends currency (Bond Bells), friends quest level |
| Taps | Total taps clicked (all time) |
| Timestamps | Last passive income update, last game state pull, last update |
The game state lives primarily in Redis for fast access. Active booster effects are calculated on-the-fly by the get_game_state.lua script when reading state, so the stored values represent base stats.
Cards
Collectible cards that generate passive income. Cards are defined by admins and players acquire and level them.
Tables: lucky_funatic_resource_cards, lucky_funatic_user_cards, lucky_funatic_card_levels (MySQL)
Card definition includes: name, image, price, base income per hour, category, rarity, and whether it's coming soon.
Player ownership tracks: which cards are owned, current level, whether max level is reached, upgrade cost, current and next income rates, and upgrade requirements (dependencies on other cards).
Card levels define the upgrade requirements and costs per level for each card.
Special cards are defined in lucky_funatic_resource_card_stories with narrative content and forging requirements (which regular cards must be maxed to unlock them).
Tournaments & Games
Minigames and the competitive tournaments that run on them.
Tables: lucky_funatic_toybox_games, lucky_funatic_tournaments, lucky_funatic_tournament_results (MySQL) + Redis sorted sets for live leaderboards
Game defines: name, logo, cover image, screenshots, score unit, scoring method (highest, lowest, highest cumulative), and aggregate stats (active players, total entries, TICO won).
Tournament defines: name, banner, game ID, prize pool distribution, entry cost (GPP), player/entry caps, start/end times, entry fee currency, and requirements (platform account, TON wallet, EVM wallet).
Tournament results track: player score, placement, entry count, and prizes won.
Live leaderboards are stored in Redis as sorted sets (tournament:{id}:leaderboard) for real-time ranking. A background worker persists final results to MySQL when tournaments end.
Store & Inventory
The item catalog, pricing, and player ownership system.
Tables: lucky_funatic_store_items, lucky_funatic_store_listings (MySQL) + player_items_counter, player_items_data, player_item_transactions (ScyllaDB)
Store items define: name, description, image, category, type, and transfer properties (whether an item can be sent to/from the Funtico Platform, its platform item ID, transfer type).
Store listings define pricing: which item, what price, in which currency, quantity per purchase, max purchases per player, total supply, and active status. Multiple listings can exist for the same item (e.g., a Maxi Ticket priced in Funz, Jokers, and Bond Bells).
Player items are tracked in ScyllaDB for write performance. Item quantities are stored as counters, with full transaction history (purchase, transfer, conversion) logged separately.
Quests
One-time tasks with rewards.
Tables: lucky_funatic_quests, lucky_funatic_user_quests (MySQL) + Redis for scheduled completions
Quest definitions include: name, description, icon, reward (Jokers and/or Funz), action URL, and whether auto-completion is enabled. Auto-complete quests (like wallet connection) are tracked via a Redis sorted set (quest_completion_schedule) and processed by the QuestCompletionWorker.
Player quest progress tracks status transitions: Not Started -> In Progress -> Completed -> Claimed.
Daily Bonus
The daily spin wheel with streak mechanics.
Tables: lucky_funatic_daily_bonus_config, lucky_funatic_daily_bonus_rewards (MySQL) + Redis for streak data
Configuration defines: max streak days, number of wheel slices, and reward pool. Each reward has a probability weight, base quantity, and optional rank-based scaling multiplier. Streak data is stored in Redis for fast access.
Raffle
Promotional raffle with eligibility tracking.
Tables: lucky_funatic_raffles, lucky_funatic_raffle_players (MySQL) + Redis cache for eligibility
Raffle definitions include: name, description, eligible player cap, and prize pool. Player eligibility is computed from multiple sources (taps, friends, username, platform link, wallet) and cached in Redis to avoid recomputation.
Boosters
Temporary and permanent power-ups.
Storage: Redis (active states, cooldowns, daily counters, permanent levels) + ScyllaDB (booster_snapshots for recovery)
Booster state is managed entirely in Redis via Lua scripts for atomicity. Each booster type tracks: whether it's active (with TTL), cooldown timer, daily usage counter, and for permanent boosters, the current level and activation history. ScyllaDB snapshots provide recovery if Redis state is lost.
Balloon Game Settings
Configuration for the WebSocket-based balloon pop minigame.
Table: lucky_funatic_balloon_settings (MySQL)
Defines: game duration, balloon spawn rate, balloon type odds (type, taps to pop, value in seconds, picker weight), leniency bonus for latency, speed ranges, and boundary ranges. These settings are loaded once when a balloon game starts and sent to the client.
Frenzy mode state (multiplier, Joker probability, duration, active status) is stored in Redis with key {user:{userID}}:frenzy_mode.
ScyllaDB Tables
ScyllaDB handles high-write-volume data that doesn't need relational queries:
| Table | Partitioning | Purpose |
|---|---|---|
state_changes_by_user |
user_id + day | Audit trail of every game state mutation |
state_changes_by_day |
day | Same data partitioned by date for analytics |
player_items_counter |
user_id | Item quantity counters |
player_items_data |
user_id | Item ownership with timestamps |
player_item_transactions |
user_id | Full transaction history |
booster_snapshots |
user_id | Booster state for recovery |
support_actions |
timestamp | Admin action audit log |
time_trial_scores |
user_id | Time trial results |
Redis Key Patterns
| Key Pattern | Type | Purpose |
|---|---|---|
{user:{id}}:gamestate |
Hash | Player's live game state |
{user:{id}}:boosters:* |
Various | Active boosters, cooldowns, daily counts |
{user:{id}}:boosters:permanent:* |
Hash | Permanent booster levels |
{user:{id}}:frenzy_mode |
Hash | Active frenzy state |
{user:{id}}:daily_bonus:streak |
Hash | Daily bonus streak data |
tournament:{id}:leaderboard |
Sorted Set | Live tournament rankings |
quest_completion_schedule |
Sorted Set | Scheduled auto-completions |
popup:active |
String (TTL) | Popup display flag |
popup:views |
Counter | Popup view tracking |