Build the OpenRCT2 Touch MVP described in docs/openrct2-ipados-BUILD-PLAN.md on the ipad branch. Continue autonomously through the smallest verifiable engineering slice until the current goal's exit criteria are green. Preserve user-owned game data, upstream provenance, and a green macOS-first build. Stop only at an explicit human gate or when three materially different attempts have demonstrated the same external blocker.
The terminal outcome is a signed native iPadOS build that imports the user's own RCT2 data, loads a scenario, can build a coaster and place scenery with pointer and finger controls at at least 30 fps on a mid-size park, and loads one plugin or custom scenario. Apple Pencil and multiplayer are explicitly outside this release scope.
Repeat this sequence for one small slice at a time:
- Observe: read
AGENTS.md, this file, the current goal,git status, and the last failing proof. - Protect: confirm the branch is allowed and run
./scripts/check-repo-safety.shbefore any build, commit, staging, archive, or install operation. - Choose: select the smallest unmet exit criterion. Do not start work from a later goal.
- Define proof first: write down the exact command and observable result that will prove the slice complete.
- Implement: make one reversible change. Do not mix infrastructure, behavior, and polish unless the proof requires all three.
- Verify fast to slow: static/safety checks, focused build or test, full macOS headless loop, Simulator, then device only when applicable.
- Diagnose: on failure, preserve the error, form a new hypothesis, and make a materially different attempt. After three attempts at the same external blocker, stop at the human gate with evidence.
- Audit: inspect the diff, licences, generated artifacts, and tracked files. Confirm no proprietary asset entered a tracked file or distributable bundle.
- Checkpoint: when green, create one
[touch] ...commit, record the proof, and updateAGENTS.mdif a goal was completed. - Advance: move to the next goal only when every current exit criterion is green.
Each iteration reports: current goal, slice, changed files, proof commands and outcomes, remaining risk, and the next slice or human gate.
- Work is on
ipad; the already-published documentation commit ondevelopis preserved rather than rewritten. ref/data is ignored andgit ls-files refreports onlyref/README.mdor nothing.upstreamhas no usable push URL in the local clone../scripts/bootstrap.shand./scripts/check-repo-safety.shexit 0.- Root instructions, environment paths, and the initial
[touch]commit exist.
./scripts/build-macos.shbuilds native arm64 from a clean build directory.- All runtime roots are repo-local.
./scripts/run-macos-headless.shloads a tracked, legally redistributable smoke park, simulates fixed ticks, rejects fatal/assert logs, and exits 0.- A windowed run works with the user's local RCT2 data.
- CMake distinguishes macOS from iOS instead of treating every
APPLEtarget as Cocoa/macOS. - The UI code can be linked into an iOS app target; do not assume the existing desktop
openrct2executable is alibopenrct2uilibrary. - Device arm64 and Simulator arm64 dependency smoke targets link successfully.
- Exact dependency sources, versions, hashes, flags, licences, and slices are recorded in
vendor/MANIFEST.md. - OpenGL, HTTP, networking, FLAC, and Vorbis start disabled; scripting stays enabled. Re-enable optional features deliberately later.
- The UIKit/SDL entry point links the engine and launches in an iPad Simulator.
- Logs are streamable and lifecycle transitions do not crash.
- The build contains only redistributable engine assets and shows either the title UI or a clean missing-data/import state.
- The engine software framebuffer is presented through SDL's iOS Metal renderer.
- Landscape, Retina scale, safe areas, palette, aspect ratio, and resize/lifecycle behavior are correct.
- A repeatable Simulator screenshot check is green.
- Bundle resources are read-only; Documents/Library paths are writable and survive relaunch.
- The Files picker validates
Data/g1.dat, copies or coordinates access safely, reports progress/errors, and persists the selected path. - Proprietary data is never copied into
.app,.ipa,.xcarchive, or another distributable artifact. Simulator seeding, if added, targets only an installed app container and refuses bundle/archive destinations. - A scenario loads through both a local developer flow and one manual Files import on a physical iPad.
- Existing SDL input is used where sufficient; GameController-specific glue is added only for uncovered behavior.
- Left/right/middle click, scroll, pointer movement, text entry, and shortcuts work on device.
- A coaster can be built and scenery placed end-to-end with a trackpad or mouse.
- Pinch zoom, two-finger pan, long-press secondary action, tap/confirm placement, window manipulation, and usable hit targets pass focused tests.
- The human confirms the MVP can be completed with fingers and the interaction feels acceptable.
- The root README is the canonical install guide and matches the implemented build, signing, Files import, controls, and limitations.
- Apple Pencil and multiplayer are explicitly unsupported rather than promoted.
- The app bundle contains the GPL, attribution, dependency manifest, and third-party licence texts while rejecting proprietary game data.
- Fork-specific issue and contribution paths do not redirect iPad users to upstream support.
- At least 30 fps on the agreed mid-size park with recorded device/build/settings.
- A 30-minute stress session does not OOM.
- The top three reproducible device crashes are fixed and regression-covered where practical.
- One JavaScript plugin or custom scenario loads on-device.
- Safety checks prove no proprietary assets are present in the archive/export.
- A signed build installs through the chosen private channel and the complete demo script passes on a physical iPad.
Stop and ask for the human only for:
- first device provisioning, signing, trust, or account selection;
- touch-control feel decisions;
- a dependency/toolchain blocker repeated across three materially different attempts;
- any operation that could place proprietary data in source control or a distributable artifact;
- a choice that materially changes scope, licensing, or distribution.
- The current fork began with the port documents committed on
develop; do not rewrite that published history. Branch from it once, then keep new work onipad. - The local RCT2 install is under
ref/Rollercoaster Tycoon 2, notref/rct2; environment discovery supports both without moving user files. - The root CMake build currently creates
libopenrct2plus anopenrct2UI executable. Goal 2 must establish an iOS-linkable UI target or an equivalent source target. - Existing Apple guards and framework links mean macOS (
Cocoa,CoreServices) and iOS (UIKit, mobile-safe APIs) must be separated explicitly. Ui.cppexposesSDL_mainonly for Android today; the iOS entry-point contract must be proven rather than assumed.- Proprietary data may be placed only in an installed app sandbox for local testing, never staged into a bundle that could be archived or shared.