Skip to main content

pyrct2

Python client for OpenRCT2. Launch headless games, read state, execute actions, all in Python!

Connects to the openrct2-bridge plugin over TCP. Every game action, state query, and enum is auto-generated from OpenRCT2 C++ source by openrct2-codegen.

Install

pip install pyrct2
pyrct2 setup        # finds OpenRCT2, installs the bridge plugin

Quick start

from pyrct2.client import RCT2
from pyrct2.scenarios import Scenario

# Launch a built-in scenario
with RCT2.launch(Scenario.CRAZY_CASTLE) as game:
    print(f"{game.park.name}: rating {game.park.rating}, cash ${game.park.finance.cash}")

# Or load a scenario/save by path
with RCT2.launch("/path/to/my_park.park") as game:
    print(game.park.name)

# Or connect to an already-running instance
with RCT2.connect() as game:
    print(game.park.name)

Building a park

from pyrct2.client import RCT2
from pyrct2.enums import Direction, StaffType
from pyrct2.objects import RideObjects, FootpathAdditions, FootpathSurfaces, FootpathRailings
from pyrct2.scenarios import Scenario
from pyrct2.world import Tile

with RCT2.launch(Scenario.TEST_PARK, headless=False) as game:
    game.park.cheats.build_in_pause_mode()
    game.park.finance.set_entrance_fee(10)

    # -- Match the scenario's path style --
    game.paths.set_default_surface(FootpathSurfaces.TARMAC)

    # -- Place a flat ride south of the main path --
    ride = game.rides.place_flat_ride(
        obj=RideObjects.gentle.MERRY_GO_ROUND,
        tile=Tile(44, 34),
        entrance=Tile(44, 32),
        exit=Tile(46, 34),
        direction=Direction.NORTH,
    )
    ride.set_price(30)
    ride.open()

    # -- Place some stalls along the main path --
    burger = game.rides.place_stall(RideObjects.stall.BURGER_BAR, Tile(42, 29))
    burger.open()
    drink = game.rides.place_stall(RideObjects.stall.DRINKS_STALL, Tile(46, 29))
    drink.open()

    # -- Paths --
    game.paths.place_line(Tile(44, 30), Tile(44, 31))           # branch to ride
    game.paths.place(Tile(44, 31), queue=True)                   # queue to entrance
    game.paths.place_line(Tile(46, 30), Tile(46, 34))            # exit path back

    # path additions
    game.paths.place_addition(Tile(43, 30), FootpathAdditions.LAMP1)
    game.paths.place_addition(Tile(45, 30), FootpathAdditions.BENCH1)
    game.paths.place_addition(Tile(47, 30), FootpathAdditions.LITTER1)

    # verify connectivity from entrance to ride
    assert game.paths.is_connected(Tile(48, 30), Tile(44, 31))

    # -- Staff --
    handyman = game.park.staff.hire(StaffType.HANDYMAN)
    handyman.set_patrol_area(Tile(40, 28), Tile(50, 36))
    game.park.staff.hire(StaffType.MECHANIC)

    # -- Open the park and let it run --
    game.park.open()
    game.park.cheats.generate_guests(50)
    game.advance_ticks(100)

    # -- Read state --
    print(f"Rating: {game.park.rating}, Guests: {game.park.guests.count()}")
    print(f"Cash: {game.state.park().cash}")
    for r in game.state.rides():
        print(f"  {r.name}: {r.status}, excitement {r.excitement}")

Building tracked rides (beta)

Tracked rides — coasters, water rides, transport rides, and tracked gentle rides — can be built piece by piece via game.rides.create_tracked_ride() and .place(). This is a new, beta feature and the API may change.

See examples/ for 12 worked layouts and its README for the construction guide and circuit-geometry cheat sheet.

Raw API

All 82 game actions and state queries are available directly if you need something the high-level API doesn't wrap yet:

# Actions (raw ints, less friendly)
game.actions.staff_hire_new(auto_position=True, staff_type=0, costume_index=0, staff_orders=0)
game.actions.ride_set_price(ride=0, price=50, is_primary_price=True)

# State queries (full Pydantic models)
game.state.date()                          # GameDate — ticks, day, month, year
game.state.scenario()                      # Scenario — objectives, completion status
game.state.climate()                       # Climate — current/future weather
game.state.park_messages()                 # list[ParkMessage] — guest complaints, awards
game.state.park_awards()                   # list[Award]
game.state.park_research()                 # Research — invented/uninvented items
game.state.guests()                        # list[Guest] — every guest in the park

Requirements

  • Python 3.11+
  • OpenRCT2 installed with RCT2 game data

OpenRCT2 version compatibility

pyrct2 officially targets OpenRCT2 v0.5.0. Older versions may work but mileage may vary — development started on v0.4.32 so support starts from that version.

Release files for pyrct2 0.10.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyrct2 0.10.0
File Size Uploaded
pyrct2-0.10.0.tar.gz 226.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pyrct2 0.10.0
File Interpreter ABI Platform
pyrct2-0.10.0-py3-none-any.whl Python 3 none any Details

Total release size: 355.0 kB

Release files / pyrct2-0.10.0.tar.gz

Download URL pyrct2-0.10.0.tar.gz
Size 226.8 kB
Tags Source
SHA-256 checksum
How to use checksums
68ef92f23de923b7c4aae1040d8650f6ffbf8bcf7de11ddb7bce5bedc1c8e6cf
BLAKE2b-256 checksum
How to use checksums
7442299c713c07c0253b7a9bc93b2fd3d395ddda1f051442b5c45fde964dbe25
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 27, 2026.

Transparency log

Release files / pyrct2-0.10.0-py3-none-any.whl

Download URL pyrct2-0.10.0-py3-none-any.whl
Size 128.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3d3ef0a5a472e7ec3baeba6761554ad00626294af55c56b944786f7d25c4a7ea
BLAKE2b-256 checksum
How to use checksums
d77899f26bba2101b4236d50b0d4c296c439f9759ba3c0f699389f79cd26b214
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 27, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.10.0 This release

2 release files

0.9.8

2 release files

0.9.7

2 release files

0.9.6

2 release files

0.9.5

2 release files

0.9.3

2 release files

0.9.2

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page