Yar Malik
HomeFree CourseResourcesStartupsPortfolioPartnershipsAbout
Join the community
Build a 1-Person AI Business with Claude/Browser Games

Course 08 · Lesson 7 of 11

High Scores and Persistence

A game without a high score is a game you play once persistence is what makes players come back

A high score is what makes a player return: to beat their own record, to beat someone else's. This lesson covers everything about saving and displaying scores and progress across sessions.

What Persistence Means for Games

By default a browser game loses all data when the page is refreshed. Close the tab and the score is gone. Reload and it is back to zero.

localStorage fixes this. Like the Web Apps course covered for calculators, localStorage saves data to the browser permanently. The game writes the score and on next load it reads it back. The player returns and their record is waiting.

For games there are three things worth persisting.

High score is the single best performance ever achieved.

Statistics are totals and averages that paint a picture of all-time performance covering games played, win rate, average score, and best streak.

Game progress is for idle and clicker games where you save the full state including balance, upgrades, and level. This is what makes idle games work as products because the player's world continues while they are away.

High Score: The Minimal Implementation

For any score-based game like Snake, Breakout, or Flappy Bird, add this to your prompt:

Track and persist the high score using localStorage.

Key: '[GAME_NAME]HighScore' e.g. 'snakeHighScore'

On page load: highScore = parseInt(localStorage.getItem('snakeHighScore') || '0')

On game over: if score is greater than highScore, set highScore = score and save

localStorage.setItem('snakeHighScore', score)

Display both score and highScore in the UI at all times.

If a new high score is set, show a brief 'New Record!' message in the game over overlay.

Statistics Board: Multiple Data Points

For word games, quiz games, and memory games where per-game performance matters more than a single peak score, track statistics.

Add this to your prompt:

Track game statistics in localStorage under the key '[GAME_NAME]Stats'.

Store as a JSON object with these fields:

  • gamesPlayed: 0
  • gamesWon: 0
  • currentStreak: 0
  • maxStreak: 0
  • totalAttempts: 0
  • distribution: 1 through 6 each starting at 0
  • On game start: load stats from localStorage using default values if none saved.

On game win:

  • Increment gamesPlayed and gamesWon
  • Increment currentStreak
  • If currentStreak is greater than maxStreak, update maxStreak
  • Increment distribution for the number of attempts used
  • Calculate winRate as Math.round(gamesWon divided by gamesPlayed multiplied by 100)

On game loss:

  • Increment gamesPlayed
  • Reset currentStreak to 0

After each update save stats using localStorage.setItem with JSON.stringify.

Display statistics in a modal triggered by a stats button. Show: games played,

win percentage calculated on display, current streak, max streak, and guess

distribution bar chart.

Guess Distribution Bar Chart

The distribution chart showing horizontal bars for how many games were won in 1 through 6 guesses is pure HTML and CSS. Include this in your word game prompt:

  • The guess distribution is displayed as a bar chart made of divs.
  • Each row has a label showing the number 1 through 6 and a bar.
  • The bar width is proportional: count divided by maxCount multiplied by 100 percent
  • where maxCount is the highest value in the distribution object.
  • Minimum bar width: 10 percent so even zero values show a thin line.
Bar color: [ACCENT HEX].

The row for the current game result should be highlighted in a brighter colour.

Save Slots and Named Profiles

For more complex games like clicker and idle games with long play sessions, add named save slots:

  • Create three save slots. Each slot saves the full game state as JSON.
  • Show three buttons above the game: Save Slot 1, Save Slot 2, Save Slot 3.
  • A fourth button handles Load. The currently active slot is highlighted.
  • Auto-save to the active slot every 30 seconds.
  • On clicking Load: show a confirmation dialog saying "Load Slot X? Your current
  • progress will be lost." If confirmed, load that slot's data and reset the game state.
  • Store slots as localStorage.setItem('gameSlot1', JSON.stringify(saveData)) and so on.

Offline Progress Calculation

For clicker and idle games the player earns resources while they are away. This is called offline earnings.

When the game loads calculate how much the player should have earned since they last closed the tab. The formula is:

  • offlineSeconds equals Date.now() minus lastSaveTimestamp divided by 1000. offlineEarned equals totalPerSecondRate multiplied by offlineSeconds multiplied by 0.5.
  • The 0.5 multiplier which is 50% efficiency offline is the industry standard. It rewards returning players without making offline play feel overpowered.

Cap offline earnings at 8 hours maximum to prevent exploits:

offlineSeconds equals Math.min(offlineSeconds, 8 multiplied by 60 multiplied by 60).

Include this in your clicker game prompt:

  • On page load calculate offline earnings. Cap offline time at 8 hours.
  • Apply 50% efficiency. Show a notification: "Welcome back! You earned [X] while
  • you were away (8 hours max)." Add the offline earned amount to balance and totalEarned.

Clearing Save Data

Always include a way to reset. Players who want to start fresh should be able to. Add this to every game with localStorage:

  • Add a "Reset All Data" button in the settings or footer area.
  • On click: show a confirmation dialog saying "This will delete all your scores
  • and progress. Are you sure?"
  • If confirmed: call localStorage.clear() and reload the page.
  • This is also useful when testing because you can clear all save data without opening developer tools.

Testing Persistence

After building any game with localStorage follow these steps.

Play the game and achieve a score or complete a session. Refresh the page with Ctrl+R on Windows or Cmd+R on Mac. Verify that the score, stats, or progress loaded correctly. Open Chrome DevTools and go to the Application tab then Local Storage then your domain. You can see every key and value saved and verify the data looks correct. Click the trash icon next to any key to delete it which simulates a first-time user. Refresh the page and the game should revert to the default zero state.

PreviousSound Effects in GamesNext lessonGames on Mobile

Do it with other builders

Post your homework. Get unstuck.

Every course ends with homework. Post yours in Claude Codex Mastery, the community this course comes from, and get feedback from Yar and 400+ people building the same way.

Join the community · $29/mo
Browser Games
  1. 1.Games: Start Here
  2. 2.Types of Games You Can Build
  3. 3.How Browser Games Actually Work
  4. 4.Build a Snake Game
  5. 5.Build a Clicker Game
  6. 6.Sound Effects in Games
  7. 7.High Scores and Persistence
  8. 8.Games on Mobile
  9. 9.The Master Game Build Prompt
  10. 10.Course Summary: Games
  11. 11.Homework: Build Your Game

Yar Malik

AI operator, educator, and founder building businesses around automation, media, and monetizable skills.

HomeAboutFree CourseBlogsPartnershipsCommunity

© 2026 Yar Malik. All rights reserved.