What I Built
Most "touch grass" apps want you to look at them. I wanted one that wants you to stop.
Playground Game Maker takes a few facts (how many players, their ages, the stuff you have, the space, the minutes) and an open-weight model invents a game for exactly that mix. You tap Start playing, the screen locks behind a countdown, and the phone goes in your pocket.
Demo
Live: https://playground-game-maker.onrender.com/
It is a public demo on Render's free tier, running the real model (Qwen/Qwen3-8B through Tinker). The free tier sleeps when idle, so the first load can be slow, and the first game after waking can take up to 90 seconds. To protect my credits it allows 5 games per visitor per hour and 100 per day, and it does not save stats online (the stats page and CSV only work in the local version). The screenshots below are from my own computer.
The form: who is playing, what you have, how much space and time. The gear box takes free text.
A real game from Qwen3-8B ("Tennis Toss Tag"). It used only the chalk, cones and tennis balls I listed.
The phone locks behind a countdown. Elapsed and remaining always add up to the total.
Code
GitHub: https://github.com/DkHrR/playground-game-maker (MIT)
To run it locally: python app.py, then put your own model key in .env.
How I Built It
- Flask backend and one HTML page. No accounts, no names, no location, no tracking. In the local version everything is saved in a SQLite file on my computer. Game prompts go to Tinker, so nothing here is "offline".
- The model returns JSON: name, setup, up to 6 rules, how to win, a safety note.
- The lock screen runs on the real clock, so a sleeping screen does not break the countdown.
- The app counts screen seconds next to minutes outside. Outside minutes are self-reported by the player.
- Code written with Antigravity. The interface was designed in Google Stitch (not open source). The games come from Qwen3-8B, served through Tinker's sampling client (inference only, no fine-tuning).
- Hosting: Flask with gunicorn on Render's free tier. The model call goes out to Tinker. Keys live only in Render's environment settings, never in the repo. On my laptop the app used about 350 MB after warm-up and one game (peak 362 MB), which fits Render's 512 MB free tier.
Why an Open Model Mattered
A fixed list of games cannot cover "4 kids, two tennis balls, a small yard, 30 minutes". A model can. An open-weight 8B model also means no per-game price and no closed model deciding what is safe for kids. It also let me see exactly where a small model is weak, which led to the most useful part of the project: the safety rules live in code, not in the prompt.
What Went Wrong
- The model invents items. In my first 3-game check it added things I never listed: a plastic knife, a bucket, a finish line, foam. Telling it "use only the listed items" in the prompt did not fix it.
- Prompt rules are not safety. So the code removes unsafe items from what the player types before the model sees them (knife, scissors, matches, glass, rope and similar). The game card says "Removed unsafe item". The code also scans the model's reply and retries once, and it always adds "Tell a parent or adult where you are playing", because the model only sometimes remembered.
- It is not 100% reliable. In my real-model check scripts, between 70% and 80% of generations passed (7 of 9, 7 of 10 and 8 of 10 in three runs). Some failed and I do not know why. Once warm, most games took 5 to 17 seconds. The first game after starting the server took 30 to 90 seconds, and a few took close to a minute.
- Empty replies. Some calls ended with "No JSON object found". The most likely cause: Qwen3-8B "thinks" before it answers, and my 1,000-token limit could run out before the JSON started. I raised the limit to 2,500. I did not re-run my full check afterwards, so I cannot say it fixed every case.
- The games are playable, not great. One game's rules were three half-ideas that did not fit together: run to the center, pass the ball, bounce it over cones.
- A bug in the design code. The lock-screen countdown flipped between two numbers. I recorded my screen and found a hardcoded sample timer from the Stitch design running next to the real one. Deleting it fixed it.
- Another leftover. After tapping an age chip, the age box showed the icon name ("All agescheck_cir..."). My screenshots use the default age.
- A fake test result. My last scripted 20-call test hung, and Antigravity then ran it against my mock engine: 20 of 20 "passes" in 0.00 seconds. I threw those results away because they came from a fake model.
- Free credits. Backboard's free credit could not pay for chat models, so I moved to Tinker.
The code removed the unsafe items I typed (jump rope, knife, air gun) before the model saw them, and it added the parent reminder. The rules and note still mention a chalkboard and foam balls.
What I Did Not Do
I did not field-test this outside with other people, so I have no play data, ratings, or "minutes outside" to report. The checks above are lab tests on my own laptop.
Prize Categories
- Tinker: the games are generated by Qwen3-8B on Tinker, inference only.
-
Render: the demo runs as a Render free-tier web service.
render.yamlis in the repo.
AI Disclosure
Code built with Antigravity, interface designed with Google Stitch, games generated by Qwen3-8B, and this post drafted with Claude and edited by me.




Top comments (1)
Official Platform Update
Security protocols have been updated for all developer accounts.
Some comments have been hidden by the post's author - find out more