Demo: https://drive.google.com/file/d/1eEQ0hlKQH1g_NqAJ0Q2wi6Lo4T0Smea3/view?usp=sharing
- Li Zhuofei (Felix-Li-0306): 3036481468
- Gu Xiangyi (2529602): 3036481248
- Wang Yujin (Eugenia-wyj): 3036481999
- Chen Yilin (lisasa10): 3036482929
- Zhao Yiwei (Meditator Wayne): 3036483090
Shelter Seconds is a text-based post-apocalyptic survival game that runs in the Linux terminal. The player controls three survivors - You, Emma, and Noah - through two connected phases: an opening timed scavenging stage and a day-by-day shelter survival loop. The goal is to keep at least one survivor alive until the target day for the selected difficulty is reached.
At the beginning of a new game, you must pick a difficulty. It changes almost everything:
| Feature | Easy | Normal | Hard |
|---|---|---|---|
| Starting food & water | 20 each | 12 each | 5 each |
| Starting medicine | 3 | 1 | 0 |
| Starting tools | 3 | 2 | 1 |
| Days to survive | 10 days | 14 days | 20 days |
| Event chance per day | 40% | 70% | 90% |
| Scavenging time budget | 8 actions | 6 actions | 5 actions |
| Daily hunger/thirst increase | +14 | +15 | +18 |
Hard mode also makes the whole team consume 1 extra food and 1 extra water per day, and exploration becomes more dangerous.
You have a short window to dash outside and grab extra supplies.
- You start at Your House and can move among 5 locations: Your House, Supermarket, Pharmacy, Hardware Store, and Fire Station.
- Each action (move or scavenge) costs 1 time unit. Your total time budget depends on difficulty.
- Scavenging a location gives random loot: food, water, medicine, or tools.
- Supermarket gives more food/water.
- Pharmacy gives medicine.
- Hardware store gives tools.
- Fire station gives water and sometimes a tool.
- Hard difficulty reduces the loot by ~1 unit; Easy may give a small bonus.
- At the end, the shelter’s base emergency supplies (from difficulty) are added – you see both numbers.
Once inside, each day follows the same fixed order:
Shows day number, difficulty, resources (food/water/medicine/tools), exploration cooldown, and each survivor’s health, hunger, and thirst.
- Food & water needed = number of alive characters (Hard: +1 extra food and +1 extra water for the team).
- If enough resources exist, they are consumed; if not, the remaining resources are consumed and that day's hunger/thirst recovery is lost.
- Hunger and thirst increase by the difficulty‑based amount.
- If there was enough food that day, hunger is reduced by 10 (Easy:12, Hard:7). Same for water and thirst.
- Damage: If hunger or thirst exceeds the threshold (normal 100, Easy 105, Hard 90), the survivor loses health.
- Death occurs when health reaches 0.
If you have medicine (>0), you are offered to use it. You select a living character, consume 1 medicine, and restore 25 health (up to maximum 100).
Based on the difficulty’s event chance, an event may happen. The event pool includes:
| Event | Effect |
|---|---|
| Find Food | Gain 2‑5 food (Easy:3‑6, Hard:1‑3) |
| Find Water | Gain 2‑5 water (Easy:3‑6, Hard:1‑3) |
| Find Medkit | +1 medicine |
| Sickness | Random alive character loses 15‑25 health |
| Raiders | Lose food and water; if you have at least 2 tools, you can attempt to barricade |
| Water Leak | Lose 2‑4 water |
| Tool Break | Lose 1 tool (if available) |
| Minor Recovery | Random alive character gains 10‑20 health |
| Hidden Ending | Digitalization – see below |
Tools can mitigate negative events: For Sickness or Water Leak, using 1 tool halves the loss (and has a 10% chance to fully cancel the event).
- Cooldown: After exploring, you cannot explore the next day (Easy: 0 cooldown).
- You choose one alive survivor to go out.
- Outcome probabilities depend on difficulty:
- Easy: 50% positive, 30% neutral, 20% negative
- Normal: 40% positive, 30% neutral, 30% negative
- Hard: 25% positive, 25% neutral, 50% negative
- Positive: gain food, water, sometimes medicine/tools.
- Neutral: nothing.
- Negative: survivor takes damage (8‑32 health).
- Hidden Ending – Meta‑Awakening: With 0.2% chance (or if environment variable
META_AWAKENING=1is set), the character breaks the fourth wall and ends the game.
4. Hidden Endings
🌟 Extra Special Features: Hidden Endings!
To enhance players' willingness to keep playing, we designed two Hidden Endings for our text-based game.
These endings go beyond the normal win-or-lose outcome, offering players unexpected sci-fi plot twists.
1. Hidden Ending: Digitalization of Human Beings (from random event findAIAgent, weight 3)
-
Trigger Condition: It is triggered upon discovering and interacting with an "Ancient AI Core" hidden in the shelter.
-
Narrative Concept: A cyberpunk-inspired ending where the team members transcend human biological limitations. The player's flesh-and-blood body is discarded, and their consciousness is uploaded into an eternal digital network.
-
Creative Implementation: We creatively use some C++ statements within the narrative text itself. For instance, a
struct humanKinddefinition is printed to visually show the player's transformation into lines of C++ code, which boosts this ending's sense of future. We also outputHuman 00000010to make the process more realistic as the player is named after a sequence of 0 and 1. Moreover, statements such asbool is_mortal = falseare also included in the definition of humankind, which exhibits classic fiction features.
2. Hidden Ending: META-AWAKENING (from exploration)
-
Trigger Condition: This is an extremely rare event that might be triggered during exploration.
-
Narrative Concept: The in-game character suddenly gains self-awareness, realizing they are nothing more than a C++
GameStatestruct comprised of data types such as integers and booleans. The character stops walking, looks directly at the player in the real world (YOU!), and questions the nature of reality before shutting down the game. -
Creative Implementation: This ending is a tribute to sci-fi classics like The Matrix and The Truman Show. Through the character perceiving
lines of codebehind their existence, we explore the boundary between simulation and reality, which is meant to stimulate the player in the real world (YOU!) to reconsider your own existence carefully.
- 5 save slots, each with a custom name.
- Save files store: day number, target day, difficulty, event pressure, cooldown, hidden‑ending flags, all resources, team size, and every character’s name/alive/hunger/thirst/health.
- Loading is robust: it checks file integrity, frees old memory, and allocates fresh team array.
The game is split into independent modules:
| File | Responsibility |
|---|---|
main.cpp |
Entry point, random seed, initEvents() |
game.cpp |
Main menu, game loop, daily orchestration, final summary |
player.cpp |
Character status, food/water consumption, medicine, death handling |
event.cpp |
Event pool, random selection, tool mitigation, hidden ending |
exploration.cpp |
Exploration logic, cooldown, difficulty‑based outcomes, meta‑awakening |
config.cpp |
Difficulty parameters (start resources, thresholds, event chance) |
save.cpp |
File I/O: save and load game state |
scavenging.cpp |
Timed pre‑shelter scavenging phase |
Enjoy surviving. And watch out for the truth behind the code.
This project is a command-line-based post-apocalyptic survival text game. The implementation centers around the following 5 required coding elements:
Uses C/C++ random number interfaces to generate non-deterministic behavior:
- Multiple random events implemented in
event.cpp/event.h, such as resource loss, character illness, exploration hazards, etc. - In the main game loop (
game.cppcontains functions likerunGame()), random numbers are used to determine:- Whether an event is triggered on a given day;
- Which type of event is triggered;
- The outcome of the event (success/failure, damage/reward magnitude, etc.).
- In exploration and timed scavenging phases (
scavenging.cpp), random numbers similarly decide:- Whether a search is successful;
- The resource quantity ranges obtained from different locations (house / supermarket / pharmacy / hardware store / fire station);
- Whether hazards are encountered, injuries sustained. Through these random mechanisms, each playthrough exhibits variability and replayability.
Utilizes custom structures/classes and standard library containers to organize game state:
game.h/game.cpp: Defines the overall game state structure, such as:CharacterInventoryGameState- Current day and target survival days
- Difficulty setting and configuration
- Shelter resources (food, water, medicine, tools)
player.h/player.cpp: Handles player-related operations such as daily state updates, damage handling, medicine usage, and death checks.Character* teamtogether withteamSizestores the current team in the running game state.std::vectorand other STL containers are used inevent.cppandexploration.cppfor the event pool and temporary alive-character lists.- Appropriate data structures in
event.cpp,exploration.cpp, andscavenging.cppfor managing event tables, location information, resource mappings, etc., ensuring clear logic and extensibility.
The project demonstrates dynamic memory management through:
- During initialization, new games, and loading saves in
game.cpp/save.cpp:- Player objects and resource states are created based on save data or difficulty configuration
- Appropriate number of instances correspond to actual game needs
- Unified initialization and cleanup flows prevent memory leaks and maintain consistency and maintainability of game state throughout the entire runtime.
File reading and writing are implemented in save.h / save.cpp:
- Uses
<fstream>library'sstd::ofstreamandstd::ifstreamfor text file operations - Save file contents include:
- Current day number and difficulty information (derived from
configstructures) - Quantities of various resources (food, water, medicine, tools)
- States of all players (name, health value, hunger, thirst, illness/death flags, etc.)
- Current day number and difficulty information (derived from
- During load operations:
- Game state is restored from files in fixed format
- Player lists and resource values are reconstructed
- The game can continue from the interruption point
The project adopts a modular multi-file design, dividing different functionalities into independent .h / .cpp files:
config.*: Difficulty and parameter configurationevent.*: Random event systemexploration.*: Daily exploration logicscavenging.*: Timed scavenging phase at game startgame.*: Main game flow and state managementplayer.*: Player/companion data structures and related operationssave.*: Save and load functionalitymain.cpp: Program entry point, responsible for menu and top-level control Each module exposes interfaces through header files, with implementation logic in source files. TheMakefileunified compilation and linking. This structure improves code readability and maintainability, aligning with course requirements for multi-file programming.
The project primarily uses C/C++ standard libraries (<iostream>, <vector>, <string>, <fstream>, etc.), without dependency on external third-party libraries, ensuring direct compilation and execution in the course environment.
Compile the project in the root directory with:
makeRun the game with:
./shelter_secondsYou can rebuild from scratch with:
make clean && make