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
| Script | Responsibility | Key wiki concept |
|---|---|---|
SnakeInput.cs | Buffers one turn per step; rejects 180° reversals | unity-input |
SnakeGame.cs | Grid simulation: list-based body, timed stepping, food, growth, collision, score | csharp-collections, monobehaviour-lifecycle |
ArcadeHud.cs (in ../shared/) | Shared on-screen HUD: a status line plus a timed centre message, drawn with TextMeshPro | ui-design, game-interface-types |
What is different from steps 1–2
- Discrete grid. The board is a
gridWidth × gridHeightarray of cells. Positions areVector2Int, not floats. Collision is a list lookup (IsWall,IsBody), not geometry. - Timed stepping.
UpdateaccumulatesTime.deltaTimeand advances exactly one cell eachcurrentInterval, 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)
- New 2D scene, Main Camera set to Orthographic (size ~5 suits the default 20×15 board).
- 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.)
- Food prefab: another square sprite in a contrasting colour; make it a prefab too.
- Create an empty GameObject
Snake, addSnakeInputandSnakeGame. - On
SnakeGame, assign Segment Prefab, Food Prefab, and drag the same GameObject’sSnakeInputinto the Input field. - HUD: copy
../shared/ArcadeHud.csinto 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 textStatusTextand anchor it to the top-left; duplicate it asMessageText, anchor it to the centre, and set its alignment to centre. AddArcadeHudto the Canvas, drag both texts into its Status Text and Message Text fields, then drag the Canvas into the Hud field onSnake. (Leave Hud empty and messages print to the Console instead.) - 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):
- 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.
- Visible grid / border — draw the play area so the bounds are readable; first touch of unity-tilemap thinking.
- Food variety — occasional bonus food worth more points or extra growth.
- Two-snake / AI snake — a second body that pathfinds toward the food; the bridge to enemy logic in later projects and to pathfinding-algorithms.
- Audio and a short death pause — minimal game-feel; see unity-audiosource.