Back
MIDNIGHT STORM
Explored 0%
Easy mode gameplay — midnight level Extreme mode with lightning strike active Hard mode — sunrise level with house background Easy mode close view — raindrop and poison drop Midnight Storm level select screen
C# WinForms · Solo · College

Midnight Storm

A C# WinForms 2D sprite game about catching raindrops in a bucket before the storm hits — four difficulty levels, every sprite hand-drawn in Piskel, and lightning, poison and random drops to dodge.

Type
College Assignment
Language
C# WinForms
Qualification
OCR Level 2
Year
2020
Team
Solo
Sprites
Hand-crafted in Piskel
Showcased
Next Year's Students
Grade
Distinction · OCR Level 2
C# WinForms Visual Studio WMPLib Piskel 2D Game Console App Sprite-Based OCR Diploma
Final Grade 0%
0
Difficulties
0
Lines of C#
0
Sprite types
0
Documented bug fixes
Overview

What is Midnight Storm?

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.

Midnight Storm gameplay // Midnight Storm — gameplay screenshot

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

Four Levels, Four Worlds

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

DifficultyThemeTargetMechanics
EasyMidnight Level35 dropsRain only
MediumMorning Level35 dropsLightning · Poison Drop · wider map
HardSunrise Level35 dropsLightning · Poison · Random Drop
ExtremeSunset Level50 dropsAll mechanics · no Missed counter
Advanced difficulty stage // Difficulty level — advanced stage

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

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.

Poison drop sprite

Poison Drop

Drop
Random drop sprite

Random Drop

Drop
Lightning strike sprite // Lightning sprite

Lightning

Hazard
Blue splash sprite

Splash

Splash
Poison splash sprite

Poison Splash

Splash
Random splash sprite

Random Splash

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.

Technical Breakdown

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 featureA 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.
Challenges & Lessons

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 lessonTwo 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.

Milestones

Trophies Earned

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