Minimal Snake (Unity / C#)

The step-3 project in overview-arcade-classics-as-learning-projects. It is the first game in the route that leaves continuous motion behind: where Pong and Breakout move pixels every frame, Snake moves one grid cell per timed step. The canon reference (see source-classic-games-canon) lists its skills as grid logic, queues/lists, and timed stepping.

Original project inspired by a recognisable pattern — not a clone.

Files

ScriptResponsibilityKey wiki concept
SnakeInput.csBuffers one turn per step; rejects 180° reversalsunity-input
SnakeGame.csGrid simulation: list-based body, timed stepping, food, growth, collision, scorecsharp-collections, monobehaviour-lifecycle
ArcadeHud.cs (in ../shared/)Shared on-screen HUD: a status line plus a timed centre message, drawn with TextMeshProui-design, game-interface-types

What is different from steps 1–2

  • Discrete grid. The board is a gridWidth × gridHeight array of cells. Positions are Vector2Int, not floats. Collision is a list lookup (IsWall, IsBody), not geometry.
  • Timed stepping. Update accumulates Time.deltaTime and advances exactly one cell each currentInterval, so the snake’s speed is independent of frame rate. This fixed-timestep idea reappears constantly in simulation code.
  • List-as-body. The snake is a List<Vector2Int> with the head at index 0. Each step inserts a new head; if no food was eaten, the tail is removed — the classic add-head / drop-tail move that makes a queue behave like a snake.

Scene setup (about 5 minutes)

  1. New 2D scene, Main Camera set to Orthographic (size ~5 suits the default 20×15 board).
  2. Segment prefab: a square sprite. Drag it into the Project window to make a prefab, then delete the scene copy. (No collider or script needed — the model tracks positions; the prefab is only the visual.)
  3. Food prefab: another square sprite in a contrasting colour; make it a prefab too.
  4. Create an empty GameObject Snake, add SnakeInput and SnakeGame.
  5. On SnakeGame, assign Segment Prefab, Food Prefab, and drag the same GameObject’s SnakeInput into the Input field.
  6. HUD: copy ../shared/ArcadeHud.cs into the project as well. Add GameObject → UI → Text - TextMeshPro (click Import TMP Essentials the first time). Unity also creates a Canvas (leave it on Screen Space - Overlay) and an EventSystem. Name the text StatusText and anchor it to the top-left; duplicate it as MessageText, anchor it to the centre, and set its alignment to centre. Add ArcadeHud to the Canvas, drag both texts into its Status Text and Message Text fields, then drag the Canvas into the Hud field on Snake. (Leave Hud empty and messages print to the Console instead.)
  7. Press Play. Steer with WASD or the arrow keys. Eating food grows the snake, nudges the speed up, and adds to the score; hitting a wall or yourself shows game over on screen and restarts.

The board is centred on the Snake object’s position, so move that object to move the whole playfield.

Extension ladder

These lead toward step 4 (Space Invaders, wave systems and timers):

  1. Wrap-around walls — instead of dying at an edge, wrap the head to the opposite side (modulo the grid size). Compare how this changes the game’s feel.
  2. Visible grid / border — draw the play area so the bounds are readable; first touch of unity-tilemap thinking.
  3. Food variety — occasional bonus food worth more points or extra growth.
  4. Two-snake / AI snake — a second body that pathfinds toward the food; the bridge to enemy logic in later projects and to pathfinding-algorithms.
  5. Audio and a short death pause — minimal game-feel; see unity-audiosource.

Source files

2 items under this folder.