Skip to content

Repository files navigation

⚡ Git Battle

Git Battle — learn Git by typing the commands: animated codebook, typing practice and a live multiplayer battle

Learn Git commands by typing them for real — an animated codebook, solo practice with three difficulties, and a real-time multiplayer battle with power-ups. Bilingual (Español / English), with light & dark themes and sound effects.

Run

npm install
npm start

Open http://localhost:3000. The server binds to 0.0.0.0, so other players on your network can join at http://<your-ip>:3000.

Deploy to Cloudflare Pages (static, no server)

Cloudflare Pages serves only static files — there is no Node server — so multiplayer there runs over the InsForge host-authoritative transport (see Multiplayer transports). The build just assembles public/ into dist/ and injects the InsForge config:

npm run build          # -> dist/  (also copies insforge-config.js if present locally)

Option A — direct upload from your machine (uses your local public/js/insforge-config.js):

npm run deploy         # npm run build && wrangler pages deploy dist --project-name git-battle

Option B — git-connected build (Cloudflare clones the repo and builds). Since insforge-config.js is gitignored, provide the config via environment variables so the build generates it:

Cloudflare Pages setting Value
Build command npm run build
Build output directory dist
Environment variable INSFORGE_URL your https://<appkey>.us-east.insforge.app
Environment variable INSFORGE_ANON_KEY your anon_… key

The anon key is browser-safe (Row-Level-Security-protected) and is shipped to every browser anyway, so it is fine as a Cloudflare env var. Never put the uak_ admin key here. Without any config the site still builds and Practice/Learn work — only multiplayer needs the backend.

