Last time we built the desktop client, in 2015, NW.js was called node-webkit. Since then: - NW.js has added NaCl and some other things, ballooning the installer from 30 MB to 120 MB. (The NaCl stuff on Windows seems to be deletable, helping keep its installed size slightly smaller.) (If anyone wants to make a custom build without NaCl, that'd help me a lot) - NW.js also has a lot more files, and NSIS makes adding/removing files annoying enough that I wrote a script to automate it for me. - Apple has made Gatekeeper requirements a lot stricter, requiring setting up entitlements, Hardened Runtime, notarization, and stapling, (in addition to just signing in 2015). I documented the process because there are zero online guides for it right now. But on the other hand, this update hopefully fixes the crashes that the old desktop client has. It also fixes: - the Chrome bold emoji bug is gone - MP3 is no longer under patent, allowing us to have only MP3 files for everything - honestly I don't think we use any other Chrome feature added in the last four years
5.7 KiB
Desktop apps
Pokémon Showdown for desktop is made with NW.js.
There's an .ico icon (for Windows) and an .icns icon (for Mac) in the graphics-src directory of this repository. We use these pretty much whenever we need icons.
Note that NW.js doesn't support normal window icons in Windows, so we have to use a PNG icon to get scaling not to look horribly ugly.
Packaging
NW.js's docs contains packaging instructions, but they're strewn across their wiki and don't really go into best practices, so I have better packaging instructions here.
For performance, we don't zip up the package on either platform. In Windows, the index.html and package.json files are dropped directly into the install directory, and in OS X the files are dropped into Resources/app.nw.
Packaging for Windows
-
Put a copy of node-webkit (build or extract the prebuilt binary) into this folder.
-
Rename
nw.exetopokemonshowdown.exe -
Edit
pokemonshowdown.exewith Resource Hacker, and replace the node-webkit icon withicons/pokemonshowdown.ico -
You may need to update
pokemonshowdown.nsiif the file layout has changed; refer tomake-nsis-script.js -
Using NSIS, build
pokemonshowdown.nsi
Packaging for OS X
NOTE: By default, Mac apps will refuse to run, displaying a Gatekeeper warning. Removing the Gatekeeper warning requires an Apple Developer account (costs $99/year) and an annoying notarization process (step 8 to 18).
-
Get a copy of node-webkit (build or extract the prebuilt binary)
-
Rename it to
Pokemon Showdown.app -
Update
Pokemon Showdown.app/Contents/Info.plist, changing:CFBundleIdentifiertocom.pokemonshowdown.pokemonshowdownCFBundleNametoPokemon ShowdownCFBundleDisplayNametoPokemon ShowdownCFBundleShortVersionStringto the current version, e.g.0.11CFBundleVersionto the some sort of version code, I just used the git commit hash- empty the arrays of
CFBundleDocumentTypes,CFBundleURLTypes,NSUserActivityTypes, andUTExportedTypeDeclarationsso they look like<array></array>- (these register the app as able to open these files/URLs, which we definitely do not want to do)
-
Update
Pokemon Showdown.app/Contents/Resources/en.lproj/InfoPlist.strings, changing:CFBundleNameto"Pokemon Showdown"CFBundleDisplayNameto"Pokemon Showdown"CFBundleGetInfoStringto something like"Pokemon Showdown 0.11, Copyright 2011-2020 Guangcong Luo and contributors."NSHumanReadableCopyrightto something like"Copyright 2011-2020 Guangcong Luo and contributors."
-
Delete all the other
*.lprojfolders (other thanen.lproj) inPokemon Showdown.app/Contents/Resources- (our app is named "Pokemon Showdown" in all languages, we definitely don't want it to be called "nwjs" in other languages)
-
Replace
Pokemon Showdown.app/Contents/Resources/app.icnsandPokemon Showdown.app/Contents/Resources/document.icnswith the icns file ingraphics-src. -
Create a folder
Pokemon Showdown.app/Contents/Resources/app.nwand putindex.htmlandpackage.jsonin it. -
Grab a developer ID certificate (this requires an Apple Developer account costing $99)
- https://developer.apple.com/account/mac/certificate/certificateList.action
- type should be "Developer ID Application"
- Install the cert in Keychain and remember its "identity" (the part in parentheses)
- just drag and drop the cert file into Keychain Access
- Sign the app, set up entitlements, and set it to use Hardened Runtime
- Edit
sign-mac-app, settingAPPto the location of your app, andIDENTITYto the identity from step 9 - Run
sign-mac-app
- Verify the signature
codesign --verify -vvvv "Pokemon Showdown.app"
- Zip up the app into
Pokemon Showdown.zip
- right-click, Compress, rename to remove the
.apppart
- Notarize the app, noting the
RequestUUID
[USERNAME]is your Apple Developer account username (should be an email address)[PASSWORD]is an app-specific password for your Apple Developer account- get an app-specific password here: https://support.apple.com/en-us/HT204397
xcrun altool --notarize-app --primary-bundle-id "com.pokemonshowdown.pokemonshowdown" --username "[USERNAME]" --password "[PASSWORD]" --file "Pokemon Showdown.zip"- this will show a
RequestUUID, which you'll need
-
Wait for the app to notarize (this takes around 10 minutes in my experience)
-
Check the notarization
[RequestUUID]is the UUID from abovexcrun altool --notarization-info [RequestUUID] -u "[USERNAME]"- it will ask for a password; use the same password as in step 12
- the Status line will say either
in progress,Package Approved, orPackage Invalidin progress- try again in ten minutesPackage Invalid- error messages will be in theLogFileURLlinkPackage Approved- this is what we're hoping for
- Staple the notarization
xcrun stapler staple "Pokemon Showdown.app"
- Validate the notarization
spctl -a -vvvv "Pokemon Showdown.app"
- Delete the un-stapled zip, and create a new zip
Apple's own documentation on the command-line notarization process might be useful:
But it doesn't cover how to set up an existing app for Hardened Runtime (I only figured it out from a random GitHub issue after an hour of Googling).