Build a Choose Your Own Adventure Script in Python: Absolute Beginners Tutorial

A choose your own adventure game is one of the best first Python projects because it teaches variables, user input, conditional branching, and functions through a task that immediately produces something playable. By the end of this tutorial you will have a working branching script you can run in any terminal.

Python is one of the most readable programming languages available, and that readability makes it forgiving for beginners. Rather than memorizing syntax in isolation, this tutorial builds a short text adventure scene by scene. Each scene introduces exactly one new concept, so nothing arrives without context.

What Python Concepts This Game Teaches

A choose your own adventure script is simple enough to finish in one sitting, yet complex enough to require four core Python tools: variables to remember information, input() to collect choices, if/elif/else to branch the story, and functions to organize each scene into its own named block. These four concepts appear in almost every Python program ever written, making this project a practical foundation rather than a toy.

Before you start

You need Python 3 installed on your machine. Open a terminal and run python --version or python3 --version to confirm. Any version from 3.8 onward works for this tutorial. Create a new file called adventure.py and open it in any text editor.

The game structure you will build looks like this: a player reaches a crossroads, chooses a path, faces a second decision in that path, and arrives at one of several endings. Every fork in the story is one if/elif/else block, and every location is one function. The result is a script you can extend indefinitely by adding new functions and calling them from existing branches.

Why Story Projects Work for Learning

When code controls a narrative, mistakes have obvious consequences. If the branching logic is wrong, the player ends up in the wrong scene. If the variable storing the player's name is misspelled, the greeting breaks. Errors become plot problems, which makes them easier to notice and reason about than abstract syntax exercises.

Variables and User Input

A variable is a named container that holds a value. In Python you create one by writing a name, an equals sign, and the value you want to store. There are no type declarations and no reserved words like var or let. Python infers the type from the value you assign.

python
# Store a string in a variable
player_name = "Alex"

# Store a number
health = 100

# Python infers the type — no declaration needed
print(player_name)   # outputs: Alex
print(health)        # outputs: 100

Variable names in Python are case-sensitive and can contain letters, numbers, and underscores, but cannot start with a number. The convention is lowercase with underscores separating words — a style called snake_case. Consistent naming makes code easier to scan at a glance.

Collecting Input From the Player

The input() function pauses execution, displays an optional prompt string, and waits for the user to type something and press Enter. Whatever the user types is returned as a string. You store that string in a variable exactly as you would store any other value.

python
# Ask the player for their name
player_name = input("What is your name, traveller? ")

# Greet them using the stored value
print("Welcome, " + player_name + "!")

The string passed to input() is the prompt the player sees. Including a trailing space inside the string keeps the cursor from touching the text. The return value of input() is always a string — if you ever need to treat the input as a number, you wrap it: int(input("Enter a number: ")).

Pro Tip

Use .lower() on player input before comparing it in conditions. choice.lower() converts the string to all lowercase, so typing "Forest", "FOREST", or "forest" all match the same branch. Without this, a capital letter causes unexpected behavior.

code builder click a token to place it

Build the correct Python statement to collect a player's name and store it in a variable called player_name:

