Back
MIDNIGHT STORM
Distinction · OCR Level 2

What is Midnight Storm?

Midnight Storm gameplay // Midnight Storm — gameplay screenshot

Midnight Storm is a C# WinForms 2D sprite game built entirely in Visual Studio as an OCR Technical Diploma Level 2 assignment — written with little to no prior C# experience. Every sprite was hand-crafted in Piskel, including the player character (with separate left and right-facing models), four unique backgrounds, raindrops, poison drops, a random drop, lightning strike, and their respective splash effects.

The premise: a man living in the countryside has his water pipes burst. With stores miles away and a heavy storm incoming, he grabs a bucket and heads outside to catch as many raindrops as he can. Catch 35 to win — or 50 in Extreme mode.

The game was showcased to the following year's students due to its complexity relative to the assignment brief. It started with no difficulty system at all; the four-level structure was introduced as a last-minute expansion after the core game was complete.

  • Awarded Distinction — highest OCR Level 2 grade attainable
  • Showcased to the following year’s students as an exemplary project
  • All sprites hand-crafted in Piskel, including 8 unique sprite types with splash effects
  • Four fully distinct difficulty modes, each with a different background and rule set
  • WMPLib dual-audio workaround to enable simultaneous music and SFX
  • Four drop types: rain, poison (slows), random (RNG effects), and lightning (stuns)
  • Turbo Mode activates dynamically mid-game based on missed drop count
  • Nine documented bug fixes logged in the project’s M2 technical document

Four Levels, Four Worlds

Advanced difficulty stage // Difficulty level — advanced stage

Each difficulty is a named environment with its own pixel background, mechanics, and challenge profile:

Difficulty Theme Target Mechanics
Easy Midnight Level 35 drops Rain only
Medium Morning Level 35 drops Lightning · Poison Drop · wider map
Hard Sunrise Level 35 drops Lightning · Poison · Random Drop
Extreme Sunset Level 50 drops All mechanics · no Missed counter

Medium mode uses a wider map than the others to increase difficulty through spread — compensated by a slower rainfall rate. A Turbo Mode activates in medium difficulty once the player drops too many catches, accelerating the rainfall and raising the stakes. Extreme mode removes the missed counter entirely as an additional psychological challenge.

Hand-Crafted in Piskel

Every visual asset in the game was drawn from scratch in Piskel, a browser-based pixel art editor. The sprite set includes separate left and right player models so direction changes are visually reflected, not mirrored.

Blue raindrop sprite Raindrop
Poison drop sprite Poison Drop
Random drop sprite Random Drop
Lightning strike sprite Lightning
Player sprite Player
Blue splash sprite Splash
Poison splash sprite Poison Splash
Random splash sprite Random Splash

Each drop type has its own paired splash sprite that plays on miss — a deliberate improvement over a first version where drops simply disappeared. Four unique pixel backgrounds were also designed: Midnight, Morning (wider canvas), Sunrise, and Sunset — each setting the tone for its respective difficulty.

Systems & Architecture

The game runs across five C# WinForms: Form1 (main menu), midnightStorm (Easy), mediumMode, hardMode, and extremeMode — totalling approximately 1,470 lines of C#. Each difficulty is a self-contained form with its own game loop driven by a GameTimer tick event.

  • Raindrop movement — a foreach loop iterates over all PictureBox controls tagged "raindrop" or "poisondrop", moving each by a speed variable each tick.
  • Collision detection — bounds intersection between the player's PictureBox and each falling drop's bounds. No physics engine; pure rectangle overlap.
  • Player movement — two keyboard events set goleft / goright booleans. Each tick applies playerspeed pixels in the corresponding direction, with boundary clamping to the window's client width.
  • Lightning Strike — a randomised timer (striketime) fires the strike. When active, playerspeed = 0 temporarily freezes the player while a visibleTimer counts down the strike duration before resetting.
  • Poison Drop — contact sets a poisoned boolean and starts a poisonedtime countdown. Each tick decrements by 5 until zero, at which point player speed and boolean are restored.
  • Random Drop — effects are entirely RNG-driven. Outcomes range from a bonus point to an instant game over. After the M2 refinement patch, the extreme speed outcomes were capped to remain within a fair range.
  • Audio — WinForms' built-in SoundPlayer can't play two sounds simultaneously, so WMPLib (Windows Media Player COM library) was used for background rain audio, looped via backgroundPlayer.settings.setMode("loop", true). A second SoundPlayer instance handles lightning strike sounds.
Scrapped feature A shop system was planned — an upgrade store where players could spend caught raindrops on power-ups, extra health, and bonuses. It was cut before the final submission to stay within scope.

What Went Wrong (And What It Built)

This was the first C# project of any real scope — written before understanding how to coherently structure a codebase without introducing cascading errors. The M2 refinement document captured nine bug fixes across lightning-and-poison interaction conflicts, incorrect spawn resets, and a poison timer that failed to decrement properly after the first encounter.

Key lesson Two audio sources fighting each other exposed WinForms' SoundPlayer limitations early. The WMPLib workaround worked — but knowing it existed at all required hitting the wall first. Later projects inherited the awareness.

The medium difficulty was identified post-submission as near-impossible due to the wider map combined with standard rainfall speed. The M2 patch slowed rainfall on medium and introduced the Turbo Mode trigger — moving it from a score threshold to a missed-count threshold, which was fairer because it activated based on player struggle rather than player progress.

Despite the bugs and scope limitations, the game was notable enough to be showcased to the following year's students as an example of what was achievable within the qualification. It was the first completed, distributable game — packaged as a .exe within a compressed ZIP.