Case study · Solo project
Pinnable
A 2D arcade score-attack game. You steer a metal bucket along the base of the screen with the mouse, catch the marbles fired from a moving cannon, dodge the pins raining down, and push for a high score as the game steadily raises the pressure the longer you last.
- RoleSolo developer
- EngineUnity 2D · C#
- GenreArcade score-attack
- PhysicsRigidbody2D catch loop
Overview
A tight arcade loop that pushes back
Pinnable is a single-screen arcade game with one goal: survive and score for as long as you can. A cannon at the top of the screen fires marbles, you catch them in the bucket to bank points, and a board of pins supplies both the hazards and the opportunities. There is no level select and no story. The whole game is the loop, and the loop is built to grow harder in step with how well you are doing.
Underneath, it is a study in a handful of small systems that each do one job well: a spawn director that decides what the game throws at you, per-pin behaviour that decides how those hazards move, and a physics catch loop that carries the moment-to-moment feel.
Difficulty
A weighted, self-escalating spawn director
Difficulty is not a single global multiplier. It is decided per pin. Each pin rolls its own type from a weighted random pool, and those weights are gated two ways: hazardous types stay locked until you pass a survival-time threshold, after which their weight scales with your score. Play well, and the board quietly stacks itself against you.
There is a deliberate piece of stagecraft in there too. The first time a newly unlocked type is due to appear, its weight is spiked so the introduction is guaranteed, then it settles back to normal scaling. A new threat always announces itself cleanly rather than hiding inside a random roll.
Hazards
Pins with behaviour of their own
The hazards are not static. Once bumped, homing pins turn continuously to face the player and accelerate as they close, so ignoring one becomes a slowly tightening trap. Drill pins watch the player's position, charge up when you line up beneath them, then bore downward with an accelerating fall and a slowdown zone that sells the sense of grinding through the floor.
Each behaviour is a compact, self-contained routine tied to its own animation state: small enough to reason about, distinct enough that the player can learn to read and counter every type.
Game feel
A physics catch loop, and the feel around it
Marbles are genuine Rigidbody2D objects. They launch from the cannon with a velocity biased by both the player's position and the cannon's own lateral movement, arc across the screen, and bounce off the bucket. The fire rate tightens over time, so the screen grows busier the longer you survive.
The bucket itself is layered from small effects that each add feel: velocity-proportional sway and tilt, clamped so it never flips; a wheel that rotates with movement; a hull sprite that swaps with the tilt angle; and a cursor-follow drive that scales speed with distance to the pointer. Sitting over all of that are three ten-second power-ups, including a zero-gravity mode that rewrites the world's gravity for its duration.
Under the hood
By the numbers
- Built in Unity 2022.3 LTS, roughly 2,400 lines of C# across 33 gameplay scripts.
- 64 pins seeded on a fixed grid at the start of every run.
- Hazard types unlock on a timer (10s to 100s survived), then scale their spawn weight with score.
- Fire rate ramps from a three-second base toward a one-second floor as the run continues.
- Three power-ups: ground value, zero-gravity and double-points, each on a ten-second timer.