Methods Of Awarding Badges

API against BadgeOS

Generally, the app is able to call into BadgeOS using a GET call that specifies the user and achievement which are both static. Dynamic information would land in the App's database.

Reference: Award Badges API and Badge Design


  • Game Events - For example, Logging in or answering puzzle question. This is handled by annotating the method. The User is picked up from the session and bundled into an event which is responded to by a separate thread that logs the event and then passes it along to be evaluated.
  • Single external action visiting URL - Visited Course Page as an example. This will also work for an action linked to separate page back to App. At some point along the path, there should be an opportunity to invoke an API that awards the achievement. In this case, the achievement ID is passed to a Web Service endpoint which invokes a specific annotated method to create the event record as above.
  • Single internal action by Game - Registered Player App. In this case, the action can hard-code the achievement ID (or at least the mapping between the achievement and its ID) and the flow continues as above.
  • Manual Recommendation (not shown in the diagram)- Admin reviews and approves a request to be awarded an achievement. Can carry information to be reviewed.



Examples from the Badge Constellation

  • Registered Player App: Somewhere along the way — perhaps once the registration is completed against a confirmed email address — an annotated API can be called that generates the desired achievement record. This action maps directly to an achievement one-to-one for the session's user.
  • Visited Course Page: Within the application, when the link is selected, the response to the mouse-click or screen-tap will invoke an API endpoint with the associated achievement ID. Essentially, this a pre-mapped achievement and is one-to-one for the session's user. In this case, it makes sense to have a configured map with the following:
    • Component for presenting to the user and responding to the mouse-click / screen-tap.
    • Configured URL alongside the ID of the achievement; this can be recorded in a database table for ease of application maintenance.
    • Verification at run-time that the configured URLs provide an achievement ID that can be found in the Criteria tree.
    • Server-side response that verifies again that the achievement ID contributes toward some badge prior to an attempt to propagate the Badge Event.
  • Completed Pre-Ride Training: This achievement is awarded to each member of the present team. It may make sense to create an endpoint that accepts a Team and then generates the events for each user in that team. (Further notes below since there may be more than one team-wide achievement.)
  • Completed Course: There is some logic involved. We'd prefer that the three constituent steps be the same course, for example. Also, Accepting the invite probably should record the course. Will the record within the BadgeEvent table be sufficient? There is also some logic required to determine for a given course what the start and destination locations are so the correct badgeEvents are taken into account. Another question is whether or not it makes sense to put all the logic in the server and just issue the "Completed Course". To answer this, it is useful to point out that within BadgeOS, it will be easier to spell out what is required to complete a step if we break it into the constituent achievements within BadgeOS rather than "hide" it within the server. The visibility is a good thing to work out.
  • Participation Points: This has two constituent pieces: Provided Answer and Answered Correctly. In both cases, there is a `postAnswerForSession` call, but there is no evaluation of that puzzle to assert that one answer or the other is correct. That logic would affect which achievement to award. Regarding this particular badge, I can see advantages of encouraging evaluations — which I have not yet implemented. Want to think about this prior to release — or soon afterward.

Tour Examples

See Clue Ride page for themes.

  • Theme Close-Ended: Visiting each of the Tiny Doors, Breakfast locations, Markets, whatever. In this case, there needs to be a map between each location visited and the achievement accomplished. There is a one-to-one map, but maintaining this map is the interesting part.
    • Inbound event is derived from the Guide indicating the Team's arrival. This starts as a Team Event. (SVR-31)
    • As part of handling the event, it is parsed out according to the "methodName" field being set to "arrival". We may eventually assign this work to a separate thread, but for now, we can perform the work of awarding the badge synchronously with a) sending the Game State event and 2) persisting the event in the database. Performing this synchronously has the advantage of not having to check that SSE notification of game state and database persistence have occurred prior to awarding achievements.
    • Once the "arrival" event is found, the Attraction/Location is used to lookup a list of achievements. There may be zero or more, but arriving at this attraction will signify a "visit" to the attraction for the purposes of awarding the achievement. (There may be other team events that don't change the game state, but may trigger an achievement — awareness of a "tree tunnel" for example is not a stop, but it is still a visit.)
    • For each of the achievements (and for each team member), the call is made to award the achievement for the user.
  • Theme Open-Ended: Visiting the other places is counted differently, and may not be awarded? Does all of this occur within the CR Server App?

Implementation thoughts

  • Just the two Seeker badges and the list of Theme Close-Ended/Open-Ended badges are probably a good starting point.
  • Putting a BDD in front of each badge would help assert that I'm not regression-breaking critical functionality.
  • Clearing out the awards for a given user would help with this testing — particularly as changes are made to the content of the records (OutingView to OutingPlusGameState, for example). NOTE: There are a couple of wp_usermeta fields that track achievements: badgeos_achievements and badgeos_active_achievements.
  • Found some success building a "map" table within the database to hold the many-to-many or one-to-many or one-to-one relationships. The table `arrival_to_step_map` is one example.

Map of Attraction/Location to Achievements

  • Each attraction will have the ID and Name.
  • Each achievement will have a parent, ID, and name.
  • Parent may need to be chased another level up to tell if it is Open-Ended or Close-Ended.


  • When awarding "Completed Pre-Ride Training", the award need to take place against each member. Would it be too convoluted to cause each member's App to separately invoke the annotated method just so we could associate each User with the achievement? Maybe we want to award some achievements to each member of a team.
  • For a "Publicist": How to score a post to Facebook? Can we tap into the Facebook API to know when the post action is complete? If so, we can programmatically make a call and record the post response as well as invoke the awarding of the achievement. Review Action might carry this load.
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License