- Lab
- Core Tech

Guided: Build a Text-Based Adventure Game in Rust
This hands-on lab is designed to help you practice your understanding of core Rust concepts. A series of guided steps will give you a walkthrough on how to apply your knowledge of these fundamental Rust concepts in a development setting. By the end of the lab, you will have demonstrated your ability to build a functioning multi-modular Rust application using these concepts.

Path Info
Table of Contents
-
Challenge
Introduction
In this lab, you have been given a text-based adventure game application in Rust. However, the major components have not been fully completed. As such, it will be your responsibility to finish each of their implementations within this lab.
The application can be run at any time by executing the
cargo run
command in the terminal or clicking the Run button in the terminal.Note: You may notice that when completing tasks for earlier modules(ie. modules 1 and 2) the test output may still output warnings. This is normal as these warnings are just referencing the later modules you have not yet completed and will gradually disappear as you progress.
-
Challenge
Step 1: Implementing the Player
The first incomplete component is the Player. The
Player
module is located withinplayer.rs
, which has aPlayer
struct already defined. There are also multiple spawning functions for each class, each with their own distinct values. Theget_class_input()
method is a predefined auxiliary function for reading your input when selecting a class.You will need to complete the
Player
module by implementingpick_class()
for selecting your class at the start of the game,level_up()
for strengthening your character on each level up,rest_health()
for healing between dungeon rooms, andplayer_attack()
to simulate combat.Instructions
let player; if selected_class is warrior(value of 1) set player to spawn_warrior() print warrior class selection else if selected class is wizard(value of 2) set player to spawn_wizard() print wizard class selection else set player to spawn_ranger() print ranger class selection player.expect("No player class was selected.")
Hint #1
Use the
Option
enum in Rust withSome()
when assigning theplayer
variable. This is done usingplayer = Some(input)
which extracts the value ofinput
and assigns it to theplayer
if it exists, orNone
if it doesn't.Hint #2
The functions to spawn a class are defined for you at the top of the
Player
module. Functions of a module can be called in Rust with the syntaxModule::function()
. For example,Player::spawn_warrior()
.Instructions
let mut enough_xp = true; while enough_xp is true define req_exp for level up if self.exp >= req_exp increment self.level subract req_exp from self.exp increase player stat values based off self.class print level up message else set enough_xp to false
Hint #1
When increasing stat values, use a
match
statement.match
works similar toswitch
statements from other languages . The default case of thematch
statement should be to do nothing in the format_ => {}
Instructions
if self.rests >= 1 calculate half_hp(self.max_health/2) if self.current_health <= half_hp, self.current_health += half_hp else self.current_health = self.max_health decrement self.rests by 1 print current health print remaining rests else print no more rests message
Hint #1
You can use a ternary statement when setting
self.current_health
.Instructions
let mut base_dmg = rng.gen_range(self.min_damage to self.max_damage) let total_damage check if attack is a critical hit, if it is then double base_dmg check if dmg_ismagic if it is, set total_damage to base_damage - mob.resistance or 1 if the value is less than 1 if dmg_ismagic is false set total_damage to base_damage - mob.armor or 1 if the value is less than 1 subtract total_damage from mob.current_health if attack is critical hit, print critical hit message. Else print normal damage message.
Hint #1
To calculate if an attack is a critical hit, use
rng.gen_range()
to generate a value between 1 and 100, inclusive. If this value is less than or equal to self.crit_chance, then the attack is a critical. -
Challenge
Step 2: Implementing the Mobs
The
Mob
module contains all the data regarding the monsters you will encounter in this game. It is very similar to thePlayer
module as it has aMob
struct with multiple spawning functions for mobs with their own distinct values.The only function that you will need to complete is the
mob_attack()
function to simulate combat against the player.Instructions
check if player dodge rolled successfully if player didnt dodge calculate base damage similar to the previous task let mut total_damage = 1 #Minimum damage a mob does to a player is 1 if self.dmg_ismagic calculate total damage as base damage - player.resistance or 1 else calculate total damage as base damage - player.armor or 1 subtract total damage from player.health print damage done to player else print dodge message #no damage should have been done to player
Hint #1
Since
total_damage
should be initialized as one, it should only be changed if the calculated damage done to the player is >= 1. -
Challenge
Step 3: Dungeon Generation
Now we will need to populate the dungeon with the completed
Mob
creatures. It would be a good idea to familiarize yourself with all the mob spawning functions that were already predefined for you in theMob
module as they'll be used extensively here.Hint #1
Since the functions to spawn the mobs are in the separate
Mob
module, you will need to spawn them with theModule::function()
syntax. Sinceroom_mobs
is just a vector, you can simplypush()
the spawned mob intoroom_mobs
. -
Challenge
Step 4: Game State
The last module to complete is the
GameState
which stores data on the current progression of the game.player_victory()
andproceed_room()
are the two functions that you will need to implement here.Instructions
print statements add curr_mob.exp to player.exp call player.level_up() #use player parameter, not Player module increment mob_index #Dereference pointer set self to GameState::AwaitingInput #Dereference pointer
Hint #1
When working with variables that are references, you need to dereference them to directly modify the value they point to. This is done by prefixing a
*
to the variable name such as*example -=5
Instructions
increment room_number #Derefence pointer increment player.rests #No need to dereference set mob_index to 0 #Dereference pointer set self to GameState::AwaitingInput #Dereference pointer
What's a lab?
Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.
Provided environment for hands-on practice
We will provide the credentials and environment necessary for you to practice right within your browser.
Guided walkthrough
Follow along with the author’s guided walkthrough and build something new in your provided environment!
Did you know?
On average, you retain 75% more of your learning if you get time for practice.