




Overview
// 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.
Difficulty System
// 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.
Sprites & Assets
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.
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.
Technical Breakdown
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.
foreach loop iterates over all PictureBox controls tagged "raindrop" or "poisondrop", moving each by a speed variable each tick.PictureBox and each falling drop's bounds. No physics engine; pure rectangle overlap.goleft / goright booleans. Each tick applies playerspeed pixels in the corresponding direction, with boundary clamping to the window's client width.striketime) fires the strike. When active, playerspeed = 0 temporarily freezes the player while a visibleTimer counts down the strike duration before resetting.poisoned boolean and starts a poisonedtime countdown. Each tick decrements by 5 until zero, at which point player speed and boolean are restored.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.Challenges & Lessons
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.
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.