Verified leaderboards and achievements for games, on Cloudflare Workers' free plan.
Clients upload button inputs, not scores. The server replays them through the game's own Lua simulation, in a sandboxed Lua 5.1 Wasm VM, and ranks only what it verified. Achievements run on BadgeTrip.
Status: early (0.x). Deployed on Cloudflare Workers; not yet measured under real load. Changes are listed in the CHANGELOG.
A leaderboard that accepts a score from the client is a leaderboard of whoever edited the request. Scoreosis never accepts one. The game and the server run the same deterministic simulation; the client streams its inputs every second with a checksum, and the server replays them in real time.
- Fabricated scores, modified clients, speed hacks, slow motion, rewritten history are rejected. Security lists each control and its test.
- Bots that play legal inputs in real time are not detected. Nothing on the server can tell them from people.
- Global and country leaderboards per platform. Web, Windows, Android and the rest rank separately; the API also filters by store. Each named run appears separately; authenticated responses identify the latest entry for highlighting.
- Modes. A game with stages or tracks gets one board per mode.
- Achievements, local and verified. Verified progress runs on the BadgeTrip engine, committed in one transaction with the run result. Games track local progress with the same rules and show both.
- Guest identity per game installation. No accounts, no personal data.
- Server-approved pauses that cannot be used to slow the game down.
- Free plan first. Admission control stops new ranked runs before the daily quota runs out; games fall back to local play.
- Lua client library for the game side: HTTP client, ranked session, local progress, Defold bindings.
Games: Ah!Steroids, Sneak, ebakuw8.
CI=true pnpm install
npx wrangler d1 migrations apply scoreosis-dev --local
npx wrangler dev --port 8787
curl http://127.0.0.1:8787/v1/healthGetting started walks through a guest, a leaderboard and pointing a game at it.
npx wrangler d1 create scoreosis-production # put the id in wrangler.jsonc
npx wrangler d1 migrations apply scoreosis-production --remote --env production
openssl rand -hex 32 | npx wrangler secret put ADMIN_TOKEN --env production
pnpm deploy:productionDeploy to Cloudflare covers staging, origins, custom domains and updates. Other hosting explains what ties Scoreosis to Cloudflare and what running it elsewhere takes.
- The game creates a guest and starts a ranked run. Guest registration can finish on the menu; timed runs begin only on Play. The server checks disabled rulesets and reserves daily quota in one D1 batch, then returns a seed.
- The game steps its simulation at 60 Hz and sends each second of button inputs with a state checksum.
- The player's Durable Object checks timing and sequence, stores the inputs and replays them in the verifier.
- A checksum mismatch rejects the run. At the terminal tick, one transaction records the result, the BadgeTrip achievements and an outbox row.
- The outbox publishes the result to D1, where leaderboards read it.
Architecture has the details, the determinism rules and the cost per second of play.
The docs are published at walangstudio.github.io/scoreosis. The same files live in docs/.
| Doc | Covers |
|---|---|
| Getting started | Run it locally, create a guest, point a game at it |
| Deploy to Cloudflare | Staging and production, secrets, origins, custom domain |
| Configuration | Variables, secrets, bindings, fixed limits, game registration |
| Other hosting | What depends on Cloudflare and the alternatives |
| Adding a game | The ranked contract, determinism rules, packing, client flow |
| API | Routes, schemas, limits, errors |
| Architecture | Components, verification, determinism, cost |
| Security | Controls and known limits |
| Operations | Capacity, moderation, retention |
| CHANGELOG.md | Release notes |
Requires Node 24, pnpm 11, and Python 3.10+ with lupa for the Lua tests.
CI=true pnpm install
pnpm typecheck
pnpm lint
pnpm test # vitest inside workerd
python tools/test-lua.py # Lua client library under LuaJIT and Lua 5.1
pnpm docs:dev # the docs site at localhost:5173/scoreosis/Rebuild the VM after editing vm/sv.c (needs python -m pip install ziglang==0.16.0):
pnpm build:vmRepack a game after its ranked modules change:
node tools/pack-game.mjs sneakBump version in package.json, add a dated ## [x.y.z] entry to the CHANGELOG, merge to main, then tag:
git tag -a vX.Y.Z -m vX.Y.Z
git push origin vX.Y.ZThe release workflow checks the tag against package.json and the changelog, runs the full gate, and creates the GitHub release from the changelog entry. The deploy workflow ships every push to main to staging and every tag to production once Cloudflare credentials are set (how).
MIT. Copyright walangstudio.