Web app · Game
Erdus Games, an online guessing game platform
Erdus Games is a guessing game platform I designed and built: recognize a video game, a movie, a TV series, an anime, a flag, a song or a Pokémon from an image that slowly reveals itself, from successive clues or from an attribute comparison. A static JavaScript site that can be installed on a phone.
- JavaScript
- Canvas
- PHP
- PWA
The idea
Web guessing games, in the spirit of guessthe.game or framed.wtf, often stick to a single theme and a single mechanic. The idea behind Erdus Games: bring nine themes and three ways to play together on one site, with a daily challenge that is the same for everyone.
All of it without a database: a static site, a small PHP proxy for the APIs and JSON files on the server. Free play needs no account; the daily challenge, the marathon and challenges between friends only require a nickname and a sign-in link sent by email, with no password.
- Nine themes: video games, movies, TV series, anime and manga, flags, music, audio clips, Pokémon, characters
- The same item for everyone, every day
- No database, no password
- Installable on a phone (PWA)
Key features
Hidden image
The image reveals itself slowly and you have to recognize it before it is sharp. Adjustable speed and several effects: pixels, blur, zoom-out or random.
Clues
Each mistake reveals a new image and a text clue (year, genre, platform, country…), with autocomplete and color-coded guesses. For audio, the clip gets longer after each mistake, from 1 to 16 seconds.
Comparison
No image: each guess is compared with the mystery item attribute by attribute, in green, yellow or red, with arrows for ordered values. Ten lives.
Daily challenge
The same item for everyone, one attempt per theme per day, a result you can share as emojis, a streak of consecutive days and an archive of past challenges.
Daily marathon
All nine themes in a row, with a timer that only counts playing time, the option to resume and a dedicated leaderboard.
Challenge between friends
A six-character code and an invitation link: everyone plays the same five items, up to fifty players, with a leaderboard for the game.
Leaderboards, badges and stats
Leaderboards by theme and period, a circle of friends, twenty badges, personal statistics and a share image generated in the browser.
Reminders and installation
Installation on the home screen and anonymous Web Push reminders at the time you choose: daily challenge ready, streak about to expire.
Technical choices
A static site in HTML, CSS and JavaScript with no framework, plus a few PHP scripts. No database and no client-side library.
Vanilla JavaScript and Canvas
The reveal effects are drawn in a canvas. In production, eighteen scripts are concatenated and minified into a single file: the first screen loads about 135 KB, and the embedded lists are loaded on demand.
Two sources per theme
RAWG, TMDB, AniList, Deezer, PokéAPI, flagcdn, Wikidata… If the main source goes down or hits its quota, the fallback source takes over for five minutes.
A PHP proxy that protects the keys
API keys stay on the server. The proxy only accepts requests from the site, only relays allowed paths and parameters, rate-limits by IP address and enforces a daily budget per upstream service.
Passwordless sign-in
A nickname and a single-use email link, valid for fifteen minutes. Syncing between devices merges a JSON snapshot; the server only keeps the latest snapshot and the email address.
Caching and offline
A stale-while-revalidate service worker for instant display, assets cached for a year under versioned URLs, Cloudflare Turnstile bot protection and a strict CSP.
Tests and releases
End-to-end Playwright tests on desktop Chrome and Pixel 5, with a fully mocked network. Each push runs the build, an SSH deployment and a check of what is actually published.
Technologies
- JavaScript
- Canvas
- PHP
- PWA
- Service worker
- Web Push
- Cloudflare Turnstile
- Playwright
- esbuild
- GitHub Actions
Challenges and lessons learned
Staying within API quotas
Response caching, a daily budget per service and automatic failover to the fallback source. Daily challenge lists are frozen until midnight and archived: the same items and the same images for everyone, even on later days.
Releasing without cache traps
The CDN keeps JavaScript and CSS files for a year. Each version therefore gets a new URL, and the deployment uploads the bundle before the page and the service worker, so a page never references a missing file.
Browser differences
Safari does not support filters on canvas, so the blur effect uses a CSS filter. Android ignores the volume of audio elements, so it is set through the Web Audio API.
Securing link-based sign-in
A sign-in link is never exchanged without the player knowing: the request carries a secret tied to the browser and, failing that, the site asks for confirmation. Without either, the server refuses the exchange.
Errors people can understand
No raw error ever reaches the player: being offline, a timeout or a service outage each produce a plain message and a “Retry” button.
Going further
- Live site: game.erdus.fr (opens in a new tab)
- Related service: Streaming development
- Other projects: Cadence, Carnet
- All projects
A mini-game or a tool for your community?
Shared challenges, leaderboards, API integrations: let's talk about your project in thirty minutes.
A 30-minute video call, no commitment, to frame your needs.