[{"data":1,"prerenderedAt":1580},["ShallowReactive",2],{"navigation_docs_en":3,"-en-developers-build-ios":272,"-en-developers-build-ios-surround":1575},[4,38,110,190,232],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":-1},"Getting started","i-lucide-rocket","\u002Fen\u002Fgetting-started","en\u002F1.getting-started\u002Findex",[10,13,18,23,28,33],{"title":11,"path":7,"stem":8,"icon":12},"Overview","i-lucide-layout-grid",{"title":14,"path":15,"stem":16,"icon":17},"Installation","\u002Fen\u002Fgetting-started\u002Finstallation","en\u002F1.getting-started\u002F01.installation","i-lucide-download",{"title":19,"path":20,"stem":21,"icon":22},"Sign in","\u002Fen\u002Fgetting-started\u002Fsign-in","en\u002F1.getting-started\u002F02.sign-in","i-lucide-log-in",{"title":24,"path":25,"stem":26,"icon":27},"Your first instance","\u002Fen\u002Fgetting-started\u002Ffirst-instance","en\u002F1.getting-started\u002F03.first-instance","i-lucide-play",{"title":29,"path":30,"stem":31,"icon":32},"Android: install the APK","\u002Fen\u002Fgetting-started\u002Fandroid","en\u002F1.getting-started\u002F04.android","i-lucide-smartphone",{"title":34,"path":35,"stem":36,"icon":37},"iPhone\u002FiPad: install with AltStore\u002FSideStore","\u002Fen\u002Fgetting-started\u002Fiphone-ipad","en\u002F1.getting-started\u002F05.iphone-ipad","i-lucide-tablet-smartphone",{"title":39,"icon":40,"path":41,"stem":42,"children":43,"page":-1},"Launcher","i-lucide-app-window","\u002Fen\u002Flauncher","en\u002F2.launcher\u002Findex",[44,45,50,55,60,65,70,75,80,85,90,95,100,105],{"title":11,"path":41,"stem":42,"icon":12},{"title":46,"path":47,"stem":48,"icon":49},"Instances","\u002Fen\u002Flauncher\u002Finstances","en\u002F2.launcher\u002F01.instances","i-lucide-boxes",{"title":51,"path":52,"stem":53,"icon":54},"Mod loaders","\u002Fen\u002Flauncher\u002Fmod-loaders","en\u002F2.launcher\u002F02.mod-loaders","i-lucide-layers",{"title":56,"path":57,"stem":58,"icon":59},"Mods","\u002Fen\u002Flauncher\u002Fmods","en\u002F2.launcher\u002F03.mods","i-lucide-puzzle",{"title":61,"path":62,"stem":63,"icon":64},"Modpacks","\u002Fen\u002Flauncher\u002Fmodpacks","en\u002F2.launcher\u002F04.modpacks","i-lucide-package",{"title":66,"path":67,"stem":68,"icon":69},"Share modpacks","\u002Fen\u002Flauncher\u002Fshare-modpacks","en\u002F2.launcher\u002F05.share-modpacks","i-lucide-share-2",{"title":71,"path":72,"stem":73,"icon":74},"Import from other launchers","\u002Fen\u002Flauncher\u002Fimport","en\u002F2.launcher\u002F06.import","i-lucide-folder-input",{"title":76,"path":77,"stem":78,"icon":79},"Clips & screenshots","\u002Fen\u002Flauncher\u002Fclips","en\u002F2.launcher\u002F07.clips","i-lucide-clapperboard",{"title":81,"path":82,"stem":83,"icon":84},"Friends & chat","\u002Fen\u002Flauncher\u002Fsocial","en\u002F2.launcher\u002F08.social","i-lucide-messages-square",{"title":86,"path":87,"stem":88,"icon":89},"Achievements","\u002Fen\u002Flauncher\u002Fachievements","en\u002F2.launcher\u002F09.achievements","i-lucide-trophy",{"title":91,"path":92,"stem":93,"icon":94},"Skins & capes","\u002Fen\u002Flauncher\u002Fwardrobe","en\u002F2.launcher\u002F10.wardrobe","i-lucide-shirt",{"title":96,"path":97,"stem":98,"icon":99},"Settings","\u002Fen\u002Flauncher\u002Fsettings","en\u002F2.launcher\u002F11.settings","i-lucide-settings",{"title":101,"path":102,"stem":103,"icon":104},"Updates","\u002Fen\u002Flauncher\u002Fupdates","en\u002F2.launcher\u002F12.updates","i-lucide-refresh-cw",{"title":106,"path":107,"stem":108,"icon":109},"Servers","\u002Fen\u002Flauncher\u002Fservers","en\u002F2.launcher\u002F13.servers","i-lucide-server",{"title":111,"icon":112,"path":113,"stem":114,"children":115,"page":-1},"TRS Client","i-lucide-blocks","\u002Fen\u002Fclient","en\u002F3.client\u002Findex",[116,117,121,126,131,136,141,146,151,156,160,165,170,175,180,185],{"title":11,"path":113,"stem":114,"icon":12},{"title":118,"path":119,"stem":120,"icon":112},"What is the TRS Client?","\u002Fen\u002Fclient\u002Foverview","en\u002F3.client\u002F01.overview",{"title":122,"path":123,"stem":124,"icon":125},"TRS menu and HUD editor","\u002Fen\u002Fclient\u002Fmenu-and-hud-editor","en\u002F3.client\u002F02.menu-and-hud-editor","i-lucide-layout-dashboard",{"title":127,"path":128,"stem":129,"icon":130},"Performance and FPS","\u002Fen\u002Fclient\u002Fperformance","en\u002F3.client\u002F03.performance","i-lucide-gauge",{"title":132,"path":133,"stem":134,"icon":135},"PvP modules","\u002Fen\u002Fclient\u002Fpvp","en\u002F3.client\u002F04.pvp","i-lucide-swords",{"title":137,"path":138,"stem":139,"icon":140},"Zoom, freelook and toggle sprint","\u002Fen\u002Fclient\u002Fzoom-and-freelook","en\u002F3.client\u002F05.zoom-and-freelook","i-lucide-zoom-in",{"title":142,"path":143,"stem":144,"icon":145},"Minimap, waypoints and world map","\u002Fen\u002Fclient\u002Fminimap-and-world-map","en\u002F3.client\u002F06.minimap-and-world-map","i-lucide-map",{"title":147,"path":148,"stem":149,"icon":150},"Redstone tools","\u002Fen\u002Fclient\u002Fredstone-tools","en\u002F3.client\u002F07.redstone-tools","i-lucide-zap",{"title":152,"path":153,"stem":154,"icon":155},"Circuit library","\u002Fen\u002Fclient\u002Fcircuit-library","en\u002F3.client\u002F08.circuit-library","i-lucide-cpu",{"title":157,"path":158,"stem":159,"icon":94},"Emotes, capes, wardrobe and accounts","\u002Fen\u002Fclient\u002Femotes-and-capes","en\u002F3.client\u002F09.emotes-and-capes",{"title":161,"path":162,"stem":163,"icon":164},"Screenshots, clips and panoramas","\u002Fen\u002Fclient\u002Fscreenshots-and-clips","en\u002F3.client\u002F10.screenshots-and-clips","i-lucide-camera",{"title":166,"path":167,"stem":168,"icon":169},"World notes","\u002Fen\u002Fclient\u002Fnotes","en\u002F3.client\u002F11.notes","i-lucide-notebook-pen",{"title":171,"path":172,"stem":173,"icon":174},"Chat and comfort","\u002Fen\u002Fclient\u002Fchat-and-comfort","en\u002F3.client\u002F12.chat-and-comfort","i-lucide-message-square",{"title":176,"path":177,"stem":178,"icon":179},"Social in game","\u002Fen\u002Fclient\u002Fsocial-in-game","en\u002F3.client\u002F13.social-in-game","i-lucide-users",{"title":181,"path":182,"stem":183,"icon":184},"Default keys","\u002Fen\u002Fclient\u002Fkeybinds","en\u002F3.client\u002F14.keybinds","i-lucide-keyboard",{"title":186,"path":187,"stem":188,"icon":189},"Host a world for friends","\u002Fen\u002Fclient\u002Fworld-hosting","en\u002F3.client\u002F15.world-hosting","i-lucide-globe",{"title":191,"icon":192,"path":193,"stem":194,"children":195,"page":-1},"Help","i-lucide-life-buoy","\u002Fen\u002Fhelp","en\u002F4.help\u002Findex",[196,197,202,207,212,217,222,227],{"title":11,"path":193,"stem":194,"icon":12},{"title":198,"path":199,"stem":200,"icon":201},"Crash helper","\u002Fen\u002Fhelp\u002Fcrash-helper","en\u002F4.help\u002F01.crash-helper","i-lucide-heart-pulse",{"title":203,"path":204,"stem":205,"icon":206},"Common problems","\u002Fen\u002Fhelp\u002Fcommon-problems","en\u002F4.help\u002F02.common-problems","i-lucide-circle-help",{"title":208,"path":209,"stem":210,"icon":211},"Java & memory","\u002Fen\u002Fhelp\u002Fjava","en\u002F4.help\u002F03.java","i-lucide-coffee",{"title":213,"path":214,"stem":215,"icon":216},"Linux","\u002Fen\u002Fhelp\u002Flinux","en\u002F4.help\u002F04.linux","i-lucide-terminal",{"title":218,"path":219,"stem":220,"icon":221},"Logs","\u002Fen\u002Fhelp\u002Flogs","en\u002F4.help\u002F05.logs","i-lucide-scroll-text",{"title":223,"path":224,"stem":225,"icon":226},"Report a bug","\u002Fen\u002Fhelp\u002Freport-a-bug","en\u002F4.help\u002F06.report-a-bug","i-lucide-bug",{"title":228,"path":229,"stem":230,"icon":231},"Privacy","\u002Fen\u002Fhelp\u002Fprivacy","en\u002F4.help\u002F07.privacy","i-lucide-shield-check",{"title":233,"icon":234,"path":235,"stem":236,"children":237,"page":-1},"Developers","i-lucide-code-xml","\u002Fen\u002Fdevelopers","en\u002F5.developers\u002Findex",[238,239,244,249,254,259,263,267],{"title":11,"path":235,"stem":236,"icon":12},{"title":240,"path":241,"stem":242,"icon":243},"Build from source","\u002Fen\u002Fdevelopers\u002Fbuild-from-source","en\u002F5.developers\u002F01.build-from-source","i-lucide-hammer",{"title":245,"path":246,"stem":247,"icon":248},"Contributing","\u002Fen\u002Fdevelopers\u002Fcontributing","en\u002F5.developers\u002F02.contributing","i-lucide-git-pull-request",{"title":250,"path":251,"stem":252,"icon":253},"Translating","\u002Fen\u002Fdevelopers\u002Ftranslating","en\u002F5.developers\u002F03.translating","i-lucide-languages",{"title":255,"path":256,"stem":257,"icon":258},"Public API","\u002Fen\u002Fdevelopers\u002Fpublic-api","en\u002F5.developers\u002F04.public-api","i-lucide-braces",{"title":260,"path":261,"stem":262,"icon":32},"Build the Android app yourself","\u002Fen\u002Fdevelopers\u002Fbuild-android","en\u002F5.developers\u002F05.build-android",{"title":264,"path":265,"stem":266,"icon":37},"Build the iOS app yourself with Xcode","\u002Fen\u002Fdevelopers\u002Fbuild-ios","en\u002F5.developers\u002F06.build-ios",{"title":268,"path":269,"stem":270,"icon":271},"TRS Server Rules","\u002Fen\u002Fdevelopers\u002Fserver-rules","en\u002F5.developers\u002F07.server-rules","i-lucide-server-cog",{"id":273,"title":264,"body":274,"description":1568,"extension":1569,"links":1570,"meta":1571,"navigation":1572,"path":265,"seo":1573,"stem":266,"__hash__":1574},"docs_en\u002Fen\u002F5.developers\u002F06.build-ios.md",{"type":275,"value":276,"toc":1533},"minimark",[277,285,330,362,367,472,476,597,615,618,1011,1015,1019,1022,1037,1158,1165,1169,1212,1215,1245,1251,1255,1258,1340,1344,1351,1356,1378,1382,1388,1392,1405,1409,1415,1419,1431,1435,1446,1450,1468,1472,1475,1479,1482,1486,1511,1514,1518,1529],[278,279,280,281,284],"p",{},"The iOS app is the same Tauri 2 project as the desktop launcher, built for iPhone and iPad. This page is for\ncontributors and for players who want to build the IPA themselves instead of taking ours. If you only want to play,\ninstall the official app – see ",[282,283,34],"a",{"href":35},".",[286,287,288,294],"warning",{},[278,289,290],{},[291,292,293],"strong",{},"Before you start:",[295,296,297,305,316,327],"ul",{},[298,299,300,301,304],"li",{},"You need a ",[291,302,303],{},"Mac with Xcode",". The Xcode project can only be generated on macOS, so it is not in the repository – a\nscript creates it.",[298,306,307,310,311,315],{},[291,308,309],{},"Playing Minecraft needs the game engine and JIT",", exactly like with the official app. The engine is added to the\nfinished app in a separate step (see ",[282,312,314],{"href":313},"#build-the-ipa","Build the IPA","). An app you start directly from Xcode has no\nengine: everything else works, but games don't start.",[298,317,318,319,322,323,326],{},"Apps signed with a ",[291,320,321],{},"free Apple ID"," stop opening after ",[291,324,325],{},"7 days"," and must be re-signed (refreshed). A free Apple ID\ncan have only 3 sideloaded apps at the same time.",[298,328,329],{},"Only real devices (arm64) are built – there is no build for the iOS Simulator.",[278,331,332,333,337,338,341,342,345,346,349,350,353,354,357,358,361],{},"The commands on this page are the ones the CI runs (",[334,335,336],"code",{},".github\u002Fworkflows\u002Fci.yml"," job ",[291,339,340],{},"launcher-ios",",\n",[334,343,344],{},"release.yml"," jobs ",[291,347,348],{},"iOS"," and ",[291,351,352],{},"iOS engine",", ",[334,355,356],{},".github\u002Fworkflows\u002Fios-engine.yml","). The CI never signs the app – it\nbuilds an ",[291,359,360],{},"unsigned IPA",", and AltStore\u002FSideStore sign it with the user's Apple ID when installing.",[363,364,366],"h2",{"id":365},"what-is-where","What is where",[368,369,370,383],"table",{},[371,372,373],"thead",{},[374,375,376,380],"tr",{},[377,378,379],"th",{},"Path",[377,381,382],{},"What it is",[384,385,386,405,415,425,439,449,459],"tbody",{},[374,387,388,394],{},[389,390,391],"td",{},[334,392,393],{},"scripts\u002Fios-project.sh",[389,395,396,397,400,401,404],{},"Creates the Xcode project in ",[334,398,399],{},"src-tauri\u002Fgen\u002Fapple"," (",[334,402,403],{},"tauri ios init",") and adds icons and Info.plist keys",[374,406,407,412],{},[389,408,409],{},[334,410,411],{},"scripts\u002Fios-unsigned-ipa.sh",[389,413,414],{},"Builds the Rust library, then an Xcode archive without code signing, zipped as IPA",[374,416,417,422],{},[389,418,419],{},[334,420,421],{},"scripts\u002Fios\u002Fbuild-engine.sh",[389,423,424],{},"Builds the game engine (Amethyst-iOS at a pinned commit, CMake, MobileGlues, Java part)",[374,426,427,432],{},[389,428,429],{},[334,430,431],{},"scripts\u002Fios\u002Fpackage-ipa.sh",[389,433,434,435,438],{},"Puts the engine into the app and signs it with ",[334,436,437],{},"ldid"," and the entitlements",[374,440,441,446],{},[389,442,443],{},[334,444,445],{},"src-tauri\u002Ftauri.ios.conf.json",[389,447,448],{},"iOS overrides of the Tauri config (iOS 15, no desktop updater)",[374,450,451,456],{},[389,452,453],{},[334,454,455],{},"src-tauri\u002FInfo.ios.plist",[389,457,458],{},"Camera text (QR code of the PC remote) and background fetch for notifications",[374,460,461,466],{},[389,462,463],{},[334,464,465],{},"src-tauri\u002Fplugins\u002Ftauri-plugin-trs-game\u002Fios\u002F",[389,467,468,469],{},"Swift part, engine sources, ",[334,470,471],{},"trs-game.entitlements",[363,473,475],{"id":474},"requirements","Requirements",[368,477,478,488],{},[371,479,480],{},[374,481,482,485],{},[377,483,484],{},"Tool",[377,486,487],{},"Version \u002F note",[384,489,490,509,531,549,566,581],{},[374,491,492,498],{},[389,493,494,495],{},"macOS with ",[291,496,497],{},"Xcode",[389,499,500,501,504,505,508],{},"with the iPhoneOS SDK. The repository doesn't pin an Xcode version; the CI uses the default Xcode of GitHub's ",[334,502,503],{},"macos-latest"," runner (app) and ",[334,506,507],{},"macos-15"," (engine)",[374,510,511,519],{},[389,512,513],{},[282,514,518],{"href":515,"rel":516},"https:\u002F\u002Fbrew.sh",[517],"nofollow","Homebrew",[389,520,521,522,525,526,349,528],{},"for ",[334,523,524],{},"xcodegen"," (the script installs it if missing), ",[334,527,437],{},[334,529,530],{},"cmake",[374,532,533,536],{},[389,534,535],{},"Node.js and pnpm",[389,537,538,541,542,400,545,548],{},[291,539,540],{},"Node 22",", pnpm as pinned in ",[334,543,544],{},"package.json",[334,546,547],{},"corepack enable",")",[374,550,551,554],{},[389,552,553],{},"Rust",[389,555,556,557,562,563],{},"stable via ",[282,558,561],{"href":559,"rel":560},"https:\u002F\u002Frustup.rs",[517],"rustup",", target ",[334,564,565],{},"aarch64-apple-ios",[374,567,568,574],{},[389,569,570,571],{},"JDK ",[291,572,573],{},"8",[389,575,576,577,580],{},"only for the engine (CI: Zulu 8). It must be a JDK 8 – ",[334,578,579],{},"build-engine.sh"," checks that",[374,582,583,594],{},[389,584,585,353,588,353,591],{},[334,586,587],{},"git",[334,589,590],{},"python3",[334,592,593],{},"zip",[389,595,596],{},"used by the scripts",[278,598,599,600,400,603,606,607,610,611,614],{},"The app needs ",[291,601,602],{},"iOS 15",[334,604,605],{},"minimumSystemVersion"," in ",[334,608,609],{},"tauri.ios.conf.json","). The CI sets\n",[334,612,613],{},"IPHONEOS_DEPLOYMENT_TARGET=15.0"," for the app, because the Swift packages of the plugins use APIs from iOS 14 on; the\nengine itself is built for 14.0.",[363,616,314],{"id":617},"build-the-ipa",[619,620,622,627,699,703,715,719,731,748,752,788,791,857,880,884,917,950,954,975,991,995],"steps",{"level":621},"3",[623,624,626],"h3",{"id":625},"get-the-code-and-the-tools","Get the code and the tools",[628,629,634],"pre",{"className":630,"code":631,"language":632,"meta":633,"style":633},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","git clone https:\u002F\u002Fgithub.com\u002Ftheredstonee\u002FTRS-Launcher.git\ncd TRS-Launcher\npnpm install\nrustup target add aarch64-apple-ios\nbrew install ldid cmake\n","bash","",[334,635,636,651,661,670,684],{"__ignoreMap":633},[637,638,641,644,648],"span",{"class":639,"line":640},"line",1,[637,642,587],{"class":643},"sBMFI",[637,645,647],{"class":646},"sfazB"," clone",[637,649,650],{"class":646}," https:\u002F\u002Fgithub.com\u002Ftheredstonee\u002FTRS-Launcher.git\n",[637,652,654,658],{"class":639,"line":653},2,[637,655,657],{"class":656},"s2Zo4","cd",[637,659,660],{"class":646}," TRS-Launcher\n",[637,662,664,667],{"class":639,"line":663},3,[637,665,666],{"class":643},"pnpm",[637,668,669],{"class":646}," install\n",[637,671,673,675,678,681],{"class":639,"line":672},4,[637,674,561],{"class":643},[637,676,677],{"class":646}," target",[637,679,680],{"class":646}," add",[637,682,683],{"class":646}," aarch64-apple-ios\n",[637,685,687,690,693,696],{"class":639,"line":686},5,[637,688,689],{"class":643},"brew",[637,691,692],{"class":646}," install",[637,694,695],{"class":646}," ldid",[637,697,698],{"class":646}," cmake\n",[623,700,702],{"id":701},"build-the-frontend","Build the frontend",[628,704,706],{"className":630,"code":705,"language":632,"meta":633,"style":633},"pnpm generate\n",[334,707,708],{"__ignoreMap":633},[637,709,710,712],{"class":639,"line":640},[637,711,666],{"class":643},[637,713,714],{"class":646}," generate\n",[623,716,718],{"id":717},"create-the-xcode-project","Create the Xcode project",[628,720,722],{"className":630,"code":721,"language":632,"meta":633,"style":633},"bash scripts\u002Fios-project.sh\n",[334,723,724],{"__ignoreMap":633},[637,725,726,728],{"class":639,"line":640},[637,727,632],{"class":643},[637,729,730],{"class":646}," scripts\u002Fios-project.sh\n",[278,732,733,734,737,738,740,741,743,744,747],{},"It runs ",[334,735,736],{},"pnpm tauri ios init --ci"," if ",[334,739,399],{}," doesn't exist yet, copies the camera text and the\nbackground task from ",[334,742,455],{}," into the app's ",[334,745,746],{},"Info.plist"," and puts the app icons (plus the event icons\nas alternative icons) into the asset catalog.",[623,749,751],{"id":750},"build-the-app-without-signing","Build the app without signing",[628,753,755],{"className":630,"code":754,"language":632,"meta":633,"style":633},"export IPHONEOS_DEPLOYMENT_TARGET=15.0\nbash scripts\u002Fios-unsigned-ipa.sh release build\u002FTRS-Launcher-app.ipa\n",[334,756,757,775],{"__ignoreMap":633},[637,758,759,763,767,771],{"class":639,"line":640},[637,760,762],{"class":761},"spNyl","export",[637,764,766],{"class":765},"sTEyZ"," IPHONEOS_DEPLOYMENT_TARGET",[637,768,770],{"class":769},"sMK4o","=",[637,772,774],{"class":773},"sbssI","15.0\n",[637,776,777,779,782,785],{"class":639,"line":653},[637,778,632],{"class":643},[637,780,781],{"class":646}," scripts\u002Fios-unsigned-ipa.sh",[637,783,784],{"class":646}," release",[637,786,787],{"class":646}," build\u002FTRS-Launcher-app.ipa\n",[278,789,790],{},"What happens inside:",[792,793,794,815,825,839],"ol",{},[298,795,796,799,800,803,804,806,807,810,811,814],{},[334,797,798],{},"cargo build --lib --target aarch64-apple-ios --release --features tauri\u002Fcustom-protocol"," with\n",[334,801,802],{},"TAURI_CONFIG"," set to the content of ",[334,805,609],{},". The ",[334,808,809],{},"custom-protocol"," feature embeds the interface –\nwithout it the app looks for a dev server on ",[334,812,813],{},"localhost:3000"," and closes again right away.",[298,816,817,818,821,822,284],{},"The library ",[334,819,820],{},"libtrs_launcher_lib.a"," is copied to ",[334,823,824],{},"src-tauri\u002Fgen\u002Fapple\u002FExternals\u002Farm64\u002Frelease\u002Flibapp.a",[298,826,827,830,831,834,835,838],{},[334,828,829],{},"scripts\u002Fios\u002Fdisable-rust-phase.py"," switches off the Xcode build phase \"Build Rust Code\"\n(",[334,832,833],{},"tauri ios xcode-script",") – it only works inside a running ",[334,836,837],{},"tauri ios build",", and the library is already there.",[298,840,841,844,845,848,849,852,853,856],{},[334,842,843],{},"xcodebuild … archive"," with ",[334,846,847],{},"CODE_SIGNING_ALLOWED=NO",", then the ",[334,850,851],{},".app"," is zipped as ",[334,854,855],{},"Payload\u002F"," into the IPA.",[278,858,859,860,863,864,867,868,871,872,875,876,879],{},"Use ",[334,861,862],{},"debug"," instead of ",[334,865,866],{},"release"," for a debug build (the library then goes to ",[334,869,870],{},"Externals\u002Farm64\u002Fdebug\u002F","). For CurseForge,\nset ",[334,873,874],{},"CURSEFORGE_API_KEY"," or put the key into ",[334,877,878],{},"~\u002F.tauri\u002Fcurseforge-api-key"," – it's optional, without it CurseForge is\nhidden.",[623,881,883],{"id":882},"build-the-game-engine","Build the game engine",[628,885,887],{"className":630,"code":886,"language":632,"meta":633,"style":633},"JAVA8_HOME=$(\u002Fusr\u002Flibexec\u002Fjava_home -v 1.8) bash scripts\u002Fios\u002Fbuild-engine.sh build\u002Fengine-ios\n",[334,888,889],{"__ignoreMap":633},[637,890,891,894,897,900,903,906,908,911,914],{"class":639,"line":640},[637,892,893],{"class":765},"JAVA8_HOME",[637,895,896],{"class":769},"=$(",[637,898,899],{"class":643},"\u002Fusr\u002Flibexec\u002Fjava_home",[637,901,902],{"class":646}," -v",[637,904,905],{"class":773}," 1.8",[637,907,548],{"class":769},[637,909,910],{"class":643}," bash",[637,912,913],{"class":646}," scripts\u002Fios\u002Fbuild-engine.sh",[637,915,916],{"class":646}," build\u002Fengine-ios\n",[278,918,919,920,925,926,929,930,353,933,341,936,353,939,349,942,945,946,949],{},"The script fetches ",[282,921,924],{"href":922,"rel":923},"https:\u002F\u002Fgithub.com\u002FAngelAuraMC\u002FAmethyst-iOS",[517],"Amethyst-iOS"," at the pinned commit\n",[334,927,928],{},"9212a1894865e7ac0466029e25ddb0d895544c76",", checks the vendored files against it, builds the native engine and\nMobileGlues with CMake and the Java part with the JDK 8. The result is a folder with ",[334,931,932],{},"Frameworks\u002F",[334,934,935],{},"libs\u002F",[334,937,938],{},"resources\u002F",[334,940,941],{},"LICENSES\u002F",[334,943,944],{},"engine.json",". The Java runtimes are ",[291,947,948],{},"not"," part of it – the app downloads them on the\nfirst game start.",[623,951,953],{"id":952},"put-the-engine-into-the-app","Put the engine into the app",[628,955,957],{"className":630,"code":956,"language":632,"meta":633,"style":633},"bash scripts\u002Fios\u002Fpackage-ipa.sh build\u002FTRS-Launcher-app.ipa build\u002Fengine-ios build\u002FTRS-Launcher.ipa\n",[334,958,959],{"__ignoreMap":633},[637,960,961,963,966,969,972],{"class":639,"line":640},[637,962,632],{"class":643},[637,964,965],{"class":646}," scripts\u002Fios\u002Fpackage-ipa.sh",[637,967,968],{"class":646}," build\u002FTRS-Launcher-app.ipa",[637,970,971],{"class":646}," build\u002Fengine-ios",[637,973,974],{"class":646}," build\u002FTRS-Launcher.ipa\n",[278,976,977,978,980,981,400,984,987,988,284],{},"This copies the engine into the app, adds the Info.plist keys for the Files app, landscape mode, mouse and game\ncontrollers, and signs everything with ",[334,979,437],{}," – the app with the entitlements from\n",[334,982,983],{},"src-tauri\u002Fplugins\u002Ftauri-plugin-trs-game\u002Fios\u002Ftrs-game.entitlements",[334,985,986],{},"get-task-allow"," for JIT, the increased memory\nlimit and extended virtual addressing). Another file can be passed with ",[334,989,990],{},"TRS_IOS_ENTITLEMENTS",[623,992,994],{"id":993},"install-it","Install it",[278,996,997,998,1001,1002,1005,1006,1010],{},"Copy ",[334,999,1000],{},"build\u002FTRS-Launcher.ipa"," to your iPhone or iPad and install it in AltStore or SideStore with ",[291,1003,1004],{},"My Apps → +",". They\nsign it with your Apple ID, like the official app. Other tools that sign an IPA with your Apple ID should work too, but\nwe haven't tested them. Then ",[282,1007,1009],{"href":1008},"\u002Fen\u002Fgetting-started\u002Fiphone-ipad#enable-jit","enable JIT"," to play.",[1012,1013,1014],"note",{},"When AltStore\u002FSideStore re-sign the app with a free Apple ID, the two memory entitlements usually get lost. The app\nchecks at runtime what it really has and picks the Java memory from that – so the game gets less memory than with\nTrollStore.",[363,1016,1018],{"id":1017},"run-it-from-xcode-with-your-own-apple-id","Run it from Xcode with your own Apple ID",[278,1020,1021],{},"You can also start the app straight from Xcode on a connected iPhone and sign it with your own team (a free Apple ID\nworks as \"Personal Team\"). This is handy for working on the interface. Two things to know:",[295,1023,1024,1031],{},[298,1025,1026,1027,1030],{},"The app has ",[291,1028,1029],{},"no game engine"," this way – starting an instance reports that the engine is missing. Sign-in, social,\nwardrobe, modpacks and everything else work.",[298,1032,1033,1034,284],{},"The CI never signs with a team, so ",[291,1035,1036],{},"we haven't tested this path",[619,1038,1039,1043,1050,1077,1084,1088,1107,1114,1118,1137,1141],{"level":621},[623,1040,1042],{"id":1041},"build-the-rust-library-for-debug","Build the Rust library for Debug",[278,1044,1045,1046,1049],{},"Do the steps up to ",[282,1047,718],{"href":1048},"#create-the-xcode-project",", then:",[628,1051,1053],{"className":630,"code":1052,"language":632,"meta":633,"style":633},"export IPHONEOS_DEPLOYMENT_TARGET=15.0\nbash scripts\u002Fios-unsigned-ipa.sh debug build\u002FTRS-Launcher-debug.ipa\n",[334,1054,1055,1065],{"__ignoreMap":633},[637,1056,1057,1059,1061,1063],{"class":639,"line":640},[637,1058,762],{"class":761},[637,1060,766],{"class":765},[637,1062,770],{"class":769},[637,1064,774],{"class":773},[637,1066,1067,1069,1071,1074],{"class":639,"line":653},[637,1068,632],{"class":643},[637,1070,781],{"class":646},[637,1072,1073],{"class":646}," debug",[637,1075,1076],{"class":646}," build\u002FTRS-Launcher-debug.ipa\n",[278,1078,1079,1080,1083],{},"This leaves the library in ",[334,1081,1082],{},"src-tauri\u002Fgen\u002Fapple\u002FExternals\u002Farm64\u002Fdebug\u002Flibapp.a"," and switches off the Rust build phase in\nthe project, so Xcode can build the app on its own.",[623,1085,1087],{"id":1086},"open-the-project","Open the project",[628,1089,1091],{"className":630,"code":1090,"language":632,"meta":633,"style":633},"open src-tauri\u002Fgen\u002Fapple\u002F*.xcodeproj\n",[334,1092,1093],{"__ignoreMap":633},[637,1094,1095,1098,1101,1104],{"class":639,"line":640},[637,1096,1097],{"class":643},"open",[637,1099,1100],{"class":646}," src-tauri\u002Fgen\u002Fapple\u002F",[637,1102,1103],{"class":765},"*",[637,1105,1106],{"class":646},".xcodeproj\n",[278,1108,1109,1110,1113],{},"Choose the scheme that ends in ",[334,1111,1112],{},"_iOS"," and your iPhone as the destination.",[623,1115,1117],{"id":1116},"set-your-team-and-bundle-id","Set your team and bundle ID",[278,1119,1120,1121,1124,1125,1128,1129,1132,1133,1136],{},"In the app target under ",[291,1122,1123],{},"Signing & Capabilities",", pick your ",[291,1126,1127],{},"Team"," and change the ",[291,1130,1131],{},"Bundle Identifier"," to one of\nyour own (for example ",[334,1134,1135],{},"io.github.yourname.trslauncher",") – Apple only lets one team use a bundle ID.",[623,1138,1140],{"id":1139},"run","Run",[278,1142,1143,1144,1146,1147,1150,1151,1154,1155,284],{},"Press ",[291,1145,1140],{},". On iOS 16 and newer, the iPhone asks for ",[291,1148,1149],{},"Developer Mode"," first (",[291,1152,1153],{},"Settings → Privacy & Security →\nDeveloper Mode","). With a free Apple ID you may also have to trust your developer profile under ",[291,1156,1157],{},"Settings → General →\nVPN & Device Management",[1159,1160,1161,1162,1164],"tip",{},"Xcode signing changes live in the generated project. They are gone when you delete ",[334,1163,399],{}," and create it\nagain.",[363,1166,1168],{"id":1167},"make-it-your-own-app","Make it your own app",[295,1170,1171,1177,1199],{},[298,1172,1173,1176],{},[291,1174,1175],{},"Bundle ID:"," AltStore\u002FSideStore sign the IPA with your Apple ID, so you don't have to change anything for that. For\nXcode, change the bundle ID there (see above).",[298,1178,1179,1188,1189,1192,1193,1195,1196,1198],{},[291,1180,1181,1182,606,1185,284],{},"Don't change ",[334,1183,1184],{},"identifier",[334,1186,1187],{},"src-tauri\u002Ftauri.conf.json"," It is shared with Android, where the Kotlin package and\nthe Rust code depend on it – the Android build then stops (see\n",[282,1190,260],{"href":1191},"\u002Fen\u002Fdevelopers\u002Fbuild-android#make-it-your-own-app","). An iOS-only ",[334,1194,1184],{}," in\n",[334,1197,609],{}," might work, but we haven't tested it.",[298,1200,1201,1204,1205,1208,1209,1211],{},[291,1202,1203],{},"Keep the background task ID"," ",[334,1206,1207],{},"dev.theredstonee.trslauncher.push-poll"," as it is: it appears both in\n",[334,1210,455],{}," and in the push plugin's Swift code, and iOS only runs tasks listed in the Info.plist.",[278,1213,1214],{},"What still works in your own build, according to the code:",[295,1216,1217,1223,1229,1239],{},[298,1218,1219,1222],{},[291,1220,1221],{},"Microsoft sign-in"," uses the device-code sign-in (you type a code on Microsoft's page) – it doesn't depend on the\nbundle ID.",[298,1224,1225,1228],{},[291,1226,1227],{},"TRS services"," (friends, chat, capes, TRS API) talk to the same API; there is no check of the app or its signature.",[298,1230,1231,1234,1235,1238],{},[291,1232,1233],{},"Links"," like ",[334,1236,1237],{},"trs-launcher:\u002F\u002Fpack\u002F\u003Ccode>"," use the same scheme in every build.",[298,1240,1241,1244],{},[291,1242,1243],{},"Updates:"," your build isn't connected to our AltStore\u002FSideStore source. Update it by building and installing again.",[278,1246,1247,1248,284],{},"If something breaks in your own build, please ",[282,1249,1250],{"href":224},"report it",[363,1252,1254],{"id":1253},"run-the-checks","Run the checks",[278,1256,1257],{},"The same checks as the CI:",[628,1259,1261],{"className":630,"code":1260,"language":632,"meta":633,"style":633},"pnpm generate\ncd src-tauri\nIPHONEOS_DEPLOYMENT_TARGET=15.0 cargo clippy --workspace --target aarch64-apple-ios -- -D warnings\n# game plugin for iOS, Rust and its Swift package (job \"iOS engine\"):\nIPHONEOS_DEPLOYMENT_TARGET=14.0 cargo build -p tauri-plugin-trs-game --target aarch64-apple-ios\n",[334,1262,1263,1269,1276,1310,1316],{"__ignoreMap":633},[637,1264,1265,1267],{"class":639,"line":640},[637,1266,666],{"class":643},[637,1268,714],{"class":646},[637,1270,1271,1273],{"class":639,"line":653},[637,1272,657],{"class":656},[637,1274,1275],{"class":646}," src-tauri\n",[637,1277,1278,1281,1283,1286,1289,1292,1295,1298,1301,1304,1307],{"class":639,"line":663},[637,1279,1280],{"class":765},"IPHONEOS_DEPLOYMENT_TARGET",[637,1282,770],{"class":769},[637,1284,1285],{"class":646},"15.0",[637,1287,1288],{"class":643}," cargo",[637,1290,1291],{"class":646}," clippy",[637,1293,1294],{"class":646}," --workspace",[637,1296,1297],{"class":646}," --target",[637,1299,1300],{"class":646}," aarch64-apple-ios",[637,1302,1303],{"class":646}," --",[637,1305,1306],{"class":646}," -D",[637,1308,1309],{"class":646}," warnings\n",[637,1311,1312],{"class":639,"line":672},[637,1313,1315],{"class":1314},"sHwdD","# game plugin for iOS, Rust and its Swift package (job \"iOS engine\"):\n",[637,1317,1318,1320,1322,1325,1327,1330,1333,1336,1338],{"class":639,"line":686},[637,1319,1280],{"class":765},[637,1321,770],{"class":769},[637,1323,1324],{"class":646},"14.0",[637,1326,1288],{"class":643},[637,1328,1329],{"class":646}," build",[637,1331,1332],{"class":646}," -p",[637,1334,1335],{"class":646}," tauri-plugin-trs-game",[637,1337,1297],{"class":646},[637,1339,683],{"class":646},[363,1341,1343],{"id":1342},"troubleshooting","Troubleshooting",[623,1345,1347,1348,1350],{"id":1346},"build-phase-tauri-ios-xcode-script-nicht-gefunden","\"Build-Phase ",[334,1349,833],{}," nicht gefunden\"",[278,1352,1353,1355],{},[334,1354,411],{}," switches off that build phase the first time it runs – a second run doesn't find it any\nmore and stops with this message. The CI always starts with a fresh project. Locally, delete the generated project and\ncreate it again:",[628,1357,1359],{"className":630,"code":1358,"language":632,"meta":633,"style":633},"rm -rf src-tauri\u002Fgen\u002Fapple\nbash scripts\u002Fios-project.sh\n",[334,1360,1361,1372],{"__ignoreMap":633},[637,1362,1363,1366,1369],{"class":639,"line":640},[637,1364,1365],{"class":643},"rm",[637,1367,1368],{"class":646}," -rf",[637,1370,1371],{"class":646}," src-tauri\u002Fgen\u002Fapple\n",[637,1373,1374,1376],{"class":639,"line":653},[637,1375,632],{"class":643},[637,1377,730],{"class":646},[623,1379,1381],{"id":1380},"errors-about-the-deployment-target-or-ios-14-apis","Errors about the deployment target or iOS 14 APIs",[278,1383,1384,1385,1387],{},"Set ",[334,1386,613],{}," before building the app (14.0 for the engine plugin check) – the Swift packages\nneed at least iOS 14.",[623,1389,1391],{"id":1390},"the-app-closes-right-after-opening","The app closes right after opening",[278,1393,1394,1395,1398,1399,1401,1402,1404],{},"If you built the Rust library by hand, you probably left out ",[334,1396,1397],{},"--features tauri\u002Fcustom-protocol"," – then the app waits\nfor a dev server on ",[334,1400,813],{},". Use ",[334,1403,411],{},", which always sets it.",[623,1406,1408],{"id":1407},"jdk-8-fehlt-java8_home-setzen-or-java8_home-ist-kein-jdk-8","\"JDK 8 fehlt (JAVA8_HOME setzen)\" or \"JAVA8_HOME ist kein JDK 8\"",[278,1410,1411,1412,1414],{},"The engine's Java part needs exactly a JDK 8. Install one and point ",[334,1413,893],{}," to it.",[623,1416,1418],{"id":1417},"ldid-fehlt-brew-install-ldid","\"ldid fehlt (brew install ldid)\"",[278,1420,1421,1424,1425,1427,1428,284],{},[334,1422,1423],{},"package-ipa.sh"," signs with ",[334,1426,437],{},": ",[334,1429,1430],{},"brew install ldid",[623,1432,1434],{"id":1433},"vendored-datei-weicht-von-upstream-ab","\"vendored Datei weicht von Upstream ab\"",[278,1436,1437,1438,1441,1442,1445],{},"A file under ",[334,1439,1440],{},"ios\u002FEngine\u002Fvendor\u002Famethyst-ios"," differs from the pinned Amethyst-iOS commit. Only the patched files\nlisted in that folder's ",[334,1443,1444],{},"UPSTREAM.md"," may differ – undo your change or update the list.",[623,1447,1449],{"id":1448},"the-game-closes-right-after-starting","The game closes right after starting",[278,1451,1452,1453,1456,1457,1460,1461,400,1464,1467],{},"Almost always ",[291,1454,1455],{},"JIT is not on",". See ",[282,1458,1459],{"href":1008},"Enable JIT",". The engine log is in\nthe Files app under ",[291,1462,1463],{},"On My iPhone → TRS Launcher",[334,1465,1466],{},"trs-engine.log",").",[623,1469,1471],{"id":1470},"minecraft-263-doesnt-start","Minecraft 26.3 doesn't start",[278,1473,1474],{},"26.3 is not supported on iOS yet (the engine has no SDL3 support there). Use 26.2 or older.",[623,1476,1478],{"id":1477},"unable-to-verify-app-after-a-week","\"Unable to verify app\" after a week",[278,1480,1481],{},"The 7 days of the free Apple ID are over. Refresh the app in AltStore\u002FSideStore, or run it from Xcode again.",[363,1483,1485],{"id":1484},"license-and-name","License and name",[278,1487,1488,1489,400,1492,1495,1496,1499,1500,1503,1504,1507,1508,1510],{},"TRS Launcher is free software under the ",[291,1490,1491],{},"GNU General Public License v3.0",[334,1493,1494],{},"LICENSE",", copyright notices in ",[334,1497,1498],{},"NOTICE",").\nYou may build, change and share the app. If you share an IPA, the GPL requires that you share it under the same license\nand make the ",[291,1501,1502],{},"complete source code"," of exactly that build available, including your changes. The iOS engine is based\non Amethyst-iOS (GPL-3.0) and ships more third-party parts; their license texts are copied into the app\n(",[334,1505,1506],{},"licenses\u002Fengine",") and listed in ",[334,1509,1498],{}," – keep them.",[278,1512,1513],{},"The repository has no separate trademark rules. Still: if you hand out your own build, give it its own name and bundle\nID so nobody mistakes it for the official TRS Launcher, and point people to your source code – not to our support.",[363,1515,1517],{"id":1516},"next-steps","Next steps",[1519,1520,1521,1525],"card-group",{},[1522,1523,1524],"card",{"icon":32,"title":260,"to":261},"The APK with your own signing key – works on Windows and Linux.",[1522,1526,1528],{"icon":37,"title":1527,"to":35},"iPhone & iPad","Install the official app with AltStore or SideStore.",[1530,1531,1532],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":633,"searchDepth":653,"depth":653,"links":1534},[1535,1536,1537,1546,1552,1553,1554,1566,1567],{"id":365,"depth":653,"text":366},{"id":474,"depth":653,"text":475},{"id":617,"depth":653,"text":314,"children":1538},[1539,1540,1541,1542,1543,1544,1545],{"id":625,"depth":663,"text":626},{"id":701,"depth":663,"text":702},{"id":717,"depth":663,"text":718},{"id":750,"depth":663,"text":751},{"id":882,"depth":663,"text":883},{"id":952,"depth":663,"text":953},{"id":993,"depth":663,"text":994},{"id":1017,"depth":653,"text":1018,"children":1547},[1548,1549,1550,1551],{"id":1041,"depth":663,"text":1042},{"id":1086,"depth":663,"text":1087},{"id":1116,"depth":663,"text":1117},{"id":1139,"depth":663,"text":1140},{"id":1167,"depth":653,"text":1168},{"id":1253,"depth":653,"text":1254},{"id":1342,"depth":653,"text":1343,"children":1555},[1556,1558,1559,1560,1561,1562,1563,1564,1565],{"id":1346,"depth":663,"text":1557},"\"Build-Phase tauri ios xcode-script nicht gefunden\"",{"id":1380,"depth":663,"text":1381},{"id":1390,"depth":663,"text":1391},{"id":1407,"depth":663,"text":1408},{"id":1417,"depth":663,"text":1418},{"id":1433,"depth":663,"text":1434},{"id":1448,"depth":663,"text":1449},{"id":1470,"depth":663,"text":1471},{"id":1477,"depth":663,"text":1478},{"id":1484,"depth":653,"text":1485},{"id":1516,"depth":653,"text":1517},"Build the TRS Launcher IPA for iPhone and iPad on a Mac: Xcode project, Rust library, game engine, sideloading and running it with your own Apple ID.","md",null,{},{"icon":37},{"title":264,"description":1568},"BEByme5m7MHn4TGgD7y8zSlqWFwBDkSa84CoQQv-Xvs",[1576,1578],{"title":260,"path":261,"stem":262,"description":1577,"icon":32,"children":-1},"Build the TRS Launcher APK from source: Android SDK and NDK, Rust targets, debug and release builds, your own signing key and your own app ID.",{"title":268,"path":269,"stem":270,"description":1579,"icon":271,"children":-1},"Plugin and server mod that locks, forces or limits TRS Client features on your server: platforms, config reference, protocol and all module IDs.",1792830334764]