Swipenor: if the client computes the score, what does the server trust?
ActiveA swipe-based true/false trivia experiment; the real subject is not the game but making a client-computed score verifiable through a signature.
- Started
- July 2026 — Ongoing
Technologies
The mechanic is simple: a card arrives, swipe right for “True”, left for “False”. Content is tailored by age group (4–9, 10–17, 18+), correct answers score, streaks earn a bonus, and results land on global and per-age leaderboards. The part that is not simple is who owns the score.
What I tried
The game loop runs on the client at 60fps (reanimated worklets plus gesture-handler), so the client naturally computes the score. A server that believes that number blindly turns the leaderboard into garbage on day one.
The model under test is signed-client: the server issues a server_nonce
per session, the client HMACs the score with it, and the API both sanity-checks
the value and verifies the signature. The scoring constants are not baked into
the client either — 100 points per correct answer, a streak threshold of 3, a
+25 streak bonus — they all come from GET /config so client and server never
drift apart.
What came out of it
Four separate repositories in one workspace: game (Expo SDK 57, React Native,
TypeScript), api (Laravel 13, PostgreSQL 16, Redis), admin (Filament,
running against the shared database but never migrating it — the API owns
the schema) and a marketing page built with Astro. The core loop works end to
end: swiping, scoring, streak bonus, global and per-age leaderboards.
Why it continues
The open ends are around the game rather than in it: ad integration and the one-time “remove ads” purchase, store assets, and the release process. How well the signing model holds up against real users is something only shipping will tell.