DEV Community

Cover image for QuestSloth: Local Gemma Turns Lecture Notes Into a Dungeon Quiz
Arjan kc
Arjan kc

Posted on

QuestSloth: Local Gemma Turns Lecture Notes Into a Dungeon Quiz

Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady Submission πŸ¦₯

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady

What I Built

QuestSloth automates a chore teachers dread β€” turning dry syllabus notes into quizzes β€” and makes studying feel like a tiny dungeon crawl.

  1. Teacher Forge β€” paste lecture notes. Open-weight Gemma 2 2B runs locally in the browser via WebLLM and emits a strict quest.json (quest title, boss name, five MCQs, answers, explanations).
  2. Student Dungeon β€” play that pack with no AI inference: HP bars, combos, difficulty modes, consumable powers, achievements, procedural SFX + battle music. Correct answers hurt the boss; misses hurt you and show the explanation.

Slow and steady / International Sloth Day: the teacher stops inventing five MCQs by hand; students get a boss fight instead of a worksheet. Notes never leave the device.

Demo

Live app: https://arjankc.github.io/QuestSloth/

  • Forge needs WebGPU (recent Chrome/Edge). First Gemma download is ~1.5GB for the f16 build (or ~2.5GB if your GPU lacks shader-f16 and Forge falls back to q4f32) and caches in the browser.
  • Dungeon works without loading any model β€” try Play sample quest immediately. Unmute the header speaker for lobby pad / battle BGM / SFX.
  • Forge Play in Dungeon hands the pack over via sessionStorage (plus a short local quest stash).

Code

Repo: https://github.com/arjankc/QuestSloth

GitHub logo arjankc / QuestSloth

Browser-local Gemma turns lecture notes into dungeon quizzes (Hacktoberfest 2026 Week 3)

QuestSloth

Turn lecture notes into a dungeon-crawler quiz β€” entirely in the browser.

Built for Hacktoberfest Open-Source AI Challenge: Week 3 β€” Slow and Steady. Teachers paste notes; local Gemma 2 2B (via WebLLM) forges a quest.json. Students fight the boss by answering β€” no inference on the play path.

Why open weights?

  • Notes never leave the device (Forge runs on-device WebGPU).
  • No OpenAI/Claude bill for every quiz.
  • Students only need the JSON file β€” the dreaded β€œwrite five MCQs by hand” chore becomes a paste β†’ download.

Stack

  • Vite + React + TypeScript + Tailwind CSS
  • @mlc-ai/web-llm Β· prefers gemma-2-2b-it-q4f16_1-MLC-1k (~1.5GB); auto-falls back to gemma-2-2b-it-q4f32_1-MLC (~2.5GB) when WebGPU shader-f16 is missing
  • Static host: GitHub Pages (base: '/QuestSloth/', HashRouter)

Modes

Mode Route AI?
Teacher Forge #/forge Yes β€” loads Gemma, emits strict quest JSON
Student Dungeon #/dungeon No β€” upload JSON, forged handoff, sample, or
…

Worth a look:

  • src/lib/webllm.ts β€” Gemma load + f16 feature probe + q4f32 fallback + low-temperature JSON generation
  • src/lib/questSchema.ts β€” Zod validation + JSON Schema for constrained decoding
  • src/lib/difficulty.ts / src/lib/powers.ts / src/lib/progress.ts β€” Easy/Normal/Hard, Hint/Shield/Focus, XP + achievements
  • src/lib/audio.ts β€” procedural Web Audio (no sound files)
  • src/pages/Forge.tsx / src/pages/Dungeon.tsx β€” the two halves of the product

How I Built It

Constraints drove the stack: ~30GB free disk, 4GB VRAM, no Python/Ollama/Docker. Everything is a static SPA on GitHub Pages.

flowchart LR
  notes[LectureNotes] --> forge[TeacherForge]
  forge --> webllm[WebLLM]
  webllm --> gemma[Gemma2_2B]
  gemma --> pack[quest.json]
  pack --> dungeon[StudentDungeon]
  dungeon --> fight[BossFight]
  • Vite + React + Tailwind for routing and game state (HashRouter, base: '/QuestSloth/')
  • @mlc-ai/web-llm prefers gemma-2-2b-it-q4f16_1-MLC-1k (~1583MB VRAM). On GPUs that don't advertise WebGPU shader-f16, Forge probes adapter.features and loads gemma-2-2b-it-q4f32_1-MLC instead (~2.5GB) β€” same Gemma 2 2B IT weights, no Canary flags required. If the probe misses, a create failure matching shader-f16 triggers one automatic retry.
  • Strict JSON: temperature: 0.15, WebLLM response_format: { type: "json_object", schema }, then Zod parse + one repair retry
  • Code-split Forge so the Dungeon route never pulls WebLLM (phone-friendly play)
  • Game loop: difficulty tables, one-power loadout (Shield/Focus unlock at level 2), combos, level combat bonuses, achievements, CSS battle FX, lobby pad + battle BGM that speeds up on enrage

Small models love to ignore free-form prompts. Constrained decoding plus a validator kept the dungeon from crashing on bad packs β€” the same lesson browser-Gemma builders keep rediscovering (Touch Soil is a good peer example of schema-shaped WebLLM output).

The f16 fallback was a live-demo fix: WebLLM's f16-1k build hard-requires shader-f16, and shipping only that ID meant some Chrome/Edge users (especially integrated GPUs) got a Canary flag error instead of a quiz. Probe + q4f32 keeps Best Use of Gemma reachable on more hardware β€” the same pattern in-browser LLM posts keep hitting (WebGPU present β‰  WebGPU usable; ship a quantization per backend).

Why Does Open Innovation Matter?

  • Classroom notes stay on the laptop. Forge never posts syllabus text to a paid API.
  • Zero inference bill after the one-time model cache β€” important if you forge quizzes every week.
  • Students only need the JSON file. Schools with locked-down or low-end devices can still play the dungeon.
  • Swappable brain. The model id is one string in webllm.ts; any WebLLM Gemma (or other open weight) can replace it.

Lazy payoff: paste notes β†’ download (or hand off) quest β†’ share with the class. The chore of inventing five decent MCQs disappears.

Prize Categories

  • Best Use of Gemma β€” Teacher Forge runs open-weight Gemma 2 2B in-browser via WebLLM to generate every quest pack.

Top comments (0)