×

Search anything:

Open World RPG Game in Python

Internship at OpenGenus

Get this book -> Problems on Array: For Interviews and Competitive Programming

Table of contents:

  1. Introduction
  2. Step 1: Create Player Class
  3. Step 2: Define Character Types
  4. Step 3: Implement Player Creation and Login
  5. Step 4: Implement Open World Exploration
  6. Step 5: Testing our RPG Game
  7. Conclusion

Reading time: 25 minutes

Introduction

In this OpenGenus article, we will cover the steps necessary for creating your very own open-world RPG game in Python programming language. An open-world RPG is a gaming genre that involves world exploration, character roles, combat, and an immersive story. In the game, players can do the following:

  • Create their own character: player can choose from different character types with their own unique stats.
  • Explore: Set out on a journey through Crystal Caves, Glittering Gardens, Fairy Forests, Mystical Mountains, and the Swamp of Secrets
  • Make Choices: Throughout their journey, players will have to make decisions on how they'd like to move forward.
  • Level Up: Players gain XP throughout their journey based on the decisions they make.

Since these design aspects of an RPG game involve creativity and planning, we will first define the basics of what you need to get started.

My implementation includes a well-defined player class, character type class, functions that faciliate player creation and login such as create_player() and login(), and a variety of implementations for player exploration such as explore_region(player), crystal_cave_exploration(player), glittering_gardens_exploration(player), etc.

Step 1: Create Player Class

To provide a solid foundation for an RPG game, it is essential to first outline a player class that manages their stats, data, and abilities. We will include stats such as attack, defense, health, and data such as level and experience. This class will also be in charge of keeping track of player level and updating player data on file.

On input, the player class will take the in-game name, character type, and password. Later on in the article, we will define character types and how they influence the player's stats. For now, we assume that the player's stats are equivalent to the stats defined for a character role:

# Define Player class
class Player:
    def __init__(self, ign, character_type, password):
        self.ign = ign
        self.character_type = character_type
        self.password = password
        self.attack = character_type.attack
        self.health = character_type.health
        self.defense = character_type.defense
        self.xp = 0
        self.level = 1

    def update_player_stats(self, new_attack, new_health, new_defense):
        self.attack = new_attack
        self.health = new_health
        self.defense = new_defense

    def level_up(self):
        self.level += 1
        print("Level Up! You are now level " + str(self.level))
        self.save_to_file() 

    def calculate_level(self):
        return self.level * 100
    
    def gain_xp(self, amount):
        self.xp += amount
        while self.xp >= self.calculate_level():
            self.level_up()
        self.save_to_file()
            
    def save_to_file(self):
        with open("players.txt", "r") as file:
            lines = file.readlines()

        with open("players.txt", "w") as file:
            for line in lines:
                if self.ign in line:
                    line = f"{self.ign} {self.password} {self.character_type.name} {self.attack} {self.health} {self.defense} {self.level} {self.xp}\n"
                file.write(line)

update_player_stats(self, new_attack, new_health, new_defense) is responsible for updating a player's attack, health, and defense when it changes based on gameplay.

level_up(self) levels up a player.

calculate_xp(self) calculates the number of xp required for a player to level up. The calculation is customizable, but as an example, the amount of xp required will be 100 times the level. For example, if the player is level 5, the amount of xp required to level up would be 100 x 5 = 500 xp.

gain_xp(self, amount) increases a player's xp by a given amount when they have earned it through gameplay. If a player's xp has reached the required amount to level up, it levels up the player.

save_to_file(self) updates player data to file so that upon re-logging in, their data and game progress are saved.

Step 2: Define Character Types

As previously mentioned, the character type the player picks will influence the starting amount of attack, health, and defense they receive. For example, some types receive higher attack but lower health and defense, while for others it's the opposite. Again, this is completely customizable depending on the characters you'd like to create.

In my code, I created five types: fairy, wizard, elf, goblin, and valkyrie. Their character stats are defined below.

