Skip to Content
Course content

435: Building a Simple Text-Based Adventure Game

Click on the "Edit" button in the top corner of the screen to edit your slide content.

A few years ago, I was reviewing a PR for a junior dev who was building a small RPG for a game jam. He had written this massive, 400-line block of nested if and elif statements to handle player movement. It looked like a pyramid of doom. When he tried to add a sixth room to his map, he accidentally broke the logic for the first room, and suddenly players were teleporting from the dungeon straight to the credits screen. He spent an entire Saturday chasing a bug that was simply a misplaced indentation. That's when I sat him down and showed him that a game world isn't a sequence of logic gates—it's a data structure.

Mapping Your World with Dictionaries

If you try to hard-code every possible movement in a text adventure, you'll hit a wall very quickly. The trick is to separate your game logic from your game data. I prefer using a nested dictionary to represent the world. In this setup, each key is a room, and its value is another dictionary containing the room's description and the directions available to move to other rooms.

world_map = {
    'Great Hall': {
        'description': 'A vast room with flickering torches and a cold stone floor.',
        'exits': {'north': 'Library', 'east': 'Kitchen'}
    },
    'Library': {
        'description': 'Dusty shelves reach the ceiling. It smells of old parchment.',
        'exits': {'south': 'Great Hall'}
    },
    'Kitchen': {
        'description': 'A greasy hearth and a heavy iron pot. Something is simmering.',
        'exits': {'west': 'Great Hall'}
    }
}

By structuring the map this way, your movement code doesn't need to know which room the player is in. It just needs to check if the user's input exists as a key in the current room's exits dictionary. This makes your game infinitely expandable without adding a single new if statement to your movement logic.

Driving the Action with a Game Loop

Every game, from Pong to Elden Ring, runs on a loop. In a text adventure, this loop is quite simple: get input, update the state, and print the result. I usually wrap this in a while True loop that only breaks when a specific "win" or "lose" condition is met. You'll want to track the player's current location in a variable—let's call it current_room—and update it based on the movement logic we discussed.

current_room = 'Great Hall'

while True:
    room = world_map[current_room]
    print(f"\nYou are in the {current_room}.\n{room['description']}")
    
    move = input("Which direction do you want to go? (north, south, east, west): ").lower()
    
    if move in room['exits']:
        current_room = room['exits'][move]
    else:
        print("You can't go that way!")

Notice how clean this is. The logic remains the same whether you have three rooms or three thousand. I've seen developers try to create separate functions for every room, but that's a recipe for a stack overflow and a lot of redundant code. Keep the loop lean.

Handling Inventory and Game State

A game isn't much of a game if you can't pick things up or unlock doors. To handle this, you can add an items list to your room dictionaries and a separate inventory list for the player. When a player types "get key", you check if the key is in the current room's list. If it is, you pop() it from the room and append() it to the player's inventory.

The real power comes when you tie movement to these items. Instead of just checking if a direction exists in exits, you can add a "locked" attribute to certain paths. Before updating current_room, check if the path is locked and if the player possesses the required key in their inventory list. It's a simple boolean check that transforms a walking simulator into an actual puzzle game.




📋 Practical Task

Building the Locked Cellar Gate

Your task is to expand the basic game loop into a small playable sequence. You need to create a world map with three rooms: a 'Hallway', a 'Cellar', and a 'Treasury'.

  • The Hallway should have an exit to the Cellar (south).
  • The Cellar should have an item called 'Rusty Key' and an exit to the Treasury (east).
  • The Treasury should be the win condition; once the player enters this room, the game prints "You found the gold!" and exits the loop.
  • The Twist: The exit from the Cellar to the Treasury must be locked. The player cannot enter the Treasury unless 'Rusty Key' is in their inventory list.

Implement a simple command system where the user can type "go [direction]" to move or "get [item]" to pick up the key.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.