Minimal Pong (Unity / C#)

A runnable, three-script Pong built as the step-1 project in overview-arcade-classics-as-learning-projects. It isolates the skills that project teaches first: continuous movement, the game loop, manual collision and reflection, basic input, and a single score-owning controller.

It is deliberately not a clone of Atari’s Pong — it uses plain squares and original naming. Treat the original as a design reference, not something to copy.

Files

ScriptResponsibilityKey wiki concept
Ball2D.csMoves the ball, reflects off walls and paddles, raises a Scored eventreflection, unity-collider2d-and-triggers
Paddle2D.csPlayer input or a beatable “track the ball” AI, clamped to screenunity-input, unity-transform
PongMatch.csOwns the score, serves and re-serves the ballunity-gamemanager-pattern, observer-pattern
ArcadeHud.cs (in ../shared/)Shared on-screen HUD: a status line plus a timed centre message, drawn with TextMeshProui-design, game-interface-types

No Rigidbody2D is used. Collision and reflection are written out by hand on purpose — making them explicit is the learning goal of a first project.

Scene setup (about 5 minutes)

  1. New 2D scene. Set the Main Camera to Orthographic (the scripts read orthographicSize and aspect to find the play-area edges).
  2. Create three square sprites (GameObject → 2D Object → Sprites → Square):
    • Ball at the origin.
    • LeftPaddle near the left edge, RightPaddle near the right edge. Scale each to a tall thin bar (e.g. scale 0.3, 2, 1).
  3. Add a Box Collider 2D to each paddle (used only for its bounds — no Rigidbody, no physics material needed).
  4. On Ball, add Ball2D and drag both paddle colliders into the Paddles array.
  5. On LeftPaddle, add Paddle2D with Control Mode = Player. On RightPaddle, add Paddle2D with Control Mode = Ai and drag the Ball transform into the Ball field.
  6. Create an empty Match GameObject, add PongMatch, and drag Ball into its Ball field.
  7. 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-centre; 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 Match. (Leave Hud empty and messages print to the Console instead.)
  8. Press Play. Move the left paddle with W/S or the up/down arrows; the right paddle tracks the ball. The score shows at the top of the screen, and the winner is announced in the centre.

For two human players, set the right paddle to Player and give it a custom vertical axis (Edit → Project Settings → Input Manager), then put that axis name in its Vertical Axis field.

Extension ladder

These mirror the Pong extension tasks in the canon reference (see source-classic-games-canon) and lead naturally toward step 2 (Breakout):

  1. Sound and screen shake on hit — the cheapest possible game-feel win; see unity-audiosource.
  2. Difficulty scaling — raise aiResponsiveness or startSpeed as the rally grows. (Introduces difficulty tuning, the core of Breakout.)
  3. Serve countdown — pause briefly before each serve using a coroutine.
  4. Swap to Rigidbody2D — re-implement the bounce with physics and a Bouncy 2D material to compare the two approaches; see unity-rigidbody2d and transform-vs-rigidbody2d-movement.

Source files

3 items under this folder.