Routing is hash-based (#learn/…), so no _redirects file is needed.

Modes

📖 Learn — the Git Codebook

An interactive reference of 28 commands grouped into chapters (Getting Started, Branching, Remotes, History & Undo, Advanced, Pro Tools) plus a Guides & Best Practices chapter.

  • Syntax-highlighted commands and an animated diagram of what each one does (.git appearing on init, files sliding into staging on add, branches diverging and merging, commits flying to the cloud on push, three messy commits collapsing into one on squash…).
  • A real-life anecdote for every command.
  • Guides: Squash vs Merge vs Cherry-pick (when to use / when NOT to), .gitignore (why it matters + quick generation via the toptal generator), and Good commits (do / don't).
  • Progress tracking (saved in your browser): you confirm you've read an entry by clicking Mark as read (opening it only sets a 📍 bookmark to resume where you left off), so a ✓ really means you read it. Each entry can be toggled read/unread.
  • Every entry is deep-linkable as #learn/<id> — failed questions link straight to the relevant page.

📚 Practice (single player)

5 lessons, each playable at 3 difficulties:

  • Easy — the command is shown with one part blanked out; type the missing part (or the full command).
  • Normal — you only get the description plus small hints; type the full command.
  • Hard — only the description is shown; type the full command from memory.

Placeholders like <file>, <name>, "<message>" accept any value. When you miss a question you get a link to learn it in the codebook. Each difficulty is tracked per lesson: ✓ done, ★ perfect. Lessons unlock progressively — finish one to open the next.

🏆 Achievements

A gamification section (all in your browser): a daily streak counter and 12 medals — each with its own SVG badge, greyed until earned, some hidden until unlocked. Earn them by practicing, reading the codebook, keeping streaks, and winning multiplayer (including a hidden "win without power-ups"). Unlocks pop a toast, and each earned medal has a Share button.

⚔️ Multiplayer (2–6 players, real-time)

  1. One player clicks Create room and shares the 4-letter code.
  2. Others Join with the code; the host sees the live player list and configures the match, then presses Start (2–6 players).
  3. Everyone answers the same question each round — speed-based scoring: every correct answer scores 50 + remaining-seconds × 10, so faster earns more but slower still scores. 15 s per round, then a 5-second pause showing everyone's result. Highest total wins.

Host settings (in the lobby): the host picks the mode, the number of questions, and which power-ups are available. Questions are drawn randomly from a bank of ~60 varied commands so matches don't repeat.

Mode Draws from (Learn chapters)
Novice Getting Started + Branching
Medium Remotes + History & Undo
Hard Advanced
Expert All chapters

Power-ups — a fixed inventory per game (2 freeze, 2 reverse, 1 time):

Power Effect
🧊 Freeze Blocks opponents' input for 5 s so you can type freely
🔄 Reverse Flips opponents' text right-to-left for 5 s
+Time Adds 5 s to the round

Power-ups only ever affect other players, and only one can be active at a time in the room — while a power-up is running, no one else can trigger one until it ends.

Interface

  • Bilingual: 🌐 toggle between Español and English (commands are always in English; everything else is translated). Preference is saved.
  • Light / dark theme: ☀️/🌙 toggle, saved.
  • Sound: 🔊 toggle — a rising arpeggio on a correct answer, a low buzz on a wrong one.
  • ♿ Accessibility (⚙️ in the header, or the menu card): high contrast, larger text (3 sizes), a dyslexia-friendly font (extra letter/line spacing, system fonts only), and reduce-motion (turns off confetti and non-essential animations). Preferences are saved. Keyboard focus is always visible.
  • SEO/GEO metadata (title, description, Open Graph, JSON-LD) and a custom SVG logo / favicon.

Structure

server/index.js       Express + Socket.IO — rooms, N-player round loop, speed scoring, power-ups
server/questions.js   Re-exports the shared question bank for Node
public/index.html     Single-page app (screens toggled with JS)
public/css/style.css  Terminal-inspired theme (light & dark via CSS variables)
public/js/
  i18n.js             ES/EN strings + language switching
  progress.js         localStorage progress (read, bookmark, practice completion)
  a11y.js             Accessibility settings (contrast, text size, dyslexia font, reduce motion)
  codebook-data.js    24 commands (bilingual desc + anecdote + animation key)
  guides-data.js      Guides & best-practices content
  codebook.js         Codebook nav, syntax highlight, animation engine
  lessons-data.js     Practice lessons (reference codebook commands)
  app.js              Screen router, theme, sound, celebration animations
  practice.js         Single-player logic (3 difficulties, answer checking)
  questions-data.js   Shared multiplayer question bank (browser + Node source of truth)
  net.js              MPNet transport: Socket.IO (local) OR InsForge host-authoritative (prod)
  multiplayer.js      Multiplayer UI — lobby, rounds, power-ups, timer (talks to MPNet)
  insforge-config.example.js  Copy to insforge-config.js (gitignored) to enable InsForge

Multiplayer transports

The multiplayer UI talks to MPNet (see public/js/net.js), which mirrors the Socket.IO API but runs over one of two interchangeable backends, chosen automatically at connect time:

  • Socket.IO (npm start, local dev) — the Node server in server/index.js is authoritative.
  • InsForge realtime (production, static hosting, no Node) — host-authoritative: the host player's browser runs the game loop (ported from the server) and publishes authoritative events over the channel room:CODE; other players publish intents. If the host leaves mid-game, the next player is elected host and resumes from the last state snapshot. Identity is a per-tab id (no accounts). Anti-flood: client-side throttle + host-side per-client rate limiting.

InsForge is used when public/js/insforge-config.js is present (copy it from the .example.js file and fill in your anon key — never the uak_ admin key). The browser only ever uses the anon key, which is protected by Row-Level Security. Force a backend with ?net=socket / ?net=insforge.

Tech: Node.js, Express, Socket.IO, InsForge realtime, and vanilla HTML/CSS/JS (no build step).

Contributing

See CONTRIBUTING.md for dev setup, the multiplayer architecture, project conventions, and — importantly — how to handle secrets in this public repo (the browser-safe anon key vs. the uak_ admin key, and how to rotate a leaked key).

About

Learn Git by typing the commands for real — animated codebook, typing practice at 3 difficulties, and a real-time 2–6 player battle with power-ups. Bilingual (ES/EN), accessible, runs in the browser.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages