Stella

Overview

Stella is a distributed intelligence platform that tracks 10,000+ players and monitors live game servers across multiple Roblox servers in real time. With server caps of just 25 players in Khei and 23 in Gaia, tracking the full player base requires visiting hundreds of servers continuously. Built as a small team of 2, it serves a community of 500+ users through a Discord bot interface backed by a REST API and in-game Lua automation client. Stella is powered by data sourced from the hydroxide.solutions user base.


Architecture

The system is split into three components:

  1. Discord Bot — 13 slash-command modules (Python, Discord.py) with reusable pagination, multi-field filtering, and concurrent database queries
  2. REST API Server — async aiohttp service handling bulk player/server upserts, HMAC-SHA256 signed requests, token auth, and per-endpoint token bucket rate limiting
  3. Lua Game Client — in-game automation for data collection with server-hop orchestration across hundreds of 23-25 player servers, failure recovery, and loop detection

Technical Highlights

  • Async Python backend with connection-pooled MySQL (aiomysql), auto-migrating schema, and parameterized queries
  • Security layer featuring HMAC-SHA256 request signing, timestamp-based replay protection, tiered token authentication, and automated breach alerting via Discord webhooks
  • LRU-cached Roblox API integrations with retry logic and exponential backoff
  • Race inference engine using pattern matching to automatically classify characters by name conventions
  • CI/CD with GitHub Actions for linting (Ruff) and Lua payload deployment, deployed via Dokploy (PaaS) behind Cloudflare
  • Dockerized with Alpine Linux and Nginx

Rate Limiting: Why Token Bucket

Stella uses a token bucket algorithm for per-endpoint rate limiting. We considered fixed window and sliding window, but token bucket was the right fit:

  • Fixed window has burst problems at window boundaries - a client can send double the limit by timing requests across two windows
  • Sliding window fixes the boundary issue but requires tracking individual request timestamps, adding memory overhead per client
  • Token bucket allows controlled bursts (important for our Lua client sending bulk upserts) while enforcing a steady average rate, with minimal state - just a token count and a last-refill timestamp per key

For an API that receives bursty bulk data from game clients but needs to protect against abuse, token bucket gave us the best tradeoff between burst tolerance and simplicity.


Stack

Python Discord.py aiohttp MySQL Lua Docker GitHub Actions Cloudflare Dokploy