



Overview
// Into the Shadows — title screen
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.
World Map
// Prison layout — full level map
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.
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
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.
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.
Inventory
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 System
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:
CheckBGMPlayer() method was written, called before any audio transition, to safely stop any running stream first.| 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 |
Technical Breakdown
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).
.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.System.Diagnostics.Stopwatch instance runs from game start, displaying elapsed time in the console window title bar in HH:MM:SS format.PlayerFeared boolean triggers combat penalties.Extras
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.
Challenges & Lessons
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.