Cheat Codes

I loved finding cheat codes for games as a kid (19C, 65C, 9C, 17C, A+Start anyone?). While we call them cheat codes, they are more aptly-called debug codes; a quick way for the game developers to jump between levels or get unlimited lives to test things. They just got left in the game after shipping.

Recently, I've been baking more and more cheat codes into Slopes through an oft-overlooked (or, at least, not often talked about) method: URL schemes.

The Slopes Debug Menu

I've shipped bugs, and I know I always will despite my best efforts. So a year or so ago I took a few hours to build in a debug mode; a screen I could trigger for users given a specific slopes:// URL call. In it, I baked in a ton of tools to help me out during customer support. I just say "hey, tap this link" and Slopes opens right into this screen.

Simple things that not only helped me but, sped up the support process users. For example: getting into the documents directory of the Slopes sandbox is an annoying process if the user has to go through iTunes File Sharing. So why not bake in an option to automatically zip up the subfolder I need from it and email it to me? All without needing to touch their computer.

Or, as of late, another one I've found helpful in a crunch is the ability to email the current iOS receipt to me. Receipts automatically sync with the Slopes server, but I had a very rare case (like 3 customers out of thousands) where an interruption to the IAP flow made things go wonky. I was able to manually sync things back up on my end in no time with this.

One note: I never ship anything here that I wouldn't want someone out in the real world to accidentally find. Most of these tools are harmless; I have a bunch of tools in-app that are #ifdef DEBUG'd out, ones that wouldn't be appropriate for a real-world user to ever find.

More than Secret Screens

What started as just a trick to get a debug menu in place has expanded to provide more helpful tricks in Slopes. Another case in point: press demos.

Demoing Slopes to the press when I'm not with the person can be hard. Not everyone skis, or is within driving distance of a mountain to try the app out. I ship with a sample day's worth of data for regular users to play with before they get the chance to record (always plan to delight users, even in an empty state), but I think that's not enough.

For the press I want to go a few steps further.

I need to make it easy for them to try out the Slopes Pass IAP features. Of course I have a press account in Slopes for this, but I can't keep those details on a public press kit page. I always have to privately email them the login details.

I also want to stop treating the sample day like a sample. I want to present it in-app as if they had recorded it.

Lastly, I want to give them simulated GPS. If they hit start from the comfort of their desk, I want Slopes to start "recording" a day (at ~5x the speed) as if they were on the mountain (something I've long had the ability to do in Slopes for debug purposes).

It wouldn't be the end of the world if a user stumbled upon these features, but there is no way I want some big "press mode" button on the about screen of Slopes. So a custom slopes:// URL is the perfect candidate.

With a custom URL, this is all very easily possible. Once I detect the URL, as of v2.5 I now:

  • Log them in as the press (which auto logs out after quitting)
  • Copy the sample day into "their" database of activities
  • Switch the GPS recorder to simulated mode (which deactivates when the app gets terminated in the background by iOS later)

This changes a multi-step conversation with a member of the press to "download the app, then hit the URL slopes://super-secret-url".

I have one or two more possible abuse cases I want to think through, and then I'll be able to publicly list this URL on my press kit page, letting anyone in the press demo the app without having to contact me. And the less the press has to find a way to email me for a press demo, the better (in their eyes).

(Aside: After building the press feature I do debate turning my debug menu into multiple distinct URL calls, like slopes://email-receipt, and getting rid of the screen).

DIY Cheat Codes

Implementing this in your own app is quite simple.

First, add a new URL type in your target's Info section (one left of Build Settings), with the role of viewer. In my case I chose slopes as the scheme, making my URLs slopes://.

Second, set up your app delegate to recognize URL calls for your app. You can do so in application:openURL:sourceApplication:annotation. Inspect the URL to see if it matches your desired callback (like slopes://logout or whatever you're setting up, the part after the //).

(I use the excellent JLRoutes Pod to handle my in-app routing, so the below is just a quick idea of what you might do.)

And boom, you're done. From there you can do whatever you want in-app to respond to the callback; go into press mode, show a debug screen, trigger an email with an attachment, whatever.

P.S. What was your favorite cheat code? Besides the Contra one.