An Ultima III–inspired top-down, turn-based RPG built with Python and Pygame. Lead a party of four adventurers through a procedurally generated world of overworld exploration, town visits, dungeon delving, and tactical grid combat.
This is a hobby project. The programming was done with the help of AI (primarily Anthropic's Claude), and the codebase is designed to be approachable for anyone who wants to tinker, extend, or learn from it. See the Developer Guide for tips on how to make changes yourself — even if you're not a programmer.
![]() |
![]() |
![]() |
![]() |
See the full visual tour → — title screen, party creation, overworld, combat, dungeons, towns, and more.
A pre-built macOS version is available on the Releases page. To get started:
- Download the
.zipfile from the latest release. - Unzip it — you'll get a folder called
RealmOfShadow. - Before opening the game, you must clear the macOS quarantine flag. Open Terminal and run:
If you unzipped it somewhere other than Downloads, adjust the path — or drag the folder onto the Terminal window to fill it in automatically. You need to do this each time you download a new release.
xattr -cr ~/Downloads/RealmOfShadow/ - Open the
RealmOfShadowfolder and double-click the file calledRealmOfShadow(the one with no file extension) to launch the game.
First launch: The game may take 10–20 seconds to appear the first time you run it while your system unpacks and caches the bundled libraries. Subsequent launches will be faster.
"Damaged and can't be opened" error: If you skipped step 3 and macOS says the app is damaged, don't worry — the file isn't actually damaged. macOS shows this message for any downloaded app that isn't notarized with Apple. Run the
xattr -crcommand from step 3 and try again.
Before diving into the code, these documents give useful context on the game's design and mechanics:
- Developer Guide — project structure, architecture, testing, making changes, working with AI, and game design philosophy. Start here if you want to contribute or modify the game.
- Player's Manual — races, classes, combat, spells, quests, items, and controls from the player's perspective. Illustrations are in
docs/manuals/images/. - Visual Style Guide — color palette, layout rules, sprite specs, and tile patterns. Derived from the Ultima III reference screenshots in
docs/research/. - Graphics Reference — tile IDs, sprite assignments, and asset file locations for every visual element.
- Combat Mechanics — the single source of truth for how attacks, damage, defense, and spells work under the hood.
- Ultima III Character Reference — original game's race/class/attribute system, used as a design template.
- Ultima III StrategyWiki — external reference for the original game.
The docs/research/ folder also contains reference screenshots (example_combat.webp, example_overview_map.png, etc.) and sprite reference material in docs/research/example_graphics/ that were used to guide the visual style.
-
Python 3.9 or newer. Check with
python3 --versionin a terminal. If you don't have it:- Mac:
brew install python3(if you have Homebrew) or download from python.org - Windows: Download from python.org — check "Add Python to PATH" during install
- Linux:
sudo apt install python3 python3-pip(Ubuntu/Debian) or your distro's equivalent
- Mac:
-
Git (to clone the repo). Most Macs and Linux systems have it already. Windows users can get it from git-scm.com.
-
Clone the repository:
git clone https://github.com/mattjcamp/game_rpg_turn_based_open_world cd game_rpg_turn_based_open_world -
Install dependencies:
pip3 install -r requirements.txtThis installs Pygame (graphics/audio) and NumPy (used for procedural music generation).
-
Run the game:
python3 main.py
That's it. A window should open with the title screen.
Overworld:
- Arrow keys or WASD — Move the party
- E — Examine the local area (zoomed-in view of the current tile)
- L — Load game
- P — Pause / open settings
- H — Help
- Walk into a town tile to enter it; walk into a dungeon tile to enter it
- ESC — Quit
Towns:
- Arrow keys or WASD — Move
- Walk into NPCs to talk; Space/Enter to advance dialogue
- ESC — Leave town
Dungeons:
- Arrow keys or WASD — Move
- Walk into monsters to fight; walk into chests to loot
- ESC on stairs — Leave dungeon
Combat (tactical grid):
- WASD — Move on the arena grid (each move takes a turn)
- Walk into a monster to melee attack
- Arrow keys — Navigate action menu
- Enter — Confirm action
- ESC — Flee attempt
Examine mode:
- Arrow keys or WASD — Walk around the zoomed-in area
- Q — Drop an item from inventory
- ESC — Return to overworld
If you want to build the game yourself (or build for a platform not listed in Releases), you can package it into a standalone app using PyInstaller.
pip3 install pyinstaller
python3 build_game.py
This runs PyInstaller using the included realm_of_shadow.spec and produces a ready-to-distribute folder at dist/RealmOfShadow/. The build takes a minute or two. On macOS, the script automatically applies an ad-hoc code signature to reduce Gatekeeper warnings.
Note: You need to build on each platform you want to support — a Mac produces a Mac build, Windows produces a Windows build, etc.
Zip the output folder and share it:
cd dist && zip -r RealmOfShadow-mac.zip RealmOfShadow/
Upload the zip to itch.io, attach it to a GitHub Release, or send it directly.
Windows — Unzip the folder and double-click RealmOfShadow.exe. If Windows Defender SmartScreen shows a warning, click "More info" and then "Run anyway."
Linux — Unzip the folder, then in a terminal:
chmod +x RealmOfShadow/RealmOfShadow
./RealmOfShadow/RealmOfShadow
The test suite runs entirely headless (no display needed) using a mock pygame layer defined in tests/conftest.py.
pip3 install pytest
python3 -m pytest tests/ -v
All 177 tests should pass. Run this before and after making changes to catch regressions.
For project structure, architecture, testing details, making changes (including with AI), and game design notes, see the Developer Guide.



