Hammy Pinball! – the pinball is a hamster in a hamster ball (three.js, custom 480 Hz physics, 100% procedural, mobile)

Hi everyone! I made a pinball game where the ball is Hammy, a chonky hamster in a clear hamster ball. Flip him into kawaii marshmallow bumpers, and feed him seeds until he becomes CHUBBY, then MEGA CHONK: a bigger ball that scores more and is too wide to fall between the flippers.

:play_button: Play (free, desktop and mobile): Hammy Pinball! – Free Hamster Pinball Game | Glowbit Games

There are 6 themed tables: a hamster cage, a kitchen counter with a cat in a cardboard box, a garden, a toy room, a bubble bath with rubber duck bumpers, and the moon with low gravity. You spin hamster wheels, ride clear hamster tubes and start a Hamster Party multiball with jackpots. There is also a Table Workshop where you build your own tables and share them as text codes.

Some technical bits

  • Custom 2D pinball physics: the game runs on the table plane with fixed 480 Hz steps, not a general physics engine. Balls are circles, walls are capsule segments and circles, flippers are tapered capsules swinging about a pivot, and the cat’s paw is a capsule that slides in and out. Because the hamster ball changes size when it eats, MEGA CHONK really can’t fit between the flippers. A test checks that every gap between a post and a wall is either 0 or wider than a ball, so the ball never gets stuck. If it gets wedged anyway, a small “wiggle” shove frees it.
  • Rules on top, render-free: plunger and skill shot, ball save, the H-A-M lanes and multiplier, the chub meter, drop banks, wheels, nests, tubes, the cat, missions, multiball, nudge and TILT are plain TypeScript with no DOM or three.js, and deterministic. Unit tests and a bot run them in Node; the star scores come from the bot’s results. A lesson from balancing: multiplying the lane, chub and party multipliers made scores explode, so they now add up instead.
  • The hero: a round, fuzzy hamster (MeshPhysicalMaterial with sheen for the fur, white belly, pink ears, glossy blinking eyes, puffy cheeks, running feet) inside a clear plastic hamster ball (a glossy transparent shell plus an additive fresnel rim) that rolls with real spin. Big hits make him tumble and go dizzy, eating puffs his cheeks, and each chub level makes his body fatter.
  • Toy-like tables: each table is built from a table definition. It has a toy-plastic tray with a printed playfield, candy rails, flippers, themed bumpers (marshmallows, donuts, daisies, drums, rubber ducks, planets), hamster wheels the ball rolls through, tubes made from CatmullRomCurve3, and a little diorama around it. Bumpers squish and lamps flash on every hit. A small PMREM room environment makes the glossy plastic shine, with soft shadows from one key light.
  • Any screen: the camera frames the whole table between the HUD bars for any aspect ratio. Short landscape phones get a follow camera instead. Post is postprocessing with mipmap bloom on a half-float buffer, AgX tone mapping, vignette and SMAA, and auto quality steps the pixel ratio and shadows down on slow devices.
  • 100% procedural: all textures are drawn on canvases (wood shavings, kitchen tiles, grass, bath tiles, moon dust, playfield art) and all sound is Web Audio: flipper solenoids, a different bumper sound for each theme (marshmallow puff, duck squeak, planet bloop…), hamster “nom nom” and squeaks, the cat’s meow and hiss, and a bouncy tune for each table. The download is about 1 MB, with 274 KB of gzipped JS.

Stack: three.js r186, TypeScript, Vite, postprocessing.

I’d love to hear your best score, and how it runs on your devices!