Tournament and Mission Module: Events, Ratings, Awards
1) Business objectives and activity types
Goals: Hold growth (D1/D7), ARPPU, increase session depth, promote new games and markets.
Formats:- Tournaments: by the amount of points/wins/multipliers, sprints (30-60 minutes), daytime, seasonal.
- Missions/quests: task sequences (play N spins, win X, try Y provider), with progress and stage rewards.
- Leaderboards: global, by markets/games/bets, private (friends/VIP).
- Jackpots/studio ratings: "top providers of the week," "hunt for a multiplier."
KPI: participation ≥ 12-25% of the active audience, share of income from promo 10-20%, complaints <0. 5% of participants, prize pool ≤ plan issued.
2) Architecture and data flows
Components
1. Events Gateway → reception of game events (spin, bet, win, round_end) from game-gateway/providers.
2. Rules Engine → matches events on the rules of tournaments/missions, awards points (idempotent).
3. Leaderboard Service → aggregates points, stores tops/slices, supports sorting and tie-breaks.
4. Progress Service (missions) → status of tasks/stages, issuance of interim awards.
5. Rewards Service → settlement and safe payment (via wallet: cash/bonus/fs/points).
6. Admin/Studio UI → creation, planning, economy preview, simulations.
7. Realtime/WS → publication of leadership board updates, progress, notifications.
8. Anti-Abuse → limits, risk signals, integration with anti-fraud/bot manager.
9. Storage/Cache → KV/Redis for hot tops, OLTP for facts, DWH for analytics.
Stream (e2e)
`game_event → gateway → rules_match → points → leaderboard_update → (progress_update) → notify → rewards_at_close → wallet_postings`
3) Event model (minimum fields)
json
{
"event_id": "e_9f2", "ts": "2025-10-23T17:41:26Z", "user_id": "u_123", "market": "DE", "brand": "X", "game": {"id":"g_77", "provider":"PragmaticPlay", "type":"slot"}, "bet": {"amount_minor": 100, "currency":"EUR"}, "win": {"amount_minor": 250, "multiplier":2. 5}, "round": {"id":"r_abc","status":"ended"}, "device": {"platform":"mobile","asn":"mno"}, "trace_id": "t_…"
}
Transport - Kafka/HTTP, idempotent processing (dedupe by 'event _ id'), provider/game gateway signature (HMAC).
4) Tournament rules and task designer
Declarative scheme (YAML example):yaml id: t_october_sprint window: {start: 2025-10-25T18:00Z, end: 2025-10-25T19:00Z, tz: Europe/Kyiv}
scope:
markets: [DE, SE]
providers: [PragmaticPlay, Hacksaw]
scoring:
formula: "points = min(win. amount/bet. amount, 50) 100" # multiplied by min_bet_minor: 50 eligible_games: ["g _"]
leaderboard:
type: "best_n_rounds" # summarize the best N rounds n: 20 tiebreaker: ["highest _ single _ multiplier,"" earliest _ finish _ ts"]
rewards:
pool: {currency: EUR, total_minor: 1000000}
distribution: "ladder" # ladder, top 100 anti_abuse:
min_round_duration_ms: 800 max_rps_per_user: 0. 5 exclude_asn_categories: ["hosting", "proxy"]
Missions (DSL):
yaml mission_id: m_halloween steps:
- id: s1 goal: {type: "spin_count", game_type: "slot", count: 50}
reward: {type: "freespins", value: 10, game: "g_66"}
- id: s2 goal: {type: "win_multiplier", min: 10}
reward: {type:"bonus", amount_minor: 500}
completion_reward: {type: "points", amount: 1000}
5) Ratings and calculation algorithms
Main models
Total points: linear/logarithmic/with a cap per round.
Best N rounds: lowers pay-to-grind, keeps sprint momentum.
Maximum multiplier (xWin): normalizes currencies and rates.
MMR/rating system: ELO-like for PvP/friendly competition tables.
Tie-breaks
1. 'highest _ single _ multiplier' → 2) 'fewest _ rounds' → 3) 'earliest _ finish _ ts' → 4) 'user _ id' lexicographically (fixed in rules).
Performance
Store the top K (for example, 10k) in the Redis Sorted Set 'ZADD key score member'.
For "best N rounds": keep the min-heap of the latest best N per user and amount, update on the fly.
Periodically snapshot (every 30-60 s) in OLTP/object.
6) Rewards and payments
Award types: cash/bonus/free spins/points/items/tickets.
Rules:- Issue only after finalization (appeal window 5-10 minutes).
- All payments are through Rewards Service → Wallet (ledger): double-entry, idempotence by 'reward _ id'.
- For intermediate stages of missions - the issuance of "soft" awards (FS/points), cash - at the end of the chain.
- CCM/responsible game: when blocking an account, hold/freeze the prize until verified.
- Fixed ladder: predefined steps (1st place 30%, 2nd 20%,...).
- Proportional: a share of the pool in points, but with a cap on the spot.
- Ticket-based: Missions give "tickets," drawing on tickets (transparent RNG).
7) Anti-abuse, honesty and compliance
Eligibility filters: min bet/round duration, exclusion of "0-bet," repeated re-cracks, "micro bets" in the pipeline.
Bot signals: headless-UA, abnormal frequency, abnormally stable RPS, proxy ASN → hidden challenges/freezing glasses.
Dedup/idempotency: events by 'event _ id', accruals by 'score _ id'.
Audit trail: leaderboard shots, seed RNG (for ticket draw), rule version, calculation hash.
Legal: rules/restrictions on markets, age, self-exclusion.
8) Tournament economics
Budget guardrails: upper limit of the pool + dynamic "safety valve" (reduction of intermediate bonuses when overheating).
Elasticity: Shifting rewards into points/FS instead of cash to hold margin.
Payback ratios: prize pool/receipts from the tournament games segment; target 8-15%.
Simulator in the admin panel: run of historical events → forecast of payments/participation.
9) API contracts (simplified)
Get active tournaments/missions
http
GET /v1/contests? market=DE&brand=X
→ 200 [{"id":"t_october_sprint","start":"…","end":"…","type":"xwin","status":"live"}]
Game Event (ingest)
http
POST /v1/events
{"event_id":"e_9f2", "...": "..."}
→ 202 {"accepted":true}
Leadboard (top K and user position)
http
GET /v1/leaderboards/t_october_sprint? top=100&me=u_123
→ 200 {"top":[{"pos":1,"user":"u_9","score":18400},...], "me":{"pos":342,"score":5600,"delta":+200}}
Mission progress and reward
http
GET /v1/missions/m_halloween/progress? user=u_123
→ 200 {"steps":[{"id":"s1","done":true},{"id":"s2","done":false}],"reward_ready":true}
POST /v1/rewards/claim
{"context":"mission","id":"m_halloween","step":"s1"}
→ 201 {"status":"granted","reward_id":"rw_77"}
10) Storage and scaling
Hot way: Redis (Sorted Sets/Hash) for tops and progress; TTL for "noisy" keys, sharding by 'contest _ id'.
True: OLTP (Postgres/MySQL) - points/progress/payout facts (WORM snapshots).
Queues: Kafka - event flow; Consumer groups by region/brand.
Caches: short TTL 1-5 s; stale-while-revalidate for public tops (via CDN).
WebSocket: a separate cluster/pool for realtime, batch mailing and rate-limit messages.
11) Observability and quality control
SLI/SLO:- `leaderboard_update_latency_p95 ≤ 250мс`
- `events_ingest_success ≥ 99. 9%`
- `rewards_grant_success ≥ 99. 9%`
- `ws_push_rtt_p95 ≤ 120мс`
- complaints of injustice <0. 5% of participants.
- rate of events/participants, unique players, distribution by bet/games, average multiplier; 'grant _ errors', 'dedupe _ hits'.
- Trails: ingest → rules → score → LB update → reward; 'contest _ id ', 'rule _ id' tags.
- Logs: JSON with 'trace _ id', PII ban; WORM for audit.
12) Incidents and runbook 'and (abbreviated)
A. Leader board lag (lag> 2s)
Actions: increase Kafka consumers, reduce the party "hot key" (repartition), enable batching update.
Temporary: freeze realtime animations, show "~ 1-2s delay."
B. Awards errors
Actions: stop new 'grant', check with the snapshot, replay 'grant' idempotently; status update in the lobby.
C. Abuse spike (proxy ASN)
Actions: strengthen eligibility, enable invisible challenge, temporarily ignore points to dubious sessions, post-verification.
13) UX and localization
Real time: "live" indicator, smooth deltas of points, position and distance to the next place.
Transparent rules: access to formula/tiebreakers/restrictions.
Notifications: "5 minutes left," "you are in the top 50," "reward is available."
Localization/legal texts: by market, time zones (Europe/Kyiv and participants' locales).
14) Security and privacy
Player aliases on public tops; Hide PII by default.
Signatures of webhooks/events, mTLS; protection against "cache poison" on the edge.
Rate-limit API, cache basting protection, 'idempotency _ key' control.
GDPR: event retention, right to delete (anonymize) without damaging the audit.
15) Testing and simulations
Replay of historical events for validation of rules and economics.
Load: bursts 30-120 s before the start; soak 2-4 hours.
Property-based: invariants ("the amount of awards issued ≤ the budget," "tie-break determined").
A/B: different scoring formulas, ladder depth, mission format.
16) Production readiness checklist
- Declarative rules (versions, signatures), economy simulator.
- Idempotency: 'event _ id', 'score _ id', 'reward _ id'; Inbox/Outbox.
- Tie-breaks are fixed in rules, sorting determinism.
- Leaderboards: top K in Redis + snapshots; anti-storm (jitter, coalescing).
- Anti-abuse: eligibility, bots/ASN, velocity limits.
- Rewards → Wallet via double-entry; KYC check before cash.
- Observability: SLI/SLO, dashboards, alerts; WORM audit.
- DR/Failover: multi-AZ, backups/restore, "freeze & finalize" script.
- Localization, licenses, public rules, and consent.
- Runbook 'and on lag/errors grant/burst bots, communication patterns.
Resume Summary
The successful module of tournaments and missions is event bus + deterministic rules + fast leaderboards + safe payouts. Add strict tiebreaks, anti-abuse, economics simulator and SLO observability, keep all operations idempotent and auditable - and you get a tool that grows engagement and revenue without arguing with players, regulators and support team.