🍬 Cosmic Candy Pinball

A cute, 8-bit, pixel-art pinball game, written from scratch in Python with pygame-ce. 100% procedural — there are no image or audio asset files: every sprite, texture, particle, chiptune and sound effect is generated by code at runtime.

Not web-based: it opens its own native window and renders on a low-res portrait 360×480 virtual canvas — like a proper pinball machine — upscaled with crisp nearest-neighbour scaling for an authentic retro look.

demo

Running it

Fastest (uv, already used in this project):

uv venv .venv --python 3.12      # once
uv pip install --python .venv/bin/python -r requirements.txt   # once
.venv/bin/python main.py

Or with plain venv + pip (Python 3.10+):

python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
.venv/bin/python main.py

Note: the dependency is pygame-ce, not pygame (the community edition supports newer Python versions and is what this was built against).

Controls

Key Action
← → (or Z / /) Flippers
hold Space / ↑ Charge the Candy Cannon — release to fire
M Mute
P Pause
R Restart game
Esc Quit
Enter Start / play again

How to play

  • Light the 3 star lanes up top → CANDY FEVER! (double points for 20s — keep hitting stars to extend it).
  • Bounce off the three kawaii candy bumpers and the two slingshots. Every hit inside 2.5s builds your combo multiplier (up to ×9).
  • Watch the bottom-centre drain and the two outlanes… or lose the ball.
  • Every 50,000 points earns an extra ball.
  • The kawaii cat helper reacts to your shots from the corner.

Project layout

file purpose
main.py entry point / main loop
game.py game states, scoring, juice, all rendering (pixel art)
physics.py pure pinball physics (flippers, bumpers, slingshots, drains) — no rendering
font.py hand-made 5×5 pixel bitmap font
sfx.py procedural chiptune + music synthesis (pure code, no samples)
highscore.json best score (written at game over)

Dev / test tools (run headless, no window needed):

.venv/bin/python autotest.py 40000    # auto-playing bot, prints game-health stats
.venv/bin/python runtest.py 900       # simulated session incl. rendering
.venv/bin/python shots.py shots       # dumps screenshots of every state
.venv/bin/python probe.py             # pixel-probes the rendered layout

Design notes

  • Portrait table: a 360×480 playfield like a real pinball machine, with regular-sized flippers (about a quarter of the playfield width each) at the bottom and a wide centre drain between them.
  • Physics: fixed 60 Hz logic with up to 6 collision substeps so the ball never tunnels; kinematic flippers whose angular velocity is transferred to the ball (real "scoop" feel); inward-tilting floor funnels; centre drain + guarded outlanes; a softlock rescue nudge if a ball ever parks too long.
  • Fun tuning was data-driven: an autotest.py bot plays thousands of frames and reports hit/drain rates per table element, so bumper, slingshot and flipper geometry was tuned against measured behaviour, not guesswork.
  • Audio: soft triangle/sine voices -> PCM at startup; pitched bumper pops that climb with your combo, plus two real melodies (a slow Twinkle Twinkle lullaby on the title, a bouncier version during play — no square-wave or noise percussion in the music).

Licence: MIT — go wild.

S
Description
No description provided
Readme
157 KiB
Languages
Python 100%