This is a submission for the Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass
What I Built
WildQuest AI hands you a short outdoor "quest" based on how much time you have and where you are. Things like "find three different leaf shapes in 15 minutes" or "spot five sounds you can't see the source of." You pick a duration, an energy level, a place (park, garden, street, trail, backyard), up to three interests, and whether it's for kids, teens, or adults. A local Gemma model writes the quest.
The part I cared about most was keeping the screen small. The quest shows one step at a time in big text, the safety note stays pinned at the bottom, and there's a Phone Away mode that turns the screen almost black with just a countdown until you tap it. When you're done you write a quick note, rate your mood, and it goes into a journal.
It's for anyone who wants a nudge to go outside and actually pay attention, including families with kids.
When I tried it, the first thing I noticed was the wait: Gemma takes 10 to 25 seconds to write a quest, which feels long in an app meant to get you off the screen, so the plan is to generate the quest first and then put the phone away.
Demo
Video walkthrough: https://drive.google.com/file/d/1043eK0xYnJhAgDuEH2mEGAPt3ysrwWR-/view?usp=sharing
Code
šæ WildQuest AI
Hacktoberfest 2026 ā "Touch Grass" Challenge Get off the screen. Get outside. Complete a quest.
WildQuest AI generates short, personalized, safe outdoor quests (e.g. "find 3 different leaf shapes in 15 minutes") using an open-weight Gemma 3 model running locally via Ollama. No cloud. No paid APIs. No database server.
Stack
| Layer | Technology |
|---|---|
| Inference | Ollama + gemma3:4b (local) |
| Backend | FastAPI + Pydantic (Python 3.11+) |
| Frontend | React + Vite + Tailwind CSS |
| Storage | Browser localStorage (quest journal) |
| Eval | Python scripts in /eval
|
Project Layout
wildquest-ai/
āāā backend/ # FastAPI app, Pydantic schemas, quest logic
āāā frontend/ # React + Vite + Tailwind UI
āāā eval/ # Evaluation scripts for quest quality
āāā .gitignore
āāā README.md
āāā PROGRESS.md # Running log of what's done and what's next
Prerequisites
1 ā Install Ollama
# macOS (Apple Silicon) ā recommended
brew install ollama
# Or download the macOS appā¦How I Built It
Gemma 3 4B runs on my MacBook Air through Ollama. The backend is FastAPI with Pydantic, the frontend is React, Vite and Tailwind, and the journal lives in the browser's localStorage. There's no database and no account.
The model's output is never trusted directly. Every quest gets parsed and checked against a schema and a set of safety rules. If it fails, the backend sends the model the validation error and tries again, up to three attempts. If that still fails, it serves one of 8 hand-written seed quests, and the UI shows a badge saying whether you got Gemma or the fallback.
To see how reliable the model really was, I wrote a small eval that runs 40 fixed requests through the same generation code with the fallback switched off. On gemma3:4b at temperature 0.2:
- JSON, schema, safety and duration checks all passed on 40 of 40
- Variety score 0.85 (share of unique titles)
- Mean latency 12.2 s, p95 23.0 s
- 8 of the 40 needed a second attempt, so the model got it right first try about 80% of the time
That 100% is less impressive than it looks. It mostly shows that my validator was the limit. When I read the actual quests, I found things it let through: steps telling kids to look under rocks and logs, "run" and "race" steps on a trail, steps assuming you own binoculars or a magnifying glass, and safety notes that said "don't touch plants" right beside a step about feeling moss. Some titles repeated too ("Street Spectrum Search" came up three times). So I tightened the validator to catch those cases and added tests (119 now, all passing). I haven't re-run the full eval against the stricter validator, so the numbers above are from the first version.
One bug is worth admitting. I had gemma3:12b hard-coded in the backend but had only pulled the 4B. Every request quietly returned a fallback quest and the app looked completely fine. I only caught it because I'd added the source badge. The model name is now an environment variable.
What it doesn't do yet:
- Regex safety checks reduce risk. They don't guarantee it, and a clever phrasing can still slip through.
- I tested the full flow on my laptop, including Chrome's phone layout. I haven't used it on a phone outdoors, so I can't say whether the dark theme is readable in bright sun.
- Inference is local, but there's no service worker, so I'm not claiming offline support.
- If Ollama is down, the backend still burns through all its retries before falling back instead of failing fast.
- It only runs on my machine, so there's no hosted demo.
Why Does Open Innovation Matter?
A quest request says where you are and what you're paying attention to. I'd rather that never leave your laptop, and with a local open-weight model it doesn't. There's also no API key and no per-request cost, which matters for something you might use every day. That's also why I could run the 40-prompt eval over and over without thinking about a bill.
Being able to open the box helped as well. I knew exactly which model was running, I could swap it with one variable, and I could measure it directly instead of trusting a black box. The tradeoff is real: a 4B model on a laptop takes 10 to 25 seconds per quest. I worked around it with a loading state and the fallback, but a hosted API would have been faster.
Prize Categories
Best Use of Gemma. Gemma 3 4B runs locally through Ollama and generates every quest in the app, with schema validation, retries, and a measured eval.
Top comments (0)