- TypeScript 83.6%
- HTML 14.5%
- Python 1%
- JavaScript 0.5%
- Dockerfile 0.2%
- Other 0.2%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .forgejo/workflows | ||
| backend | ||
| docs | ||
| frontend | ||
| .editorconfig | ||
| .gitignore | ||
| AGENTS.md | ||
| CONTEXT.md | ||
| docker-compose.yml | ||
| Dockerfile | ||
| pyproject.toml | ||
| README.md | ||
| uv.lock | ||
Robbies Speelland
A recreation of Robbies Speelland, the AmbraSoft kids' games site from 2008, brought back as one app instead of a graveyard of dead Flash links.
- Eight games have a native HTML5 port (no Flash, no plugin): Robbies
Speurhondenspel (Canvas2D, with a level editor and a backend for saving and
sharing custom levels), Kleurboek, Schuifpuzzels, Legpuzzels, Sudoku,
Dansspel, Penaltyspel and Valwoord — see
docs/conversion-tracker.mdfor the up-to-date list as more get ported. - Every other game (Robbies Avontuur, Tafel Bowlen, ...) still runs the
original
.swfvia Ruffle, reachable from the recreated AmbraSoft menu at the site root.
The project has two parts:
frontend/— an Angular + Tailwind app. Builds tofrontend/dist, ships as a container (frontend/Dockerfile).backend/— a Python (Flask) API for storing and serving Speurhondenspel levels.
Legal / attribution
All games, characters and artwork are © 2008 AmbraSoft. This project is
an unaffiliated fan/archival effort: the .swf files and menu assets come
from the Robbies Speeleiland item on the Internet
Archive (uploaded by
Michielvde, 2021), not modified beyond what's noted in docs/, and are
served here for preservation, not for profit. The site itself carries a
matching notice in its footer. If you fork or redeploy this project, keep
that attribution intact and don't use it commercially — see
docs/games/speurhondenspel/reverse-engineering.md and
docs/games/speurhondenspel/assets.md for how the original assets were
extracted.
Routes
/— the AmbraSoft menu (recreated background art, speech bubble, image-map)./speurhondenspel— the native Speurhondenspel./speurhondenspel/:name— a specific (possibly remixed) Speurhondenspel level, used by the editor's share links./kleurplaat,/schuifpuzzel,/legpuzzel,/sudoku,/dansspel,/penalty,/valwoord— the other native ports. Old/spel/<slug>links to these redirect here automatically./spel/:slug— every other, still-Ruffle-hosted game. Some have an oud/nieuw pick (Robbies Avontuur, Letter Doolhof) or a numbered puzzle set (seeSwfCollectioninfrontend/src/app/game/swf-games.ts)./verborgen— games that never had a tile on the original AmbraSoft menu, only reachable here./editor— the Speurhondenspel level editor.
Frontend
cd frontend
npm install
npm start # dev server at http://localhost:4200
npm run build # production build, output goes to frontend/dist
The dev server talks to http://localhost:5001 (the local backend). A
production build's backend URL and menu theme are set at container start,
not build time — see Deployment below and
frontend/src/app/runtime-config.ts.
Ruffle is pulled in as an npm dependency (@ruffle-rs/ruffle) and copied into
the build output automatically; there's nothing to update by hand.
.swf files, Sudoku's puzzle XML, and the menu's background art live under
frontend/public/{flash,xml,menu} and ship as static assets — see
frontend/src/app/game/swf-games.ts for how each game maps to its file(s).
Backend
Requires Python >=3.11 and uv.
cd backend
uv sync
uv run python app.py # dev server at http://localhost:5001, not for production use
A local worlds_data.db SQLite file is created automatically on first run. To
use Postgres instead, set DATABASE_URL (see backend/.env.example).
Deployment
Both halves ship as containers, meant to sit behind your own reverse proxy (routing both under one domain, plus
whichever of the backend's own paths — /xml, /add_world, /ping — it needs to see).
-
Frontend:
frontend/Dockerfilebuilds the Angular app and serves it via nginx.API_ENDPOINT/MENU_THEMEare read at container start (not build time — seefrontend/src/app/runtime-config.ts), so the same image works across deployments without a rebuild.docker build -t robbie-frontend ./frontend docker run -d -p 8080:80 -e API_ENDPOINT= -e MENU_THEME=zomer robbie-frontendAPI_ENDPOINTempty (the default) means relative/same-origin requests — the usual case behind a reverse proxy that also routes the backend's paths.MENU_THEMEis one ofzomer/kerst/sinterklaas(frontend/src/app/menu/menu-theme.ts), defaulting tozomerif unset. -
Backend:
Dockerfile(repo root) builds a container running the API behind gunicorn.docker build -t robbie-backend . docker run -d -p 5001:8080 -e DATABASE_URL=... -e SESSIONKEY=... robbie-backend
Or, for the whole stack locally: docker compose up. Set SESSIONKEY
(backend) and API_ENDPOINT/MENU_THEME (frontend) in a .env file at the
repo root to override the defaults in docker-compose.yml.
CI/CD
.forgejo/workflows/build-push.yml builds and pushes both images on every push to master, to
git.sbdevelopment.tech/sbdeveloper/robbie-online-{frontend,backend} (tagged :latest and :<commit-sha>).
- Each half only rebuilds if its own files changed (diffed against the push's base commit —
frontend/for the frontend image;backend/, the rootDockerfile,pyproject.toml, oruv.lockfor the backend image). [skip ci]in a commit message skips the whole workflow;[force ci]rebuilds and pushes both regardless of what changed (useful for the very first run against a fresh registry, or after changing the workflow itself).- Needs
REGISTRY_USER/REGISTRY_PASSWORDset as repo secrets, and adocker-clirunner registered on this Forgejo instance.