Continuing on from last post, let's talk about the design principles for giving The Task to the user
Once the user is presented with the narrative that explains what the task is. It's up to the user to complete the task.
We already know from our core principles that the act of completing the task must only involve a git client, GitHub, and a text editor. So logically this means our game service must prepare a repo with the right state for the player to do the task on. This means that both the game service, and the player, must at some point have access to the same repo. Thinking about the different mechanisms possible to do this, we have a few options: have the user fork a repository; have the user create a repository and share it with us; have the game service create a repository and share it with the user.
Forking the repository is the easiest way. The player just needs to click the "fork" icon in the top right corner of one of LGTM's repos. This creates a copy/fork of the repo in the player's account, it's very fast and low-friction.
There are some pros and cons to this:
- Very easy for the player
- Our game backend can get notified by GitHub when this happens through hooks, so we know who forked our repo, and we can start the game for them
- Our game backend can submit issue tickets to this forked repo
- It's easy to keep track of who's playing our game, because we can see and list all the forks!
- When the player does this, the repo must be public
- Our game backend still doesn't have write access to the repo, so cannot make commits to the repo directly, and would have to do it through Pull Requests, which the player would need to accept
I like the ease of which this can happen. But I don't like that the game has to set up the task by Pull Request. Particularly because early on, the player might not yet be familiar with how to handle Pull Requests, I don't want to have them deal with that from the first task.
If the User were to create a repo, and share it with our service, that would solve the account access requirements, but this is much more complex for the user. Deploy keys may be involved, which we'd have to dispense to the player (maybe through a login on our website?)
- Repo is now private, so the player doesn't have to share their game progress with anyone else
- Our game backend can now get full access to the repo and set things up for each Task
- Complex for the player
I don't like the complexity of this option. Having to set up this much stuff just to get into the game will surely turn a lot of people off.
We can create a repo and share it with a player. This is much easier for the user than them creating it, but there are other considerations:
- Repo is now private
- Our game backend can now get full access
- Simpler for the player
- Our account will need to contain one repo per player
The only downside to this option is that our game backend will need a separate repo per user, in order for us to share it. If we have 1000 players, then we will need 1000 repos. From a code point of view, this isn't a problem, but would we hit some kind of account limit?
This option is very slightly less straightforward for a player, because they would need to locate the invite email sent to them, as well as know their way around the GitHub interface a little more than they would doing a fork.
It's clear that asking the user to set up a repo and share with us to play the game is off the table. It's too complex.
Of the two remaining options, inviting the player to our repo may be the only reasonable option, as we need access to the repo in order to set it up. While there's a chance we hit some kind of account limit, that would be a good day when it happens, so I'd rather face that problem.
What's interesting is these options are not necessarily mutually exclusive! We're in the business of teaching the player git and GitHub, so options that were considered too complex to the player can become viable later on, simply by playing! This means we retain the option of having a user share a repo with us in later game stages.
In addition, we could use all three - allow the user to fork the repo to start the game, since this is the simplest option for them. Start with tasks where we don't need to write data to the repo (it could come with enough commits early on to do a few early tasks). Then, once the user is more familiar with things, send the invite for their repo, or ask them to create one and share with us!
So I'm going to start with git tasks that can be done with the user forking the repo, and add on more complex tasks later. This does restrict what kind of interaction we can begin with, but we can leave the rest for a version 2