Programming Achievements

Started by
9 comments, last by Atrix256 14 years, 9 months ago
So recently I've been trying to figure out the best way to implement an achievement system in my game. However, some of the more complex achievements I've seen make me wonder how the designers coded it in a way that wasn't terribly messy and a nightmare to debug. I mean, for instance in TF2, there's stuff ranging from "bump into someone who's cloaked when you're cloaked" to "kill a medic and a heavy pair when you're a heavy and a medic is healing you". What sort of structuring would allow for such a varied set of achievements?
Advertisement
Personally, I would make an achievements manager that simply unlocks achievements and saves the record that they've been unlocked.

Next, create classes for each type of achievement, e.g. grind (do x y many times), one-shot (do something once/get somewhere etc). These achivement objects are created one for each achievement, and tell the manager when an achievement has been unlocked.
Internally, achievement objects record data surrounding the achievement. The simplest example of this is "kill 50 guys" - the grind achievement object created for the this achivement tracks the number of kills, then informs the manager that the achievement has been completed.

The tricky bit is how to inform the achivement objects that something has been done. Most could be done using the observer pattern (the achivement object watches the game to see what happens) or a message system (achivement object receives "character killed" messages), but some are more complex could be done with a direct call from the source (eg check for death in a character's health decrement function).
Quote:Original post by Driverman
some of the more complex achievements I've seen make me wonder how the designers coded it in a way that wasn't terribly messy and a nightmare to debug.
That about sums it up. Some award/goal/unlock/other systems are extremely difficult, others are fairly simple.


Perhaps one of the easier ways to work with it is to have some sort of awards manager in your game.


They are obviously already tracking several things, such as kills. In that situation you simply send a notice to the award manager of a kill.

As an extremely simplified example:

OnKilledSomebody( const KillData* killData)
{
...
AwardManager::GetCurrentInstance().RecordKill( killData );
...
}

It is then up to the AwardManager class to tabulate the statistics and determine if the goal, award, mission, quest, or other event is complete.

For the achievement of medic/heavy while in a medic/heavy pair, you would need to include additional information in the kill event data, and have the award manager contain an event, perhaps tracking consecutive kills and checking to see if they match.


/edit: I type slower that Degra. But you can see the ideas are the same.
I was really hoping that this would be implementing "programming" achievements in an IDE. Which would be amazing.
Quote:Original post by rip-off
I was really hoping that this would be implementing "programming" achievements in an IDE. Which would be amazing.
rip-off typed 5,000 semi-colons without a coffee-break.
swiftcoder crashed Visual Studio 10 times in under an hour.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Okay, what you're saying to me is exactly what I had thought, but the problem is things like "kill an enemy when he took xxx action in the past 10 seconds." A lot of achievements could probably be taken care of by passing a snapshot of the game to the manager upon a kill (everyone's position, health, etc). The only way I can think of to deal with this is to have store like the entire last 5 minutes worth of data with each person in the snapshot that gets passed to the manager.
Achievement systems are just glorified data miners that look for specific sets of data and hand out awards when matches are found. The real difficulty comes from collecting and storing that data. If you're already keeping track of a lot of game statistics in a separate system, provided that you're tracking the right kind of data the achievement system might not even need to interface with game code at all and can just mine the statistics system whenever stats are changed or added. If on the other hand you don't already have a lot of stat tracking in place, then your achievement system might have to shoulder that burden and end up becoming rather intrusive as it plugs itself in all over the place to observe events that are relevant to the achievements.

At the end of the day there needs to be something littered throughout your game code that keeps track of everything going on and tabulating relevant data. It's better that this be a general-purpose statistics system that can be mined in a multitude of ways, than it be an achievement system that only serves a single purpose and could end up turning into throwaway code if it's tied too closely to a particular set of achievements.
Quote:Original post by rip-off
I was really hoping that this would be implementing "programming" achievements in an IDE. Which would be amazing.


Achievement Unlocked: SHIP IT! (Your code compiles with 0 errors or warnings.)
Achievement Unlocked: Here, let me do that for you (Successfully implemented a Win 32 API)

In the example of "Bump into someone who is cloaked while you are cloaked" there would be a little call in the collision detection code to call the achievement award for both players if the players are both cloaked. I imagine the more complex you get with the demands of the achievement, the more overhead you will have giving it out.

Kill Heavy Medic pair while a heavy and being healed
This one is tricky. I imagine I would have the achievement take note of the time if you killed a medic or heavy while they were healing a heavy/being healed (respectively), and also who the other person was. Then, if you kill the other part of that pair within x seconds, or before your next death, award the achievement. You'd need the appropriate overhead in the OnKill() code.

Sometimes, there just isn't an easy way to do things, you just have to brute force it.
Quote:Original post by rip-off
I was really hoping that this would be implementing "programming" achievements in an IDE. Which would be amazing.


Oh that would be so great. This old one comes to mind: Three Star Programmer

This topic is closed to new replies.

Advertisement