# Define CharacterType class
class CharacterType:
    def __init__(self, name, attack, health, defense):
        self.name = name
        self.attack = attack
        self.health = health
        self.defense = defense

# Define different character types
fairy = CharacterType("Fairy", 100, 1150, 100)
wizard = CharacterType("Wizard", 275, 900, 175)
elf = CharacterType("Elf", 200, 1000, 150)
goblin = CharacterType("Goblin", 125, 1000, 225)
valkyrie = CharacterType("Valkyrie", 250, 850, 250)

Step 3: Implement Player Creation and Login

For first-time users to play the game, they will need to make an account. We will define two functions: create_player and login.

create_player prompts a user for a username and password and saves that data to the players.txt file if the user doesn't already exist. If the username does exist, it prompts the user to enter a new username. Additionally, the user is asked to choose a character type, which will also be saved on file.

login facilitates user login by prompting a user to enter a username and password and checking if those user credentials match what is on record. If an incorrect user or password is input, it prompts the user to try again. Otherwise, the user will be successfully logged in and will be able to begin their open-world exploration.

# Define create_player function, which prompts the user for a username and password
# The user must choose an original username that doesn't already exist on file
# Saves player data to file players.txt
def create_player():
    while True:
        player_name = input("Enter your in-game username: ")
        password = input("Enter your password: ")

        user_exists = False
        if os.path.exists("players.txt"):
            with open("players.txt", "r") as file:
                for line in file:
                    if player_name in line:
                        print("User is already taken. Please choose a different username.")
                        user_exists = True
                        break

        if not user_exists:
            while True:
                print("Choose your character type: ")
                print("1. Fairy\n2. Wizard\n3. Elf\n4. Goblin\n5. Valkyrie")
                character_type_choice = input()
                if character_type_choice == "1":
                    player = Player(player_name, fairy, password)
                elif character_type_choice == "2":
                    player = Player(player_name, wizard, password)
                elif character_type_choice == "3":
                    player = Player(player_name, elf, password)
                elif character_type_choice == "4":
                    player = Player(player_name, goblin, password)
                elif character_type_choice == "5":
                    player = Player(player_name, valkyrie, password)
                break
            # Check if the file doesn't exist and write the header
            if not os.path.exists("players.txt"):
                with open("players.txt", "w") as f:
                    f.write("Username Password CharacterType Attack Health Defense Level XP\n")

            # Append the player's data
            with open("players.txt", "a") as f:
                f.write(f"{player.ign} {player.password} {player.character_type.name} {player.character_type.attack} {player.character_type.health} {player.character_type.defense} {player.level} {player.xp}\n")
                print("User created successfully!")
                break

# Login 
def login():
    while True:
        username = input("Enter your username: ")
        password = input("Enter your password: ")
        player_found = False
        user = None

        with open("players.txt", "r") as file:
            for line in file:
                fields = line.split()
                if len(fields) == 8:
                    stored_username, stored_password = fields[0], fields[1]
                    if username == stored_username and password == stored_password:
                        player_found = True
                        character_type = CharacterType(fields[2], int(fields[3]), int(fields[4]), int(fields[5]))
                        user = Player(stored_username, character_type, stored_password)

        if not player_found:
            print("Invalid username or password. Please try again.")
        else:
            return user

Step 4: Implement Open World Exploration

This step is the most creative one by far since it involves formulating the open-world landscape. Laying out the different regions and the specific actions a player can take within those regions are entirely up to you as the creator!

In my open-world game, I created 5 regions: Crystal Cave, Glittering Gardens, Fairy Forest, Mystical Mountains, and Swamp of Secrets. Here is an example of what a couple of these regions look like:

