This guide is for contributors who build Trestle on macOS. It explains the launcher target and the game-runtime boundary.
The iOS target provides these launcher features:
IosRuntimeBridge implementation for the bundled, in-process Java runtime.Physical-device builds include pinned Java 25, LWJGL, audio, and graphics runtime files. The Xcode host loads these files at runtime. Trestle owns the launcher interface, instance data, authentication, and launch arguments. The native host creates Trestle’s game surface and translates direct touch input to GLFW cursor and mouse events. The Xcode target does not link to the bundled Amethyst libraries. It loads them from the app at runtime.
The implementation follows the native runtime architecture from these projects:
Trestle pins Amethyst iOS commit 9212a1894865e7ac0466029e25ddb0d895544c76. The build verifies the source archive and Java archive before it copies files into the app. The app also contains Amethyst’s GPL license text.
Use a Mac with Xcode 16.4 or newer and JDK 21.
iosApp/Trestle.xcodeproj in Xcode.Trestle target.net.blockhost.trestle.The Xcode build phase runs this Gradle task:
./gradlew :shared:embedAndSignAppleFrameworkForXcode
You can compile the Kotlin target without Xcode:
./gradlew :shared:compileKotlinIosSimulatorArm64
This command compiles Kotlin code. It does not link or launch the iOS application on Linux.
Build the device application on a Mac:
xcodebuild \
-project iosApp/Trestle.xcodeproj \
-scheme Trestle \
-configuration Release \
-sdk iphoneos \
-destination 'generic/platform=iOS' \
-derivedDataPath build/ios \
ARCHS=arm64 \
CODE_SIGNING_ALLOWED=NO \
build
Then package the application. Install ldid if you also need the jailbreak package:
python3 scripts/package-ios.py \
--app build/ios/Build/Products/Release-iphoneos/Trestle.app \
--version 0.1.0 \
--output build/release-artifacts \
--jailbreak-entitlements iosApp/iosApp/Trestle.jailbreak.entitlements
The command creates an unsigned IPA and an ldid-signed .tipa. The IPA needs an Apple account and provisioning profile before normal installation. The .tipa is for a compatible jailbroken or TrollStore device.
AmethystRuntimeBridge.swift implements IosRuntimeBridge. TrestleApp.swift passes it to TrestleViewController.
The bridge must provide these operations:
JLI_Launch in the application process.IosJvmLaunchObserver.The bridge owns the native runtime and Java lifecycle. Trestle owns the interface, installation, authentication, and launch arguments.
The runtime descriptor must exclude normal desktop LWJGL files. It must provide patched iOS LWJGL files instead.
Minecraft needs JIT for usable Java performance on iOS. Standard App Store signing does not enable unrestricted JIT.
The Xcode target contains these public memory entitlements:
com.apple.developer.kernel.extended-virtual-addressingcom.apple.developer.kernel.increased-memory-limitYour Apple account and provisioning profile must permit these entitlements. Remove an entitlement if your profile rejects it.
The normal Xcode entitlement file contains only public memory entitlements. The separate jailbreak entitlement file follows Amethyst’s unrestricted runtime package. Do not use that file for App Store or normal development signing.
For development, Xcode can attach LLDB to the application. Other installation methods need a compatible JIT or jailbreak environment.