An open API service indexing awesome lists of open source software.

https://github.com/garnertb/geo-quest


https://github.com/garnertb/geo-quest

Last synced: 2 months ago
JSON representation

Awesome Lists containing this project

README

          

# Geo Quest

A fast, visual geography learning game for kids ages 7–16.

Built with **Next.js 16 (App Router, static export)**, **React 19**, **TypeScript**, **Tailwind v4**, **Zustand**, **Framer Motion**, and **Tauri 2**.

## Run

### Web
```bash
npm install
npm run dev # http://localhost:3000
npm run build # produces ./out (static export)
npm run lint
```

### Desktop (Tauri 2)
```bash
npm run tauri:dev # launches native window pointed at the Next dev server
npm run tauri:build # produces a native installer (macOS/Windows/Linux)
```
Requires Rust toolchain (`cargo`). The web build always works without it.

## Architecture

```
src/
app/ Next.js App Router pages (/, /topics, /play, /summary, /mastery)
components/
ui/ Buttons, cards, progress (shadcn-style primitives)
maps/ USTileMap, ContinentMap (SVG)
content/seed.ts Static content packs: continents, US states, US capitals
engine/
learning/sr.ts SM-2-lite spaced-repetition + mastery tracking (pure)
session/builder.ts Question generation, session planner, scoring
store/game.ts Zustand store + localStorage persistence
types/domain.ts Shared TS types (ContentPack, GeoItem, Question, …)
lib/ Utilities (cn, shuffle, useHydrated)
src-tauri/ Rust Tauri 2 shell
```

### Learning engine
- Each `(item, questionType)` pair has its own `LearningState`: mastery 0–1, ease factor, current streak, next-review timestamp, recent attempts.
- `applyAnswer` updates state using an SM-2-lite rule: correct answers extend the interval by `ease`, wrong answers reset the interval and resurface the item within minutes.
- `bucketStates` partitions items into **due / weak / new / strong** for session planning.
- Sessions pull **60% due, 25% weak, 15% new**, falling back to fill if a bucket is short.

### Content packs
- A `ContentPack` declares `topic`, `items`, and `supportedQuestionTypes`.
- Items reference visual assets by id (`shape`, `tile`). The map components own the actual rendering, so packs can be added later without touching the learning engine.
- The MVP uses a stylized US tile-map and simplified continent silhouettes. Swap in GeoJSON-backed components later by replacing `USTileMap` / `ContinentMap`.

### Persistence
- `localStorage` via `zustand/middleware/persist`. Works in both the web app and Tauri webview.
- Single local profile in MVP; the store is shaped to allow multiple profiles later.

### Game loop
1. **Home** — first-time players start with **Start your quest** (map pick + 5-question focused quest), then transition to **Today’s Quest** and dynamic recommendations.
2. **Daily Quest** (`/play`) — 10 mixed-topic questions with a non-required speed bonus, combo multiplier, animated correct/wrong feedback, and a teaching map for misses.
3. **Summary** — stars (based on accuracy), XP, best combo, improved items, items to review.
4. **Topic picker** — jump directly into continents / states / capitals.
5. **Mastery map** — visual progress: mastered states light up green, weak ones tint red.

## MVP scope
✅ Home · Topics · Play (10-question Daily Quest) · Summary · Mastery
✅ Speed bonus, combo, XP, streak, daily goal, star rating
✅ Correct/wrong animations and teaching feedback on misses
✅ Reusable learning engine (SR + mastery)
✅ Content-pack data model with seed content
✅ Local-first persistence
✅ Tauri 2 desktop wrapper
🚫 Achievements (intentionally out of scope)

## Design decisions
- **Tile-map for US states.** Instantly recognizable, scales perfectly, and lets us highlight any state precisely. Real GeoJSON outlines can be dropped into the `USTileMap` component later.
- **No mascot.** Polish carries the game feel: large cards, smooth transitions, satisfying button physics, animated stars.
- **Speed bonus, not speed gate.** Younger players are never punished by the timer.
- **Distractor groups by region.** Wrong-answer choices tend to be regional neighbors, making questions challenging without random difficulty.