Skip to content

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