Spaces:
Sleeping
Sleeping
| title: Doodle Duel | |
| emoji: ๐จ | |
| colorFrom: pink | |
| colorTo: blue | |
| sdk: gradio | |
| sdk_version: 6.16.0 | |
| app_file: app.py | |
| pinned: false | |
| license: mit | |
| short_description: Draw a word, a small vision model guesses it in real time | |
| tags: | |
| - build-small-hackathon | |
| - thousand-token-wood | |
| - track:wood | |
| - achievement:offbrand | |
| - achievement:llama | |
| # ๐จ Doodle Duel | |
|  | |
| Pictionary against an AI vision model โ built for the Hugging Face **Build Small Hackathon** (Chapter Two: *An Adventure in Thousand Token Wood*), track: **Thousand Token Wood**. | |
| You pick a difficulty, choose a word, draw it on the canvas, and a small vision model (โค32B) watches your canvas. Every few seconds it shouts its top guesses and shows its reasoning. The moment it recognises your drawing, you score โ faster means more points. Stump it until time runs out and *you* win the round. | |
| **The AI's vision is the whole game.** | |
| ## โถ๏ธ Demo & play | |
| - **Watch the demo:** [youtube.com/watch?v=2icnvsOzWGM](https://www.youtube.com/watch?v=2icnvsOzWGM) | |
| - **Play it live:** [build-small-hackathon/doodle-duel](https://huggingface.co/spaces/build-small-hackathon/doodle-duel) | |
| - **Post on X:** [x.com/AwsheshNath](https://x.com/AwsheshNath/status/2066533146330538328) | |
| ## ๐ฅ Team | |
| - **[AwsheshNath](https://huggingface.co/AwsheshNath)** โ solo submission. Registered for the hackathon and a member of the `build-small-hackathon` org. | |
| ## โณ First time here? Warm up the AI (please read) | |
| The vision model runs on a Hugging Face **Inference Endpoint that scales to zero when idle**. So if nobody has played for a while, the **first guess triggers a cold start (~1โ2 minutes)** while the model spins back up. This is normal โ it only happens on the first request after inactivity; after that, guesses come every few seconds. | |
| **How to tell if the AI is ready** โ watch the status pill right under the title: | |
| | Pill | Meaning | | |
| |------|---------| | |
| | ๐ก *Connecting to the AIโฆ* / *Waking the AIโฆ (cold start, up to ~2 min)* | Still warming up โ hang on, don't worry | | |
| | ๐ข *AI ready* | Good to go โ the robot will start guessing within seconds | | |
| | ๐ด *AI offline โ retryingโฆ* | Temporary endpoint hiccup โ give it a moment | | |
| **Tip:** you can start drawing while it warms up. The instant the pill turns ๐ข *AI ready*, the robot reads your current canvas and begins guessing โ no need to redraw. | |
| ## How it plays | |
| - Pick a difficulty: **๐ข Easy** (everyday objects), **๐ก Medium** (everything), **๐ด Hard** (brands, famous people, characters, landmarks) | |
| - Choose one of three secret words | |
| - **Draw** on the canvas. A 2-minute countdown ring ticks down | |
| - **Drawing tools** (canvas toolbar): adjustable **brush size and colour**, **eraser**, **undo / redo**, **clear**, and zoom โ so you can sketch rough or detailed | |
| - The robot looks at your canvas every few seconds and guesses โ even if you've stopped drawing, so it keeps trying fresh words it hasn't guessed yet | |
| - **Right-hand panel** shows the robot's live reasoning ("I see a round shape with legsโฆ") | |
| - **Guess matches โ you score** (time-scaled + streak bonus) | |
| - **Timer runs out โ you stumped the robot.** Pick a difficulty again to keep going | |
| - **Hint button** reveals letters of the answer to the robot (costs points) | |
| - Streak and best-score tracked across rounds | |
| ## ๐ฎ Game modes โ and why Hard mode is the best part | |
| - **๐ข Easy** โ everyday, clearly drawable things (animals, food, vehicles, household objects). | |
| - **๐ก Medium** โ the full word bank, easy and hard mixed. | |
| - **๐ด Hard** โ **the highlight of the game.** The answers are brands, famous people, fictional characters, and landmarks โ things you can't draw literally. The model has to **think laterally from the clues you give it**: jersey numbers, initials, logos, symbols, silhouettes, even song-title hints. It's not shape-matching any more; it's reasoning. | |
| **Amazing examples (some shown in the demo video):** | |
| - โ๏ธ Sketch a cue for **"Rap God"** โ the model reasons its way to **Eminem** ๐ค *(demonstrated in the [YouTube demo](https://www.youtube.com/watch?v=2icnvsOzWGM))* | |
| - โ๏ธ A swoosh โ **Nike** | |
| - โ๏ธ A web and a mask โ **Spider-Man** | |
| - โ๏ธ Jersey **#7** with **"CR"** โ **Ronaldo** | |
| Watching the right-hand "Robot's thoughts" panel reason through these out-of-the-box clues is the most fun part of Doodle Duel. | |
| ## ๐ง Under the hood (technical) | |
| - **Model:** **Qwen3.6-27B** (vision-language), 4-bit quantized โ served file `Qwen3.6-27B-Q4_K_M.gguf` plus an F16 multimodal projector (`mmproj-F16.gguf`) for image input. ~27B parameters, comfortably within the hackathon's โค32B "small model" rule. | |
| - **Serving:** runs on **llama.cpp** (CUDA `server`) behind an **OpenAI-compatible Hugging Face Inference Endpoint** (scale-to-zero). The endpoint runs the official **`ghcr.io/ggml-org/llama.cpp:server-cuda`** container, serving model id `Qwen3.6-27B-Q4_K_M.gguf` (auto-detected from `/v1/models`). | |
| - **Per guess:** the canvas is sent as a base64 PNG together with a Pictionary prompt that includes the answer's **letter count, word count, and a revealed-letter dash pattern** (so guesses are constrained to the right shape). The model replies in exactly two lines โ `THINK:` (the reasoning you see live) and `GUESS:` (top 3, most likely first). | |
| - **Token budget:** native chain-of-thought is disabled for speed and the response is capped at 200 output tokens, so each guess runs on roughly **~500 tokens total** โ the entire point of the *Thousand Token Wood* track. | |
| - **Sequential, rate-limited guessing:** at most one in-flight request per session and โฅ4 s between guesses, so the Space never floods (or 429s) the endpoint. | |
| ## ๐๏ธ Bonus quests earned | |
| - ๐ฆ **Llama Champion** โ the model runs through the **llama.cpp** runtime. The Hugging Face Inference Endpoint uses the official **`ghcr.io/ggml-org/llama.cpp:server-cuda`** container, serving `Qwen3.6-27B-Q4_K_M.gguf`. | |
| - ๐จ **Off-Brand (custom UI)** โ the entire interface is a hand-built dark "arcade" theme (custom `style.css`, custom HTML topbar, countdown ring, robot reasoning panel and chip bubble) that pushes well past the default Gradio look. | |
| ## Model configuration / self-hosting | |
| Needs an OpenAI-compatible vision endpoint. Set these Space secrets: | |
| | Secret | Example | Notes | | |
| |--------|---------|-------| | |
| | `MODEL_BASE_URL` | `https://your-endpoint` | vLLM / llama.cpp server | | |
| | `MODEL_NAME` | `auto` | auto-detects from `/v1/models` | | |
| | `MODEL_API_KEY` | `your-key` | optional, for authenticated endpoints | | |
| No `MODEL_BASE_URL` โ runs in **mock mode** (random guesses, for UI testing). | |
| Recommended model: any vision-capable โค32B model. **This Space runs `Qwen3.6-27B-Q4_K_M.gguf`** (Qwen3.6-27B, 4-bit `Q4_K_M` quant) on llama.cpp. | |
| ## Tuning | |
| | Var | Default | Meaning | | |
| |-----|---------|---------| | |
| | `ROUND_SECONDS` | 120 | Seconds per round | | |
| | `GUESS_MIN_INTERVAL` | 4.0 | Min seconds between AI guesses | | |
| | `POLL_INTERVAL` | 5.0 | Background guess cadence | | |
| | `BRUSH_SIZE` | 4 | Default brush width | | |
| ## Files | |
| - `app.py` โ Gradio UI: canvas, countdown timer, word choices, controls, status pill | |
| - `game.py` โ round/clock/guess/scoring/hint logic | |
| - `vision_client.py` โ sends canvas image to model, parses THINK/GUESS response | |
| - `visuals.py` โ timer ring, robot speech bubble, reasoning panel, win/lose | |
| - `config.py` โ word bank (1000+ words, 18 categories, easy/hard tagged) + timing config | |
| - `style.css` โ bright playful theme | |
| --- | |
| Been a while since I posted, but I built something fun and wanted to share it. | |
| I made a little game called **Doodle Duel** for the Hugging Face Build Small Hackathon. The idea is simple: you draw something on a canvas, and a small vision model (Qwen3.6-27B, under 32B parameters) watches what you're drawing and tries to guess it in real time โ like reverse Pictionary against an AI. | |
| What I find cool about it is that you can actually see the model's reasoning as it watches your strokes. It'll say things like "I see a round shape... maybe a wheel? a ball?" and keep guessing even if you stop drawing, trying words it hasn't said yet. There are easy, medium, and hard word modes, a hint system, and a 2-minute timer โ and in Hard mode it'll reason its way from a "Rap God" doodle all the way to **Eminem**. | |
| The whole thing runs on roughly ~500 tokens per guess, which was a genuinely fun constraint to design around. | |
| Built for the **[Build Small Hackathon](https://huggingface.co/spaces/build-small-hackathon/registration)** โ Track: Thousand Token Wood. | |