Engorged Beetles
65 HP · ATK 2.35- Bite
- Fly and Hiss
- Sprinkle Some Poop
A C# console horror adventure: escape a cult-controlled prison by hunting keycards, restoring power and surviving the guards and creatures in between — with a 45-track NAudio soundtrack and full save/load.
Into the Shadows is a C# console horror adventure game built for a Level 3 Foundations of Programming assignment at Staffordshire University — the direct successor to No Hope, rebuilt from scratch with a completely different scope. It runs entirely in the terminal using Spectre Console for styled output, arrow-key menu navigation, animated status spinners, and coloured dialogue.
You are a prisoner in a cult-controlled prison. The goal is simple: escape. The route is not. Getting out requires navigating a multi-room facility, finding Clearance Keycards at three access levels, restoring power via replacement wires, solving a keypad combination, and surviving whatever guards and creatures are between you and the exit.
Inspiration was drawn from Silent Hill Homecoming, Resident Evil 3, and Fallout 4 — three games that balance combat tension with world exploration. Awarded 100% for the assignment.
// Into the Shadows — title screen
The game takes place across a fully mapped prison. Each room is a distinct location with its own ambient BGM track, encounter table, items, and story beats. The map below is the full annotated export, charting all keycards, enemy spawn points, story triggers, puzzles, and win conditions.
// Prison layout — full level map
// Click to expand — annotated map of the full prison layout
Key locations include: Entrance (randomised enemy spawn, exit goal), Laundry Room (three sub-sections with escalating ambience), Canteen (Officer NPC dialogue, keycode 79175), Solitary, Shower Room, Cell Block A & B with Control Rooms, Weapons Room, Execution Room, The Torture Room, Visitor Centre, Guard Post, and The Rec Room.
Combat is turn-based with a full ATK/DEF/HP stat system, critical hit RNG, bleed status, daze, and sneak attack. Each enemy has unique HP, attack rating, defence rating, and a bespoke attack pool. The player can punch, swing a metal pipe, or give "death stares" when unarmed — and equip a shotgun, pistol, or AR when they're found.
// Canteen — live dialogue sequence
Bleed status causes ongoing damage each turn for a randomised duration. The Fear stat — a second resource alongside HP — rises during encounters and passively degrades performance when high. Sneak attacks deal bonus damage at the start of a fight when the player approaches undetected.
Seven consumable items exist in the game world, each with mechanical effects beyond simple HP restoration:
| Item | Effect |
|---|---|
| Expired Pack of Malteasers | +25 HP. Starts in inventory. |
| Bo'le of Aged Wa'er | +15 HP, −5 Fear. |
| Bo'le of Holy Water | Clears all Fear, +35 Max HP, +2.5 ATK, +2.5 DEF. |
| Box of Ferrero Rocher | +45 HP, +10 Max HP, +1.5 ATK, +1.5 DEF. Contains Deez Nuts. |
| Box of Doughnuts | +75 HP, +15 Max HP. Risk of Lactose Intolerance. |
| Crunchy Chick | +25 HP, +5 Max HP, +0.5 ATK, +0.5 DEF. +25 Fear. Morally questionable. |
| Bandages | +25 HP, removes Bleed status. |
Audio was the most technically demanding part of the project. Console apps do not have default access to SoundPlayer, and after
researching NuGet packages, NAudio was chosen — despite its unfamiliar implementation approach. Two core problems had to be
solved:
NAudio throws when a new file is played while another is active. A public CheckBGMPlayer() method was written, called before any
audio transition, to safely stop any running stream first.
NAudio has no built-in audio looping. A community solution was found and integrated, allowing BGM tracks to loop seamlessly.
Threading was used to queue and play background music alongside SFX concurrently without either track cutting the other.
| Category | Count | Notes |
|---|---|---|
| Battle BGM | 13 | Randomised per battle — three BGM sets (BattleBGM1, 2, 3) |
| Story BGM | 11 | Room-specific ambient tracks — main menu, basement, laundry, canteen, finale… |
| SFX | 18 | Heartbeat, keycard beeps, screaming, bone-cracking, alarm, whispering… |
| Total | ~45 | ~831 MB source audio assets |
The codebase spans ~8,882 lines across 7 C# files, each a dedicated class: MainGame (4,871 lines — story
progression), BattleSystem (1,076), ExtFunctions (1,084 — reusable utility methods), MainMenuOptions (805),
Player (647), SoundSystem (359), and PlayerJournal (33).
A parameterised public static method that encapsulates Spectre Console's selection prompt. Without it, the same 5-line menu block would have been duplicated ~100 times throughout the codebase. One method call, one switch statement — eliminates bad-input exceptions entirely.
Player state is written to a .txt file via StreamWriter, with a directory existence check before every save. Loading
uses StreamReader to parse each line, strip formatting characters, and map values back to their correct game variables.
Max level 10. Each level grants 1 stat point. At multiples of 5, boosts are stronger (HP +15, ATK/DEF +0.75 vs HP +10, ATK/DEF +0.5). The player allocates points via a menu prompt between combat encounters.
A System.Diagnostics.Stopwatch instance runs from game start, displaying elapsed time in the console window title bar in
HH:MM:SS format.
A second stat alongside HP. Rises during combat, via certain consumables (Crunchy Chick, +25), and from Slitherman encounters. At max Fear (100),
the PlayerFeared boolean triggers combat penalties.
Each character is colour-coded via Spectre Console markup. Dialogue progresses on keypress, preserving the pacing of voice line delivery.
A standalone Remastered FMVs Installer tool was built as a PreAlpha companion utility — a separate console application that lists all connected storage devices in a table, offers QuickSFV integrity checking, and guides the player to locate the game executable. It's styled to match the game's aesthetic: Spectre Console tables in cyan, branded with "Created by: NomNom" and a Discord server link.
The game also includes a Debug Menu accessible from the main menu, allowing direct testing of game states, location jumping, and variable inspection — built during development and intentionally left in the release build as a transparency gesture.
// Remastered FMVs Installer (PreAlpha)
The save/load system was the most technically challenging feature relative to prior experience. Writing variables to a text file was manageable — but parsing them back correctly on load required careful StreamReader logic to strip formatting characters and map each line to the right game variable without breaking the game state.
The CreateMenuPrompt() refactor was the single biggest quality-of-life improvement mid-project. Recognising that the same code was
being written ~100 times and taking the time to abstract it into a parameterised method reduced both line count and bugs significantly — and made
the codebase readable.
The project received 100%. It is the highest-graded programming project in the portfolio.