Overview
What SP-Legends is
+1 Skill Point Legends is a Roblox game with a deceptively simple core
loop and a deep set of perks, items, and progression mechanics underneath. The
fan resources for it were spread across half a dozen places with conflicting
numbers; SP-Legends pulls them into one site that's accurate, fast, and quiet
about it.
The hub bundles a wiki (items, perks, mechanics, with cross-links), a damage
calculator, a leaderboard, a live private-server tracker, a calculator for
membership perks, and a small set of side tools. It runs on its own dedicated
Debian VM under spl.apoptoses.com.
Stack
Architecture
Like every other web service in the apoptoses portfolio, SP-Legends is a single
Rust binary running on its own VM. The HTTP layer is Axum 0.8
behind rustls bound directly to port 443 — no reverse proxy in
front of it on the same machine, no nginx, no load balancer. Cloudflare sits in
front of the public DNS for caching and DDoS shielding, but the VM itself takes
TLS terminations directly.
Persistent state is split between two stores: a private_servers.json
file for the current snapshot of known private servers, and a binary
ps_history.bin for the rolling history. Both are written by the
same task that polls the upstream APIs, so consumers always see a consistent
view.
Polling
The 15-second refresh loop
The most visible feature of SP-Legends is the live private-server tracker. Behind
it is a polling task that fires every fifteen seconds, walks the upstream Roblox
API for the relevant endpoints, and updates the in-memory AppState
that the HTTP handlers read from.
Fifteen seconds is a deliberate choice. Faster polling buys very little
additional freshness for the user — the underlying API is itself eventually
consistent — and quickly attracts rate limits. Slower polling makes the page
feel stale. The current cadence has held up across multiple Roblox API changes
without rate-limit incidents, partly because the request surface is small and
partly because failures are surfaced and retried with backoff rather than
silently dropped.
Reliability
Alerting and persistence
When the polling task hits an unexpected error, an admin alert is fired through
a shared alert::notify_admin helper that posts to a Discord webhook.
It's fire-and-forget — the HTTP path that triggered it never blocks on the alert
delivery. The same pattern is used by emu_service; consolidating the
helper across services means there's one place to tune, one place to silence,
and one place to read when something goes wrong.
Server-list and history snapshots are flushed to disk on a cadence and on clean
shutdown, so a restart picks up where it left off rather than starting blind.
Features
What's on the site
- Wiki — items, perks, mechanics, all cross-linked, all hand-curated.
- Damage calculator — numeric model that matches the in-game formulas.
- Live private-server tracker — the page consumers actually keep open in a tab.
- Leaderboard — top players by stat axes.
- Buy Me a Coffee tier perks — supporters get small extras (custom accents, early access to side tools); the bot syncs the role automatically.
- Side tools — share-card generator, calculator presets, and so on.
Integration
How the bot ties in
The apoptotic Discord bot talks to SP-Legends
through a small internal API: it can look up Roblox player stats, surface live
private-server availability as Discord embeds, and check membership tiers when
syncing roles. The handshake re-uses the same alert and structured-logging
helpers, so events from both sides land in the same place during incident
response.
Roadmap
Where it's going
The current focus is on continuing to track the game's updates as they ship, and
on slowly migrating long-form wiki copy into a cleaner structure that can be
rendered both on the SPL subdomain and as a case-study summary on this apex
domain. The polling cadence and reliability story are both holding up well and
are not a current priority.
Related
Read more