Ubuntu Accomplishments Spec
One of the core reasons why people participate in Open Source projects is so they can create something that helps the project and showcase their contributions to that project. While we provide plenty of opportunities for people to contribute, we don’t provide a good way of contributors articulating their contributions well.
About the best method of doing this today is Launchpad Karma, but this (a) does not cover many different types of contributions (namely, those outside Launchpad), (b) has been criticized over how the scoring is performed, and (c) is uninteresting to visualize -- it is just a set of numbers.
This spec is inspired by accomplishments systems used in other systems such as the Sony Playstation 3 trophies, StackExchange Badges, and FitBit Badges. The goal here is to create an accomplishments system that is extensible enough to be used by by local applications on a computer and contributions made to the Ubuntu community. In performing this work, these are some core goals:
Extensible - this system should be flexible enough that accomplishments at a desktop level (e.g. “Sent Email From Thunderbird” or “Sent First Tweet In Gwibber”) can be achieved, as well as project contributions (e.g. “Filed First Bug”).
Discoverable - the user should be able to see what trophies are available and find out how to achieve them.
Highly Distributed - the solution should be as de-centralized as possible so as to reduce the need for an extensive central service.
Integrated - the solution should be tightly integrated into Ubuntu itself and not just a series of disconnected web-pages.
Throughout the rest of this document we will use the following terms:
Accomplishment - a goal or objective that can be achieved.
Trophy - a representation of an achieved accomplishment.
Validation Server - a component in the workflow that ensures that trophies are legitimately earned.
The workflow presented here was developed between Stuart Langridge and Jono Bacon and achieves each of the core goals highlighted above. The solution is highly distributed, uses Ubuntu One as a data sharing mechanism, and would be integrated into the Unity experience.
With this proposed system there are two core types of accomplishments:
Local Accomplishments - accomplishments that are local to your specific computer and do not require verification elsewhere (e.g. completing a level in a game).
Global Accomplishments - accomplishments that require verification from a third party (e.g. filing your first bug in Ubuntu).
All accomplishments are representing using the same kind of format and schema, but local and global accomplishments differ in how they generate trophies.
Accomplishments are defined by an application by storing a .accomplishment file in the system folder /usr/share/accomplishments/accomplishments/app-name.
Trophies, which are a record that a specific user has accomplished a particular accomplishment, are stored in a user-specific folder $XDG_DATA_HOME/accomplishments (this is likely to be $HOME/.local/share/accomplishments on most Ubuntu installations).
Local Trophies - $XDG_DATA_HOME/accomplishments/local/app-name/accomplishment-name.trophy
Global Trophies - $XDG_DATA_HOME/accomplishments/global/app-name/accomplishment-name.trophy
For local accomplishments (e.g. completing a level on a game on your system), the following files are involved:
.accomplishment - this file outlines some cosmetic details about the accomplishment such as the name (e.g. ‘Level 2 Completed’), an icon (e.g. ‘level2.png’) and what other accomplishments should be completed before this one can be unlocked (e.g. ‘mygame/level1complete’).
.trophy - this file is the generated trophy that represents the completed accomplishment. libaccomplishments-daemon generates it.
Here the .accomplishment file describes the accomplishment and when that accomplishment occurs (e.g. in a game you complete Level 2) the app would call the accomplishments system to process the .accomplishment file and generate the .trophy. This trophy would be added to the Ubuntu One Share for the local trophies.
For Global Accomplishments we need to poll external services to check if an accomplishment has been achieved (e.g. Filing Your First Bug in Launchpad). To perform this polling we need the following:
A logic file (for global accomplishments) - a file that contains the logic for determining if an accomplishment has been achieved (e.g. for a ‘1st Bug Filed’ accomplishment this file could be a small Python script that connects to Launchpad to see if you have filed a bug yet).
A server logic file (for global accomplishments) - a server-side file that verifies that the accomplishment has genuinely been completed.
A key needs-signing - true in the .accomplishment file
The logic file is a script named similarly to the accomplishment and stored in /usr/share/accomplishments/scripts. So if an app installs a global accomplishment /usr/share/accomplishments/accomplishments/ubuntu-community/first-bug.accomplishment, there should be a corresponding script /usr/share/accomplishments/scripts/ubuntu-community/first-bug.py where the extension of the script can be anything. (The identifying part is ubuntu-community/first-bug.)
At regular intervals, the libaccomplishments system will look to see, for each user on the system, which global accomplishments they have not yet accomplished. For each accomplishment, the system then runs the corresponding logic script. A logic script is expected to exit with a specific exit code: 0 for “the accomplishment is now accomplished”, 1 for “the accomplishment is not yet accomplished”, and 2 for “there was an error”. (FIXME: what should we do if there’s an error? How do we notify the user?) If the logic script indicates that the accomplishment was successfully accomplished, the system creates the appropriate .trophy file. However, because this is a global accomplishment, it needs to be validated by a separate service to ensure the user isn’t faking it. As such, this separate hosted service would have the server-side logic file for each respective accomplishment available to users.
These are the tools that will process these files and provide the functionality:
libaccomplishments-daemon - the server which provides the base-level D-Bus API to query and award accomplishments, and also notifies the user with notify-osd when an accomplishment is accomplished. The daemon should be started by D-Bus activation on the session bus if it is not already started
libaccomplishments - a small library that is called by a local application (e.g. a game) that wants to generate a trophy for a completed accomplishment; a wrapper around the libaccomplishments-daemon D-Bus API
libaccomplishments-daemon-scriptrunner - a small root-level script that runs all the available accomplishment logic files once a day and generates trophies to be sent to the validation server
accom-validate - a tool on the validation server that processes new trophy requests and signs valid trophies.
Local Accomplishment Workflow
Here is how the workflow would work for an application that is local on the computer (e.g. completing a level in a game). Note that in this case that the trophy is never sent to a validation server, this all happens locally and the logic that determines that an accomplishment has been achieved is conducted inside the application.
Global Accomplishment Workflow
There are two types of global accomplishments:
Machine Verifiable - these are accomplishments that involve third party services (e.g. Launchpad) that we can automate in verifying if they were successfully accomplished (e.g. filing your first bug or your 1000th bug comment).
Human Issued - these are accomplishments that cannot be auto-generated or verified but require human intervention or nomination (e.g. awards for great work in LoCo teams).
Here is the workflow for machine verifiable accomplishments. In this no user interaction is required, and here is an example applied to an accomplishment for fixing a first bug.
Note that we still need to define our accomplishments (.accom/.logic/.logic-valid files) and ensure they are installed on the local system. These would be present in a package that makes available all possible accomplishments.
Human Issued Workflow
This workflow applies to accomplishments that are issued by someone who is trusted in the project. Examples of this could include governors (e.g. Community Council, Technical Board) or trusted members of the project (e.g. leaders of approved LoCo Teams).
This workflow requires one additional component: a web site that acts as a means for someone to assign the trophy to a user.
This website would like this this:
This is the workflow of how the trophy is generated:
When a new human issued trophy is created it should have the date attached to it (to allow multiple trophies to be issued). As an example if Joe. S. CoreDeveloper gives out a Kudos Trophy to Colin Watson on the 2nd September 2011 it will generate a trophy called Joe S. CoreDeveloper Kudos - 2nd September 2011 and this will appear in Daniel Holbach’s trophy cabinet. The comments field is required so that we can provide contextual information if required in visualizing the trophy (e.g. hovering over a trophy and showing the comment in a toolip)
Operating System Integration
Focusing specifically on how we deliver Ubuntu Community orientated accomplishments, the functionality would broken out across the following packages:
ubuntu-accomplishments - this package would contain the applications required to operate the Ubuntu Accomplishments system. Namely, libaccomplishments, libaccomplishments-daemon, libaccomplishments-daemon-scriptrunner and accom-validate.
ubuntu-accomplishments-community - this package contains a full set of accomplishments for participating in the Ubuntu community.
ubuntu-accomplishments-community-valid (ONLY FOR THE VALIDATION SERVER) - this is the companion package to ubuntu-accommplishments-community that contains a similar set of scripts that can validate accomplishments.
ubuntu-accomplishments-community-valid-human (ONLY FOR THE VALIDATION SERVER) - this package contains a set of human accomplishments for the Ubuntu community.
The visualization part of this vision is a key piece in making it successful. There are some implicit goals here:
Trophies should feel real - we don’t want trophies to feel like pictures on a website; they need to feel like real accomplishments that are part of your Ubuntu experience.
New trophies should be discoverable - trophies that you have not achieved yet should be (a) available to see so you can see what future trophies you could achieve and (b) inform the user of how to achieve those trophies.
You should be able to ‘unlock’ new trophies - some trophies don’t make sense unless you achieve something else first (e.g. ‘Fixed 5 Bugs’ should not be available until you have achieved ‘Fixed First Bug’). By unlocking trophies when others are completed, this will continue to grow the opportunity for new challenges throughout the system.
The designs here are preliminary designs that have not yet had Design Team input. As such, we would want to consult the design team to get their perspective on how this should.
These designs show an Accomplishments Lens that would be part of the Unity dash and which also hands out control to a helper app called the Ubuntu Trophy Cabinet.
The lens would look like this:
Here you can see the list of already accomplished trophies (these would have unique trophy icons for each one, the stars here are just because Balsamiq does not have a trophy icon ).
You can see here the available trophies that have not yet been accomplished. If you click on a trophy the Ubuntu Trophy Cabinet helper app is loaded.
When the user clicks on a trophy there are two outcomes (1) the user has not yet registered in the accomplishments system or (2) they have already registered.
If they have not registered they see the getting started screen:
This screen explains the accomplishments system and allows the user to register to participate. This involves the following steps:
- This step creates an Ubuntu share and registers it with the validation server.
- This step asks the user to create a Launchpad account or authenticate. The user will need to use the same email to register in LP as in Ubuntu One. This needs to be documented. (FAQ!)
- A first trophy to get started with (this step should be hidden if the user has clicked on a trophy to see in the lens, this step should only appear if they load the helper app directly).
If the user has already registered with the system, they see details for how to achieve the selected trophy.
This provides (1) a summary of the trophy (2) links to online resources where you can find help for the topics covered by this trophy and (3) an overview of what you need to do to accomplish the trophy.
The key point about the documentation here is that it is focused on the trophy and very instructive and prescriptive about the expectations of how you accomplish the trophy and what steps are involved.
If you click the My Trophies button you can see the current achieved trophies:
This list of trophies also includes a filtering facilities to select between the context (e.g. Ubuntu Community) and topics within that context (e.g. QA). The default view here would be ‘Show me [All] trophies from [All Topics]’ and show all trophies.
Clicking the Opportunities button will show a similar view for unaccomplished trophies that are still available to be achieved:
Clicking each of these potential accomplishments will then display the trophy information screen presented earlier.
Many of the potential bug achievements are not shown here because they require these accomplishments to be completed first. As an example, if the user completed the ‘Fixed First Bug’ accomplishment the following notify-osd bubble would appear:
If the user starts the Ubuntu Trophy Cabinet helper app directly (not by clicking on something in the lens) they will see the following: