1
0
Fork 0
mirror of https://github.com/imjasonh/nescript synced 2026-07-08 17:06:04 +00:00
nescript/examples/pong/PLAN.md
Claude 21b91f6398
examples/pong: production-quality Pong game with powerups and multi-ball
A complete, playable Pong game split across examples/pong/*.ne files
and pulled in from a top-level examples/pong.ne. Features:

- **Title screen** with a 3-option menu (CPU VS CPU / 1 PLAYER /
  2 PLAYERS), a cursor sprite, blinking "PRESS A" prompt, brisk
  title march on pulse 2, and autopilot that auto-confirms CPU VS
  CPU after 45 frames of no input so the headless jsnes golden
  harness reaches gameplay by frame 180.

- **Ball physics** with signed-magnitude velocity (u8 magnitude +
  sign bit per axis), wall bounce at top/bottom, paddle AABB
  collision with push-out, and score-out detection at left/right
  exits.

- **Multi-ball** via parallel ball_* arrays (MAX_BALLS = 3). Each
  ball scores a point independently; the round continues until the
  last ball exits the playfield.

- **CPU AI** that tracks the nearest active ball heading toward its
  side with a per-frame step, 4 px dead zone, and CPU_SPEED = 1 so
  rallies can end naturally.

- **Three powerup types** that spawn every ~4 seconds, bounce off
  all four walls, and are caught by paddle AABB overlap:
  1. LONG — extends the catching paddle from 24 → 40 px for 5 hits
  2. FAST — doubles ball x-velocity on the catcher's next hit
  3. MULTI — spawns two extra balls on the catcher's next hit

- **Victory** at first-to-7 with a "PLAYER N WINS" banner and the
  builtin fanfare, auto-returning to Title.

- **Audio**: 5 user-declared sfx (WallBounce, PaddleHit, Score,
  PowerSpawn, PowerCatch) plus a title march and the builtin
  fanfare for victory.

Source layout mirrors examples/war:

    examples/pong.ne               top-level game shell
    examples/pong/PLAN.md          living design doc
    examples/pong/constants.ne     layout + gameplay constants
    examples/pong/assets.ne        45-tile Tileset (paddles, ball, alphabet,
                                   digits, cursor, center-line, powerup icons)
    examples/pong/audio.ne         sfx + music declarations
    examples/pong/state.ne         all mutable globals
    examples/pong/rng.ne           8-bit Galois LFSR
    examples/pong/render.ne        draw helpers
    examples/pong/input.ne         paddle step (human + CPU AI)
    examples/pong/ball.ne          multi-ball physics + paddle collision
    examples/pong/powerup.ne       powerup entity (spawn, bounce, catch, apply)
    examples/pong/title_state.ne   state Title + menu
    examples/pong/play_state.ne    state Playing (P_SERVE/P_PLAY/P_POINT)
    examples/pong/victory_state.ne state Victory

Verification:
- 616 compiler unit tests pass (cargo test --all-targets)
- cargo fmt / cargo clippy --all-targets -- -D warnings clean
- 33/33 emulator harness goldens match
- examples/pong.nes builds byte-identically from source

https://claude.ai/code/session_0134F5uwDEVTes2Ee9S7JeXy
2026-04-16 01:25:29 +00:00

141 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Pong — Implementation Plan
A production-quality Pong example for NEScript in the same vein as
`examples/war.ne`. This is the living plan: each step is checked off
as it completes, and any mid-flight design changes land in the
"Design revisions" section at the bottom.
---
## 1. Scope & quality bar
- **Title screen**: big "PONG" banner (later milestones), 3-option menu
(CPU VS CPU / 1 PLAYER / 2 PLAYERS), cursor, blinking "PRESS A"
prompt, brisk title march, autopilot to CPU VS CPU after
`TITLE_AUTO_FRAMES` with no input so the headless golden capture
reaches gameplay.
- **Gameplay**: two paddles, smooth ball physics, proper hit-angle
deflection, responsive controls, dashed center line, two-digit
score HUD above each side.
- **Powerups**: three types that spawn periodically, bounce around
the playfield, and apply an effect when caught by a paddle:
1. **LONG** — catching paddle extends from 24→40 px for the next
`LONG_PADDLE_HITS` paddle hits.
2. **FAST** — catching paddle's next hit doubles the ball's x
velocity for that ball's remaining life.
3. **MULTI** — catching paddle's next hit spawns two extra balls
at the hit point (so 1→3 balls, each scores independently).
- **Victory**: first to `WIN_SCORE` points. Big "PLAYER N WINS"
banner, fanfare, auto-return to title.
- **Audio**: every feel event gets a dedicated sfx, plus a title
march and a victory fanfare.
---
## 2. File layout
```
examples/pong.ne top-level: game decl, palette, Tileset, includes, start
examples/pong/PLAN.md this document
examples/pong/constants.ne layout + gameplay + powerup + phase constants
examples/pong/assets.ne Tileset sprite block (every custom CHR tile)
examples/pong/audio.ne sfx + music declarations
examples/pong/state.ne all mutable globals
examples/pong/rng.ne 8-bit Galois LFSR
examples/pong/render.ne draw_paddle, draw_ball, draw_score, draw_word_* helpers
examples/pong/input.ne paddle_step(side) — unified human + CPU paddle update
examples/pong/ball.ne multi-ball physics (update, paddle & wall collision)
examples/pong/powerup.ne powerup spawn, bounce, catch, apply
examples/pong/title_state.ne state Title + menu
examples/pong/serve_state.ne state Serve (brief pause before launch)
examples/pong/play_state.ne state Playing (phase machine)
examples/pong/victory_state.ne state Victory
```
---
## 3. Hardware budget
### Sprite budget per frame (max 64 OAM slots)
| Entity | Sprites | Notes |
|----------------------|---------|--------------------------------|
| Left paddle | 3-5 | 3 in normal, 5 in long mode |
| Right paddle | 3-5 | same |
| Active balls | 1-3 | up to `MAX_BALLS = 3` |
| Powerup | 0-1 | one slot when active |
| Center-line dashes | ~7 | 1 tile every 32 px, at x = 124 |
| HUD score digits | 4 | 2 digits per side |
| **Steady-state max** | ~24 | well under 64 |
### Sprite-per-scanline check (W0109 budget = 8)
Paddles are at x = 16 and x = 232, separated by 216 px. The ball and
powerup live in the middle of the playfield; center-line dashes live
at x = 124. HUD digits live at y = 16 (above the playfield). Worst
case scanline hits one paddle-tile + ball + powerup + center-line
dash = 4 sprites. Comfortable.
### Tile budget (max 256)
| Group | Tiles |
|-----------------------------|-------|
| A-Z alphabet (8×8) | 26 |
| 0-9 digits (8×8) | 10 |
| BIG PONG banner (4 × 2×2) | 16 |
| Paddle (top/mid/bot caps) | 3 |
| Ball | 1 |
| Cursor arrow | 1 |
| Center-line dash | 1 |
| Powerup icons (L, F, M) | 3 |
| **Total** | ~61 |
### RAM budget
| Structure | Bytes |
|-----------------------|-------|
| Paddle state (× 2) | ~16 |
| Ball state (× 3) | ~24 |
| Powerup state | ~10 |
| Scores + mode + phase | ~12 |
| RNG + timers + misc | ~12 |
| **Total** | ~74 |
All well within the NEScript 1280-byte general RAM ceiling.
---
## 4. Milestones
- [x] **M1** — Skeleton & title screen
- [x] **M2** — Paddles with input and clamping; HUD scores
- [x] **M3** — Single-ball physics (serve, bounce, score-out)
- [x] **M4** — Multi-ball via parallel ball_* arrays (structural — arrays loop from M3)
- [x] **M5** — CPU paddle AI; title mode pick dispatch
- [x] **M6** — Long-paddle powerup plumbing (draw + collision wired in M3)
- [x] **M7** — Fast-ball + multi-ball-on-next-hit flags
- [x] **M8** — Powerup entity (spawn, bounce, catch, apply)
- [x] **M9** — Victory state + fanfare
- [x] **M10** — Audio + polish pass
- [x] **M11** — Golden capture + README/examples/README entries
- [ ] **M12** — Compiler bug cleanup (revert workarounds where fixable)
- [ ] **M13** — Thorough code review pass
---
## 5. Design decisions (locked in M1)
- `WIN_SCORE = 7`
- `MAX_BALLS = 3`
- Paddle height: 24 px normal, 40 px long
- Ball base speed: 1 px/frame on each axis; FAST doubles x to 2
- Powerup spawn cadence: every `POWERUP_SPAWN_FRAMES` (~240) frames
- Powerups bounce off all four walls, catchable by either paddle
- CPU AI: 1 px/frame toward ball y, 4-frame reaction lag, ±4 px miss zone
- Default autopilot mode: CPU VS CPU (so the golden harness captures gameplay)
---
## 6. Design revisions
(empty — record any mid-flight changes here)