Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ac-unefm/snake-game/llms.txt

Use this file to discover all available pages before exploring further.

The entire Snake Classic Game — markup, styles, and logic — lives in a single index.html file. There is no build step, no external files, and no module system. Opening the file in any modern browser is all it takes to play. The file is composed of three top-level sections inside <head> and <body>.

File layout

1

Section 1: <style> block

The entire CSS lives in a single embedded <style> tag inside <head>. It contains:
  • CSS custom properties defined on :root (design tokens for colours, used throughout).
  • A universal box-sizing reset and a body flex layout.
  • Component styles for the skip link, .sr-only utility, header (h1), HUD (#hud), session bar (#session-bar), canvas (#canvas, #game-region), status message (#message), results overlay (#results-overlay, #results-panel), help overlay (#help-overlay, #help-panel), the D-pad (#dpad, .dpad-btn), and the <footer>.
  • Responsive @media queries for mobile portrait (max-width: 480px), landscape (max-height: 500px), tablets (481px–768px), and prefers-reduced-motion.
2

Section 2: HTML <body>

Semantic markup in document order:
  • Skip link<a href="#game-region" class="skip-link"> as the very first child of <body>.
  • <header> — contains only the <h1>Snake</h1> title.
  • #btn-help — absolutely-positioned help button (?) outside <main>, with aria-haspopup="dialog".
  • <main> — contains: screen-reader instructions (#game-instructions, .sr-only), the HUD (#hud), session bar (#session-bar), the game region (#game-region > <canvas id="canvas">), the status message div (#message), the D-pad (#dpad), and the ARIA alert region (#game-alert).
  • #help-overlayrole="dialog" modal with help content; aria-hidden="true" when closed.
  • #results-overlayrole="dialog" modal showing session results; aria-hidden="true" when closed.
  • <footer> — copyright, author link, and version string.
3

Section 3: <script> block

A single inline <script> tag at the bottom of <body> contains the full JavaScript engine, in this order:
  1. DOM referencesconst bindings to every element the JS touches.
  2. Board constantsGRID_SIZE, COLS, ROWS.
  3. Speed constantsBASE_TICK, MIN_TICK, STEP_SCORE, STEP_MS.
  4. Session constantsSESSION_ATTEMPTS.
  5. Colour paletteCOLORS object.
  6. reducedMotion flag — read once at startup from matchMedia.
  7. Global state — mutable let variables for per-attempt and session state.
  8. Storage functionsreadBestScore(), saveBestScore().
  9. Speed helpersgetLevel(), getTick().
  10. Session barupdateSessionBar().
  11. Game initialisationinit(), placeFood().
  12. Game loopscheduleNext(), tick(), update().
  13. RenderingdrawGrid(), drawFood(), drawSegment(), draw().
  14. UI messagingflashMessage(), showMessage(), hideMessage(), announceAlert().
  15. Session / end-game logiccaptureAttempt(), endGame(), showSessionResults(), startNewSession().
  16. Help modalopenHelp(), closeHelp().
  17. Game startstartGame().
  18. Input handlers — keyboard (keydown), D-pad touch/click, canvas swipe (touchstart / touchend).
  19. Startup callinit() then draw() to paint the initial idle frame.

CSS custom properties

All design tokens are declared on :root and referenced throughout the stylesheet via var():
:root {
  --color-bg:          #0d0d0d;
  --color-surface:     #111111;
  --color-text:        #e0e0e0;
  --color-muted:       #666666;
  --color-primary:     #a855f7;
  --color-primary-dim: #7e22ce;
  --color-food:        #f87171;
  --color-warn:        #facc15;
  --color-grid:        #161616;
  --color-border:      #222222;
  --color-success:     #4ade80;
}

Global state variables

State is split into two groups of let variables.

Per-attempt state

VariableTypeDescription
snake{x, y}[]Ordered array of grid cells; index 0 is the head
dir{x, y}Current movement direction (applied each tick)
nextDir{x, y}Buffered direction set by input handlers
food{x, y}Current food cell position
scorenumberFood items eaten this attempt
runningbooleanWhether the game loop is active
gameOverbooleanWhether the attempt has ended
loopIdnumbersetTimeout handle, used to cancel the loop
flashTimernumber | nullHandle for temporary message timeout
alertTimernumber | nullHandle for ARIA alert debounce timeout
attemptStartnumberDate.now() value when the attempt began
attemptStepsnumberCount of grid cells traversed
attemptMaxLevelnumberHighest level reached during the attempt
attemptMinTicknumberShortest tick interval seen (= peak speed)

Session state

VariableTypeDescription
sessionAttemptsAttemptRecord[]Array of completed attempt records (max 5)
currentAttemptnumberCurrent attempt index, 0–4
bestnumberAll-time best score, loaded from localStorage on startup

Data flow

Input → update → render loop:
  1. The player presses a key, swipes the canvas, or taps a D-pad button.
  2. The handler calls applyDirection(d), which sets nextDir (rejecting 180° reversals).
  3. On the next tick(), update() copies nextDir into dir, computes the new head position, checks wall and self-collision, grows or shrinks the snake, and updates the score.
  4. draw() clears the canvas and re-renders the grid, food, and all snake segments.
  5. scheduleNext() queues the next tick() via setTimeout, completing the loop.

Constants

ConstantValueDescription
GRID_SIZE20Pixel size of each cell
COLS20Grid columns (derived: canvas.width / GRID_SIZE)
ROWS20Grid rows (derived: canvas.height / GRID_SIZE)
BASE_TICK130 msStarting tick interval
MIN_TICK45 msMinimum tick interval (speed cap)
STEP_SCORE5Points per level-up
STEP_MS12 msSpeed increase per level
SESSION_ATTEMPTS5Attempts per session
SWIPE_MIN_PX20Minimum pixel distance to register a swipe

Build docs developers (and LLMs) love