def crystal_cave_exploration(player):
    print("You hear an ominous noise coming from the caves left tunnel, but there's a tiny glimmer of light.\n")
    print("The tunnel to the right is pitch black and silent.\n")
    print("1. Left\n2. Right\n")
    path = input("Which path would you like to take? ")
    if path == "1":
        print("What a relief! The noise was just the dripping of water from the top of the cave... But what is that light?\n")
        print("You've found a lucky health crystal! +50 Health")
        player.health += 50
        player.gain_xp(50)
    elif path == "2":
        print("An evil bat was silently waiting in the darkness. Get ready to fight!")
        print("1. Cast a spell\n2. Shoot an arrow")
        fight = input("We must defeat the bat to get out of here alive. Choose your attack: ")
        if fight == "1":
            print("The spell is successful. +50 Attack")
            player.attack += 50
            player.gain_xp(50)
        elif fight == "2":
            print("The arrow misses, and the bat bares its fangs before quickly flying away. -50 Health")
            player.health -= 50
            player.gain_xp(50)

def glittering_gardens_exploration(player):
    print("You stumble upon a beautiful flower field and contemplate picking one so you can always remember the beautiful sight.")
    print("Do you pick the flower?")
    print("1. Yes\n2. No")
    choice = input()
    if choice == "1":
        print("An angry elf comes running. 'How dare you touch my flowers!?'")
        print("You run away from the garden to avoid causing a scene.")
        player.health -= 50
        player.gain_xp(50)
    elif choice == "2":
        print("Might aswell enjoy the scenery while you can.")
        print("You stay at the flower field, taking in the beautiful colors.")
        print("Soon, the sun begins the set and night falls quickly.")
        print("An elf nearby notices you. 'Hello, are you lost?")
        print("1. Yes\n2. No")
        lost_choice = input()
        if lost_choice == "1":
            print("'Here's a map to help you find your way home. Goodluck on your travels!'")
            player.defense += 50
            player.gain_xp(50)
        elif lost_choice == "2":
            print("You inform the elf that you were just admiring the beautiful field and lost track of time.")
            print("The elf says, 'This is my field, but it's been a long time since I've been able to share the view with another. Please, take this flower and come again soon.'")
            player.health += 100
            player.gain_xp(100)

To explore the different regions upon selection, we must additionally prompt the user for a region on the map to travel to. Depending on their input, they will be sent to that region (and the corresponding function for that region will be run). Below, we define explore_region that takes a location as input and facilitates exploration:

regions = {
    "0": "Back to Main Menu",
    "1": "Crystal Cave",
    "2": "Glittering Gardens",
    "3": "Fairy Forest",
    "4": "Mystical Mountains",
    "5": "Swamp of Secrets"
    }


def explore_region(player):
    while True:
        print("\nMap:")
        for key, value in regions.items():
            print(f"{key}. {value}")
        location = input("Select a place to explore: ")

        if location == "0":
            break
        elif location == "1":
            crystal_cave_exploration(player)
        elif location == "2":
            glittering_gardens_exploration(player)
        elif location == "3":
            fairy_forest_exploration(player)
        elif location == "4":
            mystical_mountains_exploration(player)
        elif location == "5":
            swamp_of_secrets_exploration(player)
        else:
            print("Invalid choice. Please select a valid option.")

Step 5: Testing our RPG Game

To test our RPG game, we must run the code and create a new user. You can do this by simply running the command python3 rpg.py in terminal (in the corresponding folder where the python file is located).

Upon running the code, this is what your output should look like:
Screenshot-2023-10-16-223109

Next, input the value '1' to create a new user. Then, input your username and password and pick a character type.
Screenshot-2023-10-16-223334

You can use this same user data to log in. Once logged in successfully, you can begin playing the game and exploring the open world.

Conclusion

Overall, creating a text-based RPG game in Python is the easiest and most simple approach to the task. Other methods can be utilized to further complicate the creation of your RPG game such as:

  • Gaming Engines: game engines can be used to bring RPG games to life with beautiful graphics and gameplay while ensuring they run smoothly.
  • Utilizing different programming languages (such as C++) since some other languages can be better utilized for high performance and adaptability to other platforms. But, this depends on many factors.
  • Higher level game mechanics (such as inventory and weapons): adding a collection aspect to your game in addition to a choice of weapon could further enhance the user's gaming experience and make it more enjoyable.