your code will appear here...
"Enter your name: " print( player_name ) input( == =
Why: Assignment uses a single =, not the comparison operator ==. The variable name goes on the left. input() is the function call that collects the text, and the prompt string goes inside its parentheses. print() is for output only — it does not collect input and does not return a value you can store.

Branching With if, elif, and else

An if statement evaluates a condition. If the condition is True, the indented block below it runs. If it is False, Python skips that block and moves on. Adding elif (else if) checks a second condition when the first was false. Adding else at the end catches every case that did not match any of the earlier conditions.

python
choice = input("Go left or right? ").lower()

if choice == "left":
    print("You enter the dark forest.")
elif choice == "right":
    print("You cross the stone bridge.")
else:
    print("You stand still, unsure. Nothing happens.")

Python requires that each if, elif, and else line ends with a colon. The body of each branch must be indented consistently — four spaces is the universal Python convention. If the indentation is inconsistent, Python raises an IndentationError before the script even runs.

"Programs must be written for people to read, and only incidentally for machines to execute." — Harold Abelson, Structure and Interpretation of Computer Programs

Nested Conditions: A Second Choice Inside a Branch

After the player picks a path, the story can branch again. You add a second if/elif/else block inside the first branch. Each level of nesting adds four more spaces of indentation. Python uses that indentation to know which block belongs to which condition, so consistency is not optional — it is syntax.

python
choice = input("Go left or right? ").lower()

if choice == "left":
    print("You enter the dark forest.")
    second = input("Follow the light or run back? ").lower()
    if second == "follow":
        print("The light leads to a hidden village. You win!")
    elif second == "run":
        print("You escape the forest safely.")
    else:
        print("You freeze. The light fades. Game over.")
elif choice == "right":
    print("You cross the stone bridge.")
else:
    print("You hesitate too long. Game over.")
spot the bug click the line that contains the bug

The function below tries to branch on a player's choice but contains one bug. Click the line you think is wrong, then hit check.

1 choice = input("Enter cave or climb tree? ").lower()
2 if choice == "cave":
3 print("You crawl into the dark cave.")
4 elif choice == "climb":
5 print("You climb high and spot a path.")
6 else:
7 print("That is not a valid choice.")
The fix: Line 3 is missing its four-space indent. The print() call is the body of the if choice == "cave": block, so it must be indented by four spaces. Without the indent, Python raises an IndentationError and the script refuses to run. The corrected line is:     print("You crawl into the dark cave.")

How to Build a Choose Your Own Adventure Script in Python

The following steps walk through building the complete game from an empty file to a runnable script. Each step builds directly on the previous one. Copy the code into your adventure.py file as you go.

  1. Set up your Python file

    Create a file called adventure.py. Add a single print("Adventure starting...") line and run it with python adventure.py in your terminal. Confirming that the script runs before writing more code saves time debugging environment issues later.

  2. Collect the player's name with input()

    Replace the placeholder print with two lines: player_name = input("What is your name, traveller? ") and print("Welcome, " + player_name + ". Your journey begins."). Run the script again and type your name to confirm the greeting works.

  3. Write the first scene with if/elif/else

    After the greeting, add a scene description with print(), then collect a choice with choice = input("Enter forest or cross bridge? ").lower(). Follow that with an if choice == "forest": block, an elif choice == "bridge": block, and an else: block that handles any other input.

  4. Wrap each scene in a function

    Move the first scene into a function called def crossroads(name): and pass player_name as an argument. Create a second function def forest_path(name): and call it from inside the if choice == "forest": branch. Functions keep each scene self-contained and make the story tree easy to visualize.

  5. Add a guard clause and run the game

    At the bottom of the file add: if __name__ == "__main__": followed by the indented lines that collect the player's name and call crossroads(player_name). This guard clause ensures the game only starts when the file is run directly, not when it is imported as a module. Run python adventure.py and play through every branch.

Below is the complete game script combining all five steps. Read through it once before running it so you can trace how each function call connects the scenes.

python
# adventure.py — Choose Your Own Adventure
# Concepts: variables, input(), if/elif/else, functions

def forest_path(name):
    print(f"\nYou step into the dark forest, {name}.")
    print("A strange light flickers ahead.")
    choice = input("Follow the light or turn back? ").lower()

    if choice == "follow":
        print("\nThe light leads to a hidden village.")
        print("The villagers welcome you. You win!")
    elif choice == "turn back":
        print("\nYou return to the crossroads safely.")
        crossroads(name)
    else:
        print("\nYou hesitate too long. The light vanishes. Game over.")


def bridge_path(name):
    print(f"\nYou cross the old stone bridge, {name}.")
    print("A troll blocks the far end.")
    choice = input("Fight the troll or offer gold? ").lower()

    if choice == "fight":
        print("\nYou defeat the troll. The road ahead is clear. You win!")
    elif choice == "offer gold":
        print("\nThe troll accepts and steps aside. You pass safely. You win!")
    else:
        print("\nYou freeze. The troll grows impatient. Game over.")


def crossroads(name):
    print(f"\nYou stand at a crossroads, {name}.")
    print("To the left: a dark forest. To the right: a stone bridge.")
    choice = input("Enter forest or cross bridge? ").lower()

    if choice == "forest":
        forest_path(name)
    elif choice == "bridge":
        bridge_path(name)
    else:
        print("\nYou wander in circles and collapse from exhaustion. Game over.")


if __name__ == "__main__":
    print("=== The Crossroads Adventure ===")
    player_name = input("What is your name, traveller? ")
    print(f"\nWelcome, {player_name}. Your journey begins.")
    crossroads(player_name)
Common mistake

Notice the script uses f-strings: f"Welcome, {player_name}.". The lowercase f before the opening quote tells Python to treat anything inside curly braces as an expression to evaluate. Without the f, the curly braces print literally as text. F-strings require Python 3.6 or newer.

Python Learning Summary Points

  1. A variable stores a value under a name. Assignment uses a single =. Comparison uses ==. Confusing the two is one of the most common beginner errors.
  2. The input() function always returns a string. Call .lower() on the result before comparing it in a condition to handle any capitalization the player uses.
  3. Python uses indentation to define code blocks. Every line inside an if, elif, else, or def body must be indented by four spaces. Missing or inconsistent indentation causes an IndentationError.
  4. Functions defined with def keep each scene self-contained. Calling one function from inside another is how the story tree connects without duplicating code.
  5. The guard clause if __name__ == "__main__": is a Python convention that prevents startup code from running when the file is imported. Always include it when your script has a main entry point.

From here, extend the game by adding more functions, passing a health or inventory variable between scenes, or using a while loop to let the player return to the crossroads after a wrong choice. Each addition will introduce the next layer of Python without losing the context of a working project.

check your understanding question 1 of 5

Frequently Asked Questions

None. This tutorial is written for absolute beginners. It introduces variables, input(), if/elif/else, and functions from scratch as you build the game step by step. You do need Python 3 installed on your machine before starting.

The input() function pauses your script and waits for the user to type something and press Enter. Whatever the user types is returned as a string, which you can store in a variable. The optional string argument you pass to input() is the prompt displayed before the cursor.

An if/elif/else statement lets your script choose different paths based on a condition. If the condition after if is true, that block runs. elif (else if) checks a second condition when the first was false. else catches everything that did not match any earlier condition. Only one branch runs per evaluation.

Python uses indentation — typically four spaces — to define code blocks rather than curly braces. This is a deliberate design choice that enforces readable, consistently formatted code. Mixing spaces and tabs in the same file causes an IndentationError. Configure your text editor to insert spaces when you press Tab to avoid the issue entirely.

A function is a named, reusable block of code defined with the def keyword. Functions let you group related logic, avoid repeating the same code, and give each section of your script a clear purpose. In this game, each scene is a function, which makes adding new scenes as simple as writing a new function and calling it from an existing branch.

Save the file with a .py extension. Open a terminal or command prompt, navigate to the folder containing the file, and run: python adventure.py (or python3 adventure.py on systems where both Python 2 and Python 3 are installed). The script starts at the top and executes line by line.

When Python compares strings with ==, it checks for an exact character-by-character match including letter case. "Forest" and "forest" are not equal. Calling .lower() on the player's input before comparing it normalizes the string to all lowercase so any capitalization the player uses still matches the expected branch.

Add new functions for each scene, then call them from within existing branches. Each function follows the same pattern: print a description, collect input with input(), then use if/elif/else to route the player to the next scene function. You can also pass variables like a health score or inventory list between functions as arguments to make choices have persistent consequences.