I was thinking of adding some Achievements to our internal bug-tracking and time logging system. It’s connected to an SQL Server back-end.
At first I thought that the system could be run on the database, using triggers to, for example, know when:
- you’ve logged 1000 hours
- created 1000 tickets
- closed your own ticket
- worked on a ticket that has been not touched in a while.
- etc (you know – database-ish things)
But then I realized that I would also want purely front-end achivements
- used the advanced search abiltiy
- sorted by a column
- reset settings to default
- searched 500 times
It seems like the logic of every achievement must be hand coded. Could anyone imagine an some sort of Achievements Rules Engine, that you for example create scripts for?
And how to store them? If the achievement is:
- change column sort order 50 times in one session
that would imply that every time they sort a listview column it updates the database.
Any thoughts on this Win32 application design problem? I don’t think that the Gang of Four have an Achievements design pattern.
Note: It’s a Win32 client application, not a web-site.
i definetly like the idea of an eventing system. Various actions the user takes can raise events through a single eventing object:
protected void TimeEntriesListView_ColumnSort(object sender, EventArgs e) { _globalListener.RaiseEvent(EventType.ListViewColumnSort, sender, e); } protected void TimeEntriesListView_ColumnDrag(object sender, EventArgs e) { _globalListener.RaiseEvent(EventType.ListViewColumnDrag, sender, e); }
That object can then have logic added to it to decide which events it wants to count. But more reasonably, various event listeners can attached to the central event listener, and have their custom achievement logic.
The trick isn’t the coding of the rules, really, those are straightforward, and can perhaps be simple expressions (number_of_bugs > 1000).
The trick is accumulating the statistics. You should look at a form of Event Stream Processing to record your achievements. For example, you don’t really want to implement the ‘1000 bugs’ achievement with ‘select count(*) from bugs where user= :user’ all the time (you could do it this way, but arguably shouldn’t). Rather you should get an event every time they post a bug, and you achievement system records ‘found another bug’. Then the rule can check the ‘number_of_bugs > 1000’.
Obviously you may need to ‘prime the pump’ so to speak, setting the number_of_bugs to the current number in the DB when you start the achievement system up.
But the goal is to keep the actual event processing light weight, so let it track the events as they go by with all of the events running on a common, internal pipe or bus.
A scripting language is a good idea as well, as they can easily evaluate both expressions and more complicated logic. ‘number_of_bugs > 1000’ is a perfectly valid Javascript program for example. The game is just getting the environment set up.
You can also store the scripts in the DB and make an ‘achievement’ editor to add them on the fly if you like, assuming you’re capturing all of the relevant events.