# Breakout

Breakout, written entirely in BASIC for the AKGL BASIC interpreter. The ball and the
paddle are sprites defined from `DATA` in the listing; the bricks, the HUD and the
messages are characters in the text grid.

```sh
../../../build-akgl/basic breakout.bas
```

It needs the SDL build. The stdio build has no graphics device, so the first `RGR` refuses
and the game stops there — which is exactly what it should do.

| Key | Does |
|---|---|
| left / right | move the paddle |
| space | start a game from the title screen, then launch the ball |
| P | pause |
| Q or escape | quit |

The title screen plays itself. Attract mode is a real feature and it is also how the game
was tested without a hand on the keyboard.

Three lives, six rows of bricks worth 60 down to 10 points a row, three level layouts that
repeat with a faster ball each time, and a high score that lasts as long as the process
does.

## How it works, and how to write your own

**[Chapter 17 of the guide](../../../docs/17-tutorial-breakout.md)** builds this program in
fifteen steps you can type in one at a time, starting from an empty file: measuring the
screen, declaring every name before anything uses it, making the two sprites out of `DATA`,
building a text row whole, the main loop, the ball, the bounce, and the attract mode. It is
the tutorial; this is the finished thing.

[Chapter 18](../../../docs/18-tutorial-breakout-artwork.md) does the same for
[`../sprites`](../sprites), which builds the same game out of loaded artwork and comes out
a completely different program.

## Known warts, this game's own

- **The cell size used to be a constant.** `CW#` and `CH#` were 16, measured by hand
  against the bundled C64_Pro_Mono at 16 points, because BASIC had no way to ask — and it
  was the one thing here that would break on a different font. `RGR(3)`, `RGR(4)` and
  `RWINDOW` were added to the interpreter because of this listing, and it uses them now,
  so the game fits whatever window and font the host gives it.
- **Every character the game draws also goes to stdout**, because the frontend tees the
  text sink to the terminal. It made the whole game auditable from a log file during
  development and it is pure noise the rest of the time. Redirect it.
- **Collision is against the cell the ball's leading edge is in**, so a brick clipped at
  the very corner can be missed by up to seven pixels' worth of ball. Testing the centre
  instead was worse: the ball sank four pixels into a brick before it turned.
- **There is a stall watchdog.** Ten seconds without touching a brick and the ball gets a
  new angle — at the *next paddle bounce*, never in mid-air.
- **The demo cannot lose**, it re-serves. It also cannot be paused; `P` is ignored until a
  real game starts.
- **Sound is asked for once and then believed.** On a machine with no audio device the
  game is silent rather than dead.
- **No high score on disk.** There is no disk in this interpreter.

The interpreter defects this game turned up are filed in `TODO.md` §6 and §9, each with a
reduction that fits on a screen. Most are now fixed — the value pool that killed the first
version after twenty-five seconds, the unreachable `WINDOW`, the character written past a
short row — and the entries are struck rather than deleted, because the reduction is worth
keeping.

**The listing takes the geometry fix and leaves the rest of its shape alone.** Measuring
the cell instead of assuming it makes the game strictly better, so it does. Declaring
every name up front and looping with `GOTO` are no longer forced by anything, and are
still what the file does — its comments now say which rules stand and which are history.

## How this was checked

- Parses clean under the stdio `basic` (it then stops at the first graphics verb, as it
  should).
- Attract mode run for 145 seconds and again for 110: no runtime error, score climbing
  throughout, 39 bricks in the second run.
- Level clear verified against a copy whose first layout is a single row: `LEVEL CLEARED`,
  layout 2 loaded, ball speed up, play continues.
- Input driven with `xdotool` against the real window: paddle moves and clamps at both
  edges, ball launches, `P` pauses and unpauses, three lives drain to `GAME OVER`, space
  starts a new game, `Q` exits printing the final and high scores.
- Every direction change logged for a whole run and read back: each one is a wall, a brick
  or the paddle. Nothing turns without a reason.
