Hydra Wolf
Enemy- Venomous Bite
- Claw
- Hydra's Breath
A C++ console text-based horror adventure: wake up in a forest notorious for disappearances, discover you can cast magic, and fight through a Final Fantasy XIII-inspired turn-based battle system — all inside the terminal.
The Forbidden Hell is a C++ console text-based horror adventure game built solo as a university assignment. The player wakes up in The Forbidden Hell forest - a location notorious for unexplained disappearances and murders - and discovers they can cast magic spells. Narrative decisions are driven by RNG, and the world is populated with a full turn-based RPG battle system inspired by Final Fantasy XIII.
The game is built entirely in the terminal - no engine, no renderer. The UI is driven by FTXUI (a C++ CLI UI library) for
fullscreen interactive menus, with FMOD handling all BGM and SFX audio. Custom save/load writes player state to a proprietary
.the_forbidden_hell file format on disk.
Inspirations for tone and feel: Blair Witch Project, Final Fantasy XIII, Silent Hill Homecoming, Slender: The Arrival, Resident Evil 3, and The Evil Within.
// Main Menu — red colour scheme
:::::------::::----------::::::::-=====-::::::---- ::-----:-----------=-==**#*=-------==-==---------- ::::::::-:::::------=*######*+----=====---::::.::: ::::::::::::::::---+++++++++**-::------::::::..::: :::--:::--::------=++++=====+*====-=====--::::..:- ::--::.:--:-::::::-==+++=++=+=:--=--==-------::::: ::::::.::::...::::=-++++=====-:::--===-:-------::: :::-:::::::....:::::+++=====-::::--===--------==-- ---::.::::::...:::::=+++===--:::::-====----::----- :::...:::::-:::::--=++*++===-::---=-==--::-------- ::-:..:--::--------++++===-##+=-=---==--::-:::-=-- :::-::------::-++--=++++=-=#%%%%###*+=--::-:::-==- -::-------=+*#%%#=-*++=--+#%%%%%%%%%%%#----::-=-=- ---::----+#%%%%%%#***+=+#%%%%%%%%%%%%%%+--=--=-:-= --::::---+%%%%%%%%#*+*+=*%%%%%%%%%%%%%%#=--====--- ---:::--=+%%%%%%%%*+=*##%%%%%%%%%%%%%%%%+---==---- ----::--=*%%%%%%%%*==++#%%%%%%%%%%%%@@%%%+-----::: :---::--=*%%%%%%%%##**+%%%%++**#%%%@@@%%%%%#=---:: -----:--=+%%@%%%%%%#*##%%%%**++++#%%@@@%%%%%%#=-:: =------==+%%@%%%%%#*#%%%%%%%#*++++%%%%%%%%%%%%*--: -::----==*%%@@%%%%%***%%%%@@@@@#*+#%%%%%%%%%%%#==- ---:--===+#%#+++*#%#**%@@@@@@@@@@@@@%##%%%%%%%#=== ---:-====+%*#+***#%##%%@@@@@@@@@@@@@@#%%@%%#*===== ---=======*#%#***%%##%@@@@@@@%%@@@@@@*=========++= ===========+*%%%%@@%#%@@@@@@@@@@@@%%%*==========+= +=---=======+++#%%%%#@@@@@@@@@@@@%%%%%==========++ +==-========+++%%%#*#%@@@@@@@@@@@@%%%%*=========++
The combat system is a turn-based Final Fantasy XIII-inspired loop. Each turn the player selects a role, which determines what four actions are available. Damage types are resolved against per-element weakness/resistance/immunity tables for each combatant. The only thing missing is the ATB (Active Time Battle) gauge - which is not suitable for a game like this.
Attack · Stab · Magic Ball · Heavy Attack
Fire · Blizzard · Lightning Strike · Wind Blast
Elude · Block · Dodge · Mediguard
Cure · Remedy · Protect · Regenerate
Nine damage elements govern all combat interactions:
Status ailments operate independently on both sides of combat: Bleed, Poison, Weaken, Curse, Protection, Regeneration, Elude, Block, and Dodge.
The player starts with baseline stats and levels up through an XP system. On level-up, stat points can be allocated across HP, ATK, MG, and DEF - with a bonus stat allocation every five levels:
| Stat | Base |
|---|---|
| HP: | 175 base |
| ATK: | 5.8 base |
| MG: | 4.3 base |
| DEF: | 1.74 base |
Inventory items available in shops and as drops:
Five regular enemies inhabit the forest, each with three signature moves and their own element affinity profile. The boss encounter features full voiced audio:
A South Park City Wok reference. Three abilities: City Beef, Mongolian Chicken, City Airline's Special. Full voiced
audio: attack VO (4 lines), damage VO (3 lines), turn VO (4 lines), and a dedicated boss BGM track -
SP_CityWok_BossTheme_BGM.ogg.
The game's world was designed as a fully interconnected forest settlement with distinct zones. The player starts at the Forest Camp Site and progresses through a series of locations, each with its own narrative beat and encounter type:
The game is a pure C++ console application. There is no engine, no renderer - everything runs in the terminal. The architecture straddles a difficult constraint: two of the core libraries cannot coexist in the same translation unit. Furthermore, my implementation of FMOD was buggy, leading to eventual memory leaks.
// FTXUI and windows.h CANNOT be included together. // Including both causes compile failures due to symbol conflicts. // Any system requiring Windows API calls must live in separate // translation units — completely isolated from FTXUI headers. // This forced architectural decisions and removal of code that // had already been written.
fullscreen terminal UI. Used for interactive menus, tab containers, sliders, and animated selection. The main menu, settings, and all in-game navigation panels run through FTXUI's component system.
audio engine. Separate System, Sound, and Channel objects per audio stream. BGM loops: two main menu
variants, four battle tracks, one post-battle track, one boss theme. SFX are one-shots. Volume and channel management handled manually.
SetConsoleTextAttribute drives all terminal colour (red, blue, white - runtime selectable). SetConsoleTitle,
GetSystemPowerStatus (battery level display in main menu), Sleep, SetWindowLong (disable console resize),
and GDI console outline drawing are all used.
std::mt19937 Mersenne Twister seeded with std::random_device, with uniform distributions for both integer and float
ranges. Used for narrative branching decisions, random encounter events, and stat variance in combat.
// Save directory: game_saves/ // File extension: .the_forbidden_hell (custom format) // Written with std::ofstream, read with std::ifstream // Stores: player HP, ATK, MG, DEF, XP, level, inventory counts, // current location, status flags, discovered world state
A clearConsole() function with a loading screen animation text - simulating the player character walking between locations - is used
throughout to smooth transitions. waitForUserInput() halts execution at narrative beats for pacing.
While it was frustrating to find that my game refused to open, it made me recognise the importance of testing games on various devices to check for compatibility or more generalised issues.
The project also hit a fundamental technical constraint mid-build:
FTXUI and windows.h cannot be included in the same translation unit. They produce compile failures due to symbol
conflicts. This forced significant architectural decisions - any system that needed Windows API access had to be physically separated from any file
that included FTXUI headers. Code that had already been written had to be restructured or removed.
The FTXUI/Windows API incompatibility was the single most disruptive technical obstacle. The two libraries cannot coexist in the same file - this isn't a minor include order issue, it's a fundamental conflict between FTXUI's abstraction layer and the raw Windows console API. Resolving it required restructuring files mid-development and removing some already-written functionality. This took significant amount of time.
The project also had to be migrated to a fresh project space partway through development after the original FTXUI CMake setup failed in a way that could not be repaired in-place. Starting over in a clean environment cost significant time.
Outside the submission failure, the architecture forced by the FTXUI/windows.h conflict produced some unexpectedly clean design. The strict separation of concerns - audio in its own unit, Windows calls in theirs, FTXUI in theirs - mirrors patterns you'd apply intentionally in larger codebases. The constraint produced a cleaner project structure than a purely unconstrained build would have.
The final hefty challenge that appeared near the end of the development, was the infamous FMOD memory leaks. It seemed as if FMOD were not clearing the played sounds from memory, therefore, the memory would keep growing every sound that is played, causing out of memory error internally.
.the_forbidden_hell save format using std::ofstream / std::ifstreamSetConsoleTextAttribute