Here is the complete code for the open-world RPG game in Python:

import os
# Define Player class
class Player:
    def __init__(self, ign, character_type, password):
        self.ign = ign
        self.character_type = character_type
        self.password = password
        self.attack = character_type.attack
        self.health = character_type.health
        self.defense = character_type.defense
        self.xp = 0
        self.level = 1

    def update_player_stats(self, new_attack, new_health, new_defense):
        self.attack = new_attack
        self.health = new_health
        self.defense = new_defense

    def level_up(self):
        self.level += 1
        print("Level Up! You are now level " + str(self.level))
        self.save_to_file() 

    def calculate_level(self):
        return self.level * 100
    
    def gain_xp(self, amount):
        self.xp += amount
        while self.xp >= self.calculate_level():
            self.level_up()
        self.save_to_file()
            
    def save_to_file(self):
        with open("players.txt", "r") as file:
            lines = file.readlines()

        with open("players.txt", "w") as file:
            for line in lines:
                if self.ign in line:
                    line = f"{self.ign} {self.password} {self.character_type.name} {self.attack} {self.health} {self.defense} {self.level} {self.xp}\n"
                file.write(line)
                
# Define CharacterType class
class CharacterType:
    def __init__(self, name, attack, health, defense):
        self.name = name
        self.attack = attack
        self.health = health
        self.defense = defense

# Define different character types
fairy = CharacterType("Fairy", 100, 1150, 100)
wizard = CharacterType("Wizard", 275, 900, 175)
elf = CharacterType("Elf", 200, 1000, 150)
goblin = CharacterType("Goblin", 125, 1000, 225)
valkyrie = CharacterType("Valkyrie", 250, 850, 250)

# Define create_player function, which prompts the user for a username and password
# The user must choose an original username that doesn't already exist on file
# Saves player data to file players.txt
def create_player():
    while True:
        player_name = input("Enter your in-game username: ")
        password = input("Enter your password: ")

        user_exists = False
        if os.path.exists("players.txt"):
            with open("players.txt", "r") as file:
                for line in file:
                    if player_name in line:
                        print("User is already taken. Please choose a different username.")
                        user_exists = True
                        break

        if not user_exists:
            while True:
                print("Choose your character type: ")
                print("1. Fairy\n2. Wizard\n3. Elf\n4. Goblin\n5. Valkyrie")
                character_type_choice = input()
                if character_type_choice == "1":
                    player = Player(player_name, fairy, password)
                elif character_type_choice == "2":
                    player = Player(player_name, wizard, password)
                elif character_type_choice == "3":
                    player = Player(player_name, elf, password)
                elif character_type_choice == "4":
                    player = Player(player_name, goblin, password)
                elif character_type_choice == "5":
                    player = Player(player_name, valkyrie, password)
                break
            # Check if the file doesn't exist and write the header
            if not os.path.exists("players.txt"):
                with open("players.txt", "w") as f:
                    f.write("Username Password CharacterType Attack Health Defense Level XP\n")

            # Append the player's data
            with open("players.txt", "a") as f:
                f.write(f"{player.ign} {player.password} {player.character_type.name} {player.character_type.attack} {player.character_type.health} {player.character_type.defense} {player.level} {player.xp}\n")
                print("User created successfully!")
                break

# Login 
def login():
    while True:
        username = input("Enter your username: ")
        password = input("Enter your password: ")
        player_found = False
        user = None

        with open("players.txt", "r") as file:
            for line in file:
                fields = line.split()
                if len(fields) == 8:
                    stored_username, stored_password = fields[0], fields[1]
                    if username == stored_username and password == stored_password:
                        player_found = True
                        character_type = CharacterType(fields[2], int(fields[3]), int(fields[4]), int(fields[5]))
                        user = Player(stored_username, character_type, stored_password)

        if not player_found:
            print("Invalid username or password. Please try again.")
        else:
            return user

def crystal_cave_exploration(player):
    print("You hear an ominous noise coming from the caves left tunnel, but theres a tiny glimmer of light.\n")
    print("The tunnel to the right is pitch black and silent.\n")
    print("1. Left\n2. Right\n")
    path = input("Which path would you like to take? ")
    if path == "1":
        print("What a relief! The noise was just the dripping of water from the top of the cave... But what is that light?\n")
        print("You've found a lucky health crystal! +50 Health")
        player.health += 50
        player.gain_xp(50)
    elif path == "2":
        print("An evil bat was silently waiting in the darkness. Get ready to fight!")
        print("1. Cast a spell\n2. Shoot an arrow")
        fight = input("We must defeat the bat to get out of here alive. Choose your attack: ")
        if fight == "1":
            print("The spell is successful. +50 Attack")
            player.attack += 50
            player.gain_xp(50)
        elif fight == "2":
            print("The arrow misses, and the bat bares its fangs before quickly flying away. -50 Health")
            player.health -= 50
            player.gain_xp(50)

def glittering_gardens_exploration(player):
    print("You stumble upon a beautiful flower field and contemplate picking one so you can always remember the beautiful sight.")
    print("Do you pick the flower?")
    print("1. Yes\n2. No")
    choice = input()
    if choice == "1":
        print("An angry elf comes running. 'How dare you touch my flowers!?'")
        print("You run away from the garden to avoid causing a scene.")
        player.health -= 50
        player.gain_xp(50)
    elif choice == "2":
        print("Might aswell enjoy the scenery while you can.")
        print("You stay at the flower field, taking in the beautiful colors.")
        print("Soon, the sun begins the set and night falls quickly.")
        print("An elf nearby notices you. 'Hello, are you lost?")
        print("1. Yes\n2. No")
        lost_choice = input()
        if lost_choice == "1":
            print("'Here's a map to help you find your way home. Goodluck on your travels!'")
            player.defense += 50
            player.gain_xp(50)
        elif lost_choice == "2":
            print("You inform the elf that you were just admiring the beautiful field and lost track of time.")
            print("The elf says, 'This is my field, but it's been a long time since I've been able to share the view with another. Please, take this flower and come again soon.'")
            player.health += 100
            player.gain_xp(100)

def fairy_forest_exploration(player):
    pass

def mystical_mountains_exploration(player):
    pass

def swamp_of_secrets_exploration(player):
    pass

regions = {
    "0": "Back to Main Menu",
    "1": "Crystal Cave",
    "2": "Glittering Gardens",
    "3": "Fairy Forest",
    "4": "Mystical Mountains",
    "5": "Swamp of Secrets"
    }


def explore_region(player):
    while True:
        print("\nMap:")
        for key, value in regions.items():
            print(f"{key}. {value}")
        location = input("Select a place to explore: ")

        if location == "0":
            break
        elif location == "1":
            crystal_cave_exploration(player)
        elif location == "2":
            glittering_gardens_exploration(player)
        elif location == "3":
            fairy_forest_exploration(player)
        elif location == "4":
            mystical_mountains_exploration(player)
        elif location == "5":
            swamp_of_secrets_exploration(player)
        else:
            print("Invalid choice. Please select a valid option.")


if __name__ == "__main__":
    while True:
        print("1. Create New Player\n2. Login\n3. Exit")
        choice = input("Select an option: ")
        if choice == "1":
            create_player()
        elif choice == "2":
            player = login()
            explore_region(player)
        elif choice == "3":
            print("Goodbye!")
            break
        else:
            print("Invalid choice. Please select a valid option.")

Jessica Janko

Jessica Janko is a third-year undergraduate at the University of Connecticut pursuing a Bachelor's in Computer Science with a curiosity in software development and cybersecurity.

Read More

Improved & Reviewed by:


Aditya Chatterjee Aditya Chatterjee
Open World RPG Game in Python
Share this