A faithful recreation of the Undertale combat system, developed in C++ using the SFML graphics library. This project reproduces the original engine architecture, implementing turn-based combat mechanics, a "Bullet Hell" system for dodging attacks, and State Machine-based interaction.
The project demonstrates the use of Object-Oriented Programming concepts, resource management, and real-time entity manipulation.
- Complete Combat System: Implementation of the Fight / Act / Item / Mercy gameplay loop.
- Bullet Hell Mechanics: Projectile generation system featuring various mathematical patterns (sine waves, geometric shapes, tracking).
- Custom Graphics Engine:
- Text rendering using Bitmap Fonts (CSV analysis + textures) to maintain a pixel-perfect look, strictly avoiding standard anti-aliasing to preserve the retro aesthetic.
- Support for Stateful Sprites for dynamic animations.
- Data-Driven Design: Enemy attributes (HP, attack, dialogue, behavior) are loaded from external JSON files, allowing parameter modification without recompilation.
- Audio System: Management of background music and sound effects.
- State System: Fluid transitions between Splash Screen, Menu, Gameplay, and Game Over states.
The objective is to survive the encounter with the enemy "Froggit". The game alternates between the player's turn (selecting actions) and the enemy's turn (dodging projectiles).
| Action | Primary Key | Secondary Key |
|---|---|---|
| Move Up | W | Arrow Up |
| Move Down | S | Arrow Down |
| Move Left | A | Arrow Left |
| Move Right | D | Arrow Right |
| Confirm / Select | Z | Enter |
| Cancel / Back | X | Shift |
| Fullscreen | F4 | - |
| Quit | ESC | - |
There are three methods to end the battle:
-
Pacifist Path:
- Select ACT from the menu.
- Choose Compliment or Threaten to interact with Froggit.
- Once the enemy's name turns yellow, go to the MERCY menu and select Spare.
-
Neutral Path:
- Select FIGHT.
- Attack the enemy until their HP reaches 0.
-
Low HP Mercy:
- Attack the enemy until their HP drops below 10.
- The enemy will become reluctant to fight, at which point you can use the Spare command.
If you don't want to compile the game from source, you can download the latest pre-built version from the Releases page:
Note: Download the
.zipfile, extract it, and run the executable.
To compile and run this project, you need the following:
- C++ Compiler: Compatible with C++20 or newer (GCC, Clang, MSVC).
- CMake: Version 3.10 or newer.
- SFML: Version 3.0.0.
- External Libraries:
nlohmann/json(for JSON parsing).OpenAL(included with SFML).
The project is configured using CMake. You can use the terminal commands below or the provided helper scripts.
Standard configuration:
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug
# or ./scripts/cmake.sh configureFor Windows with GCC (using Git Bash):
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -G Ninja
# or ./scripts/cmake.sh configure -g NinjaTo configure with ASan enabled (Note: does not work on Windows with GCC), use -DUSE_ASAN=ON:
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -DUSE_ASAN=ON
# or ./scripts/cmake.sh configure -e "-DUSE_ASAN=ON"At this step, you can also request project file generation for various IDEs.
cmake --build build --config Debug --parallel 6
# or ./scripts/cmake.sh buildThe parallel option specifies the number of files compiled simultaneously.
cmake --install build --config Debug --prefix install_dir
# or ./scripts/cmake.sh installFor more details, see scripts/cmake.sh.
Note: The
build/andinstall_dir/folders are added to.gitignoreas they contain generated files and should not be versioned.
Headers/: Header files (.h) defining class interfaces.Source/: Actual implementation (.cpp) of game logic.json/: Configuration files for enemies (e.g.,froggit.json).img/,fonts/,sounds/: Media resources required to run the game.
- This project is a fan work made for educational purposes.
- Sprites, fonts, and sounds are the intellectual property of the Undertale creator (Toby Fox).
- The source code uses the SFML library (Zlib License) and nlohmann/json (MIT License).
