views:

260

answers:

2

Conceptually speaking how would one go about writing an achievement system for a website using PHP and MySQL?

Is the only real way of doing it is to constantly do MySQL queries to test for achievements and such?

A: 

You might want to consider asking a similar question on meta, to see if Jeff is willing to share any of his lessons learned in this arena. If you do, the question should be specifically about the way SO approached the problem. This question, however, is a perfectly valid question for this site (since it is asking about created a new project, inspired by what was done on SO).

I suspect, though, that the SO team has a job that periodically runs a set of queries to look for new badges to award, and then awards them. This is why badges aren't awarded immediately after the action is taken to earn them.

pkaeding
ah that is actually a good point! I didn't even realize badges weren't awarded as soon as they were awarded, it makes sense though because these queries would be quite slow... pity it can't be done instantly..
meds
This does **NOT** belong on meta
Andreas Bonini
no, I did not mean that this question belonged on meta. I meant that asking the SO team for insights learned while developing SO might be an appropriate sister question to this one. I have added clarification on this.
pkaeding
+5  A: 

You have two options, and most likely can combine them:

You can have a cron-job that runs every X-minutes, and runs over the database looking at each user and checks if they deserve a new badge.

For example, StackOverflow implements this for the Nice Answer badge. Everytime it runs, it checks how many Answers with +10 upvotes you have, and sees if you need to be awarded another badge. (It sees 5 posts with 10 upvotes and 4 Nice Answer Badges, you get a badge). Jeff has already stated that this means if you get an answer that gets a 10 vote, then downvoted, and then another post gets 10 votes, you won't get a badge.

The second option is event-based triggers. Which are really simply:

$badgeSystem->giveBadge("Some Badge Name", $User_ID);

This can be used for events you know are happening. Like the Autobiographer badge. Chances are the user won't fill out his profile unless the submit button is pressed, so the site could just check if the user has filled out the entire thing, and if they have, and they still need the badge, they get it.

The cron-job should be used for actions that are constantly checked. Things like quantitative goals like visiting the site for 150 days, or editing 500 times.

The event-based trigger should happen when an event will only happen if the user doesa specific action, such as submitting a form.

(You could probably use either for almost any situation. The event-based trigger gives quicker feedback though..)

Chacha102