A head-to-head math duel game for Rylee (3rd grade) — a web app that installs to a phone's home screen like a real app and works offline.
Two players hold one phone between them (the top half of the screen is upside-down). Both see the same problem with three answers. First correct tap scores a point; a wrong tap gives the point to the other player. First to 10 (or 5) wins. Play vs a friend or vs the bot.
https://hajidunn-coder.github.io/Homeschool/
(Requires the one-time Pages setup below the first time.)
- Open the link above in Safari.
- Tap the Share button → Add to Home Screen → Add.
- It now launches fullscreen from its own icon and works with no internet.
The repo is already public (free GitHub only serves Pages from public repos — don't make it private again or the site goes down). Then:
- GitHub → this repo → Settings → Pages → Source: Deploy from a branch → Branch: main, folder / (root) → Save.
- Wait ~1 minute; the site is live. Every later push to
mainredeploys automatically.
-
Game feel: 3-2-1-GO countdown, pop-in problems and answers, confetti bursts, combo banners ("3 IN A ROW!"), wrong-answer shake, match-point bar pulse, win-screen trophy + confetti rain, and synthesized sound effects (WebAudio, no audio files — works offline; mute button on the home screen, which also disables vibration). A daily play streak ("🔥 N-day streak") shows on the home screen; it grows by finishing at least one game a day.
-
Four sections: Addition, Subtraction, Multiplication (tables 1–12), Mixed. Answers are never negative; no division yet.
-
Difficulty tiers named by grade level (Normal ≈ strong 3rd-grade / Singapore-style standards, up to Hardest ≈ 6th grade), tuned in
TIER_CONFIGinjs/problems.js. -
Bot mode has two independent sliders: problem difficulty and bot speed. Bot timing/accuracy lives in
BOT_SPEEDSinjs/bot.js. -
Adaptive practice: every multiplication fact (and add/sub problem type) is tracked on-device. Facts Rylee misses quietly come back more often — capped at 40% of problems so it still feels like a game. Known-hard facts (6×8, 7×8, 6×7, 9×6, 7×9…) start pre-weighted via
HARD_FACT_BOOSTinjs/problems.js. -
Rylee's Progress screen: games/wins/streak, a 12×12 multiplication mastery heatmap, add/sub accuracy bars, recent games. All data stays in the browser on the device she plays on (localStorage) — nothing is uploaded.
There is no build step — the repo root is the site. Edit, push, done.
One gotcha: after changing any file, bump the cache version in sw.js (and APP_VERSION in js/main.js to match)
(rylee-math-v1 → v2 …) or phones that installed the app will keep the old
cached version.
The three tuning tables, all plain objects:
| What | Where |
|---|---|
| Problem ranges per tier | TIER_CONFIG in js/problems.js |
| Hard-fact starting weights | HARD_FACT_BOOST + TABLE_WEIGHT in js/problems.js |
| Bot speeds & accuracy | BOT_SPEEDS in js/bot.js |
npm test # unit tests (no dependencies, node --test)
npm install # once, for e2e
npm run test:e2e # Playwright: full duels on an emulated iPhone, offline PWA check- Add to Home Screen shows the icon and "Rylee's Math".
- Launches fullscreen (no Safari bars); rotation lock in portrait.
- No rubber-band scrolling or pinch-zoom during a duel; taps feel instant.
- Two simultaneous taps (one per player) award exactly one point.
- Airplane mode: app still launches and plays.
- After pushing an update: force-close the app, reopen twice (first open picks up the new service worker, second runs it).