Live: https://justinsteinmetz.github.io/presentperfectlifexp/
A fast-paced classroom game for practising the present perfect. Students claim experience cards by typing grammatically correct sentences against the clock. Supports solo play with a personal best tracker and live multiplayer via Ably.
Each card shows an emoji, a verb prompt, and an experience phrase — for example:
🍕 eat · pizza for breakfast
The student must type the correct present perfect sentence:
I have eaten pizza for breakfast.
Cards are organised into five categories: Food & Drink, Travel, Sports, Culture, and Wild Cards. Each card carries an XP value. Students score full XP on the first correct attempt and half XP on the second. Two failed attempts locks the card.
Enter a name and play alone against a 3-minute timer. Score is compared to your personal best (stored locally per name). Results screen shows total XP, sentences claimed, personal best, and the difference from your best run.
Enter the room code shown on the board and your name. Wait for the host to start. Play proceeds simultaneously with all students. A mini leaderboard strip at the bottom of the screen updates live.
Creates a room and displays a code for students to join. The host sees a live full-screen leaderboard only — no cards, no gameplay. Controls: pause/resume the timer, end the game early. On game end, results are broadcast to all students simultaneously.
| Attempt | Result | XP awarded |
|---|---|---|
| 1st | Correct | Full XP |
| 2nd | Correct | Half XP |
| 2nd | Wrong | Card locked |
A floating grammar reference panel is visible during play showing the have / has + past participle rule.
Input is normalised before comparison: trimmed, lowercased, punctuation stripped, whitespace collapsed. Students do not need to worry about capital letters or full stops — only the words matter.
Single HTML file. No build step, no framework, no backend.
- Realtime multiplayer — Ably pub/sub over WebSocket
- Personal best storage —
localStorage, keyed per player name - Deployment — GitHub Pages (static, drop-in)
The file is structured in clearly marked sections:
<style> CSS (design tokens, screen layouts, card states)
<body> HTML (four screens: lobby, waiting, game, results)
<script>
CONSTANTS Ably key, game duration
CATEGORIES Card data (emoji, verb, phrase, sentence, XP)
STATE Runtime variables
HELPERS Utility functions
SOLO Solo start/quit flow
ABLY Connection initialisation
HOST Room creation and control
JOIN Student join flow
MESSAGE HANDLER Ably event routing
BEGIN GAME Screen setup by mode
TIMERS Solo, host, and student timer loops
LEADERBOARD Build, render, update functions
CATEGORIES UI Sidebar and card rendering
CARDS Click, input, submit, validation logic
RESULTS Solo and multiplayer results screens
- Fork or clone the repository
- Enable GitHub Pages on the
mainbranch from the root - The game is live at
https://[username].github.io/[repo-name]/
No npm, no config, no build pipeline.
Card data lives in the CATEGORIES array near the top of the <script> block. Each card has five fields:
{ emoji:'🍕', verb:'eat', phrase:'pizza for breakfast', sentence:'I have eaten pizza for breakfast.', xp:10 }emoji— displayed on the card faceverb— shown as the prompt label (have eat)phrase— the experience descriptionsentence— the exact correct answer (used for validation)xp— points awarded for a first-attempt correct answer
Add, remove, or edit cards freely. MAX_XP and MAX_SENTENCES are computed automatically.
The Ably API key in the source is a free-tier key. For production use, replace it with your own key from ably.com. Free tier supports up to 200 concurrent connections.