Mod
OpenRCT2
With Python
Add your own shops, create custom menu items, and upgrade stalls step by step, watching your park update live on the right.
Add your own shops, create custom menu items, and upgrade stalls step by step, watching your park update live on the right.
Understand what OpenRCT2 modding is and see the starter file structure.
OpenRCT2 is a free, open-source remake of RollerCoaster Tycoon 2. Because it's open source, you can mod it — changing and adding things like shops, rides, and more. We'll use Python to write mod scripts that define custom stalls, menu items, and prices. Think of it as telling the game "add this shop, sell these things."
The main file we'll be editing is called custom_shops.py. Here's what an empty one looks like:
Learn what a variable and a string are by naming your park.
Every mod should have a park name. This is the string (piece of text) that appears above the entrance gate. In Python, text is stored in a variable using quote marks.
PARK_NAME = "Pixel Paradise" creates a box called PARK_NAME and puts the text "Pixel Paradise" inside it. Python uses ALL_CAPS for values that shouldn't change (called constants).Create a dictionary to define a shop with name, type, and colour.
Time to add a stall! In Python, a group of related values is stored in a dictionary — like a mini database for one thing. Each shop is a dictionary with keys like "name", "type", and "colour".
{} and stores key: value pairs. Like a form — "name" is the label, "Pip's Ice Creams" is the answer. .append() adds the shop onto the end of our list.Create a list of menu items, each with a name and price.
A stall needs things to sell! In Python, a list (square brackets) lets us store multiple items. Each item on the menu is a small dictionary with a name and a price.
items list?Add a second stall and use a for loop to register all shops.
Parks need variety! Let's add a second stall. We'll also learn how Python's for loop goes through every item in a list — exactly how the game registers all your stalls when the park loads.
for stall in shops: goes through each stall one at a time and runs the indented code below it. The game uses this same pattern to load all mods at startup.for stall in shops: do?Write a reusable function that creates and returns stall dictionaries.
A function is a reusable chunk of code that does a specific job. Instead of writing the same "add a stall" code over and over, we write a function called create_stall() and call it whenever we need it.
def, then a name, then parameters in brackets (the things it needs to do its job). The word return sends a result back. The colour="orange" part is a default value — if you don't say a colour, it uses orange automatically.create_stall("Tacos", "food_stall") without giving a colour, what colour will it use?Write if/elif/else logic to check whether visitors will buy based on price.
OpenRCT2 visitors check if prices are fair before they buy. We can code that logic too — with if/elif/else — Python's way of making decisions.
Create a souvenir shop with a list of items nested inside the dictionary.
Now let's build a souvenir shop with a full list of items inside it — a list inside a dictionary. This is called nested data and it's everywhere in real game modding.
"items" is a key whose value is a whole list of dictionaries. Real game files use this pattern constantly — rides have lists of cars, parks have lists of rides, and so on.Learn how to modify and add new keys to a dictionary after it's been created.
In OpenRCT2 you can upgrade stalls over time — fancier decor, extra items, better machines. In Python this means updating a dictionary's values after it's been created.
stall["sign"] = "fancy_sign" adds a new key or overwrites an existing one. This is how upgrade systems work in almost every game.stall["staff"] = 2 do?Write the final register_mod() function that brings everything together.
You've learned variables, dictionaries, lists, loops, functions, if/else, and nested data — that's real Python. Now let's write the final register_mod() function that would actually run in OpenRCT2.
len(shops) return?Learn how to save your mod's data to a JSON file using Python's built-in json module.
Real mods save their settings so they're remembered next time. Python's built-in json module lets you write your shop list to a file and read it back — in just a few lines.
import json loads Python's JSON module. with open(...) as f: opens a file safely — Python closes it automatically when the block ends. json.dump() converts your Python dictionary into a JSON text file. indent=2 makes it readable with nice spacing.with open(filename, "w") as f: do?Load mod data from a JSON file so the game remembers your stalls between sessions.
Saving is only useful if you can load it back. We use json.load() to read the file and rebuild the shops list — so the mod remembers everything even after the game restarts.
global tells Python we want to change the variable at the top of the file, not create a new local one inside the function. os.path.exists() checks if the file is there before trying to open it — without this the mod would crash on first run when there's no save yet.os.path.exists(filename) before opening?🛠️ Free In-House Dev Tools
Use these free browser tools alongside this workshop to create custom sprites, sounds, levels and colour schemes for your game. No installs. Free forever.