With the launch of macOS Catalina (10.15), Apple introduced a requirement to "notarize" (US English) all macOS software which has been built and codesigned after the end of July 2019. For more information on this announcement, please see this Apple Developer page: Notarizing Your App Before Distribution.
In order to comply with this, you will need to have Xcode 10 or above installed, plus be using macOS Mojave or newer when making your games. You will also need a paid Apple Developer account if you want to give your app to anyone else as only dev-testing on your own machine is free these days.
There is nothing that YoYo Games or GMS2 can do to help you get around these requirements. We have to do it with our own software, including GMS2 itself (every single build, not just the public releases).
If you do not codesign your package, Gatekeeper will say it's damaged and tell you to delete it (on Mojave and above), so not applying codesigning is not a realistic method of bypassing notarisation.
Will This Affect Me?
This will affect you if you want to send your apps to any other Mac than the one on which your own developer details are installed, including:
- Making a game .pkg to send to anyone who is using Catalina or a newer version of macOS (possibly Mojave also - see below)
- Selling on the App Store (Xcode will deal with it all automatically for you)
- Selling on Steam
- Selling on Itch.io
- Selling on wherever else you currently distribute your macOS games...
Note that because Steam also requires you to submit your test builds each time nowadays, that means each build you do will need to be notarised and then sent to them, so you may want to disable Steam integration during testing as much as possible.
It will also affect students submitting games for grading if either the student or the person doing the grading is using Catalina or newer - we would suggest whenever possible it's a .yyz Export which is sent for grading, as the project can then be opened and built on the local machine, rather than the student building the package and sending the executable. You would then avoid having to do any of the steps in this article.
Mojave also supports this "hardened runtimes" protection, but it was an optional setting you could toggle during a reformat (and the default was off). In Catalina and newer, there is no facility to turn this protection off and everyone will be affected.
What Do I Need To Do When Building My Game?
You need to be using GMS2 2.2.4 or newer when you build the package and you do need to have Xcode installed as per our Required SDKs guide, but beyond that you don't need to do anything differently within GMS2, as the notarisation process is handled by Apple's own tools once your package has been made.
Please note that we recommend you always build your final packages using YYC, as Xcode makes it much simpler, faster, and easier to diagnose compatibility issues - and Xcode's uploading UI can then be used, which will do a lot of the work for you.
However, the process you will need to follow in order to notarise your package once it has been built differs between VM and YYC and whether your game is for the App Store or not, so see the relevant section below for more info.
Be aware that hardened runtimes support requires even more stringent development standards, especially if you are using .dylib extensions, but the exact changes you need to make to your project are not something we can document, as it depends on the contents of that specific project. In general, be aware that you may need to do some additional work before a hardened runtime project build will succeed inside Xcode.
Additional Considerations For If Your Project Contains Extensions
The new rules around "hardened runtimes" means any dylib extensions (which until August 2019 you may not have been codesigning yourself) will now need to be codesigned by you before them adding to your GMS2 project or manually on the Mac within Xcode after you click Create Exe inside GMS2. Any existing codesigning by a third-party will need to be overwritten, as all codesigning must be with your certificate.
Also be aware that your extensions now need to be 64-bit only, otherwise macOS will refuse to run them.
What if I get server issues when trying to notarise?
https://developer.apple.com/system-status/ is the page which tells you if the notarisation service itself has issues at Apple's end. If you find yourself getting errors that servers/values can't be found, check here to see if you should try again later.
Unfortunately, this isn't something YoYo Games can help you fix.
Submitting Via Xcode
See this Apple tech post for more details on the process.
macOS YYC building for the App Store:
- "Create Exe" inside GMS2. This will build your Xcode project and archive as per usual.
- Open Xcode > Window > Organizer > Archives and select your game from the panel down the left. Click on the archive you wish to send, and then click the Distribute App button in the panel on the right.
- Follow the wizard for submitting to the App Store.
- This will perform the notarisation and stapling automatically as part of the upload and initial submission process.
macOS YYC building for any other form of distribution:
- "Create Exe" inside GMS2. This will build your Xcode project and archive as per usual.
- In Xcode go to Signing & Capabilities and then select the +Capabilities section. From the window that opens, double click on the Hardened Runtime option. (Recent versions of GMS2, this may be ticked already.)
- You now need to create a new archive with this option enabled by going to Product > Archive. Fix any issues Xcode asks you to resolve before it will complete the build.
- Open Xcode > Window > Organizer > Archives and select your game from the panel down the left. Click on the archive you wish to send (the newest one), and then click the Distribute App button in the panel on the right.
- Click the "Developer ID" option ("Distribute direct to customers"), then click Next.
- Click the "Upload" option, then click Next.
- This will send the package off to Apple so they can scan it and confirm all is okay.
- You can continue testing locally during this time, but you can't send the package to anyone else yet.
- At some point later (Apple advise "typically less than an hour"), Xcode will be told your notarisation is okay and will download the "ticket". Xcode will perform the stapling of this ticket to the app for you.
- You can now repeat steps 2 and 3, and then this time choose "Export". Xcode will now make you a package which is safe to use on other Macs.
Submitting Via Command Line Tools
See this Apple tech post for more details on the process.
Please note that we would recommend you do not actually use either of these two routes, and instead you always build your final packages using YYC, as that will be much simpler, faster, and easier to diagnose issues. These following sections are provided for completeness / for if you have a custom build workflow that you really want to keep using VM with.
We can't really offer support if you have issues when following these routes, as we would need your project to be sent to us, etc. We will just recommend you test your project and your extensions are suitably codesigned and hardened-runtime-compatible by building your project for YYC...
macOS VM building for the App Store:
- Create Exe inside GMS2. This will build your .app as per usual (ignore the .app.zip)
- Send the .app to Apple via Application Loader in the normal way.
- This will perform the notarisation and stapling automatically as part of the upload and initial submission process.
macOS VM building for any other form of distribution:
You need to use Textedit or similar to make a shell script which looks something like the following (obviously adding your own Apple "id" and "password" values at the top, as shown):
#!/bin/bash
set +x
app_store_id=[ADD YOUR APPLE UPLOADER ACCOUNT DETAILS HERE] app_store_password=[ADD YOUR APPLE UPLOADER ACCOUNT DETAILS HERE] filename=[ADD THE FULL FILEPATH TO YOUR .ZIP HERE] notarize_uuid=$(xcrun altool --notarize-app --primary-bundle-id "$(uuidgen)" --username "${app_store_id}" --password "${app_store_password}" --file ${filename} 2>&1 |grep RequestUUID | awk '{print $3'})
echo "notarize_uuid == ${notarize_uuid}"
sleep 50
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do echo "Checking progress... Attempt ${i}"
progress=$(xcrun altool --notarization-info "${notarize_uuid}" -u "${app_store_id}" -p "${app_store_password}" 2>&1 ) echo "progress == ${progress}"
if [ $? -ne 0 ] || [[ "${progress}" =~ "Invalid" ]] ; then echo "Error with notarization. Exiting!" error=1 fi
if [[ "${progress}" =~ "success" ]]; then echo "Notarization succeeded. Stapling!" xcrun stapler staple ${filename} break fi
echo "Not completed yet. Sleeping for 30 seconds" sleep 30
done
This needs to be saved as a .sh file and given the file-permission to be executable. You would then run the script by calling it in Terminal. Please note, as the first line of the script says, your shell needs to be set to bash (not zsh or whichever other shell you might be using), otherwise you will have to modify the script to fit your shell's needs.
Then, for each game package you wish to distribute:
- Create Exe inside GMS2. This will build your .app.zip as per usual (Apple won't accept the .app without it being in a .zip).
- Replace "[ADD THE FULL FILEPATH TO YOUR .ZIP HERE]" in the script with the full path and filename for your .app.zip file.
- Run the script and wait. Watch its progress in your Terminal window.
- When it says "Notarization succeeded. Stapling!", you will then see the stapler tool is launched in your Terminal. This will tell you if it succeeded in stapling the ticket to the .app or not.
- Assuming the stapling succeeded, then you can now send the .app to your customers (up to you if you leave it in the .zip or not when sending it).
As mentioned a little way up this guide, if you have dylib extensions inside the project, then you will need to modify our script there to codesign each of your dylibs in turn before doing the notarization. Add this as new lines between our "filename" and "notarize_uuid" lines.
Be aware that if you intend to add your .app into your own custom format installer, then you will need to complete the notarisation process twice - first for the .app payload itself and then a second time for your own installer executable once the notarised .app is inside it. We don't support this, but largely you would just repeat the steps above as required. This does not apply to standard Apple format installer packages, such as .pkg or .dmg, which the notarisation service knows about - for those, you skip notarising the .app on its own and instead just notarise the whole thing as you would send it to a customer.