You should keep track of things the player has done if the achievement sums a collection of "unique" events, a set of events that can only be triggered once by each item in the list. Think of how you don't want the star coin counter to increment when collecting one for the second time.
If you were dealing with something more loose like "collect 9999 coins", you don't have to keep track of that, because it doesn't matter which coin it is, and could simply increment the achievement's counter.
Star coins are already tracked by basegame in the SaveData._basegame.starcoinCounter variable, so you can use that for star coins.
When it comes to levels, the way I usually do it is by checking the winType and making a lookup table to see what levels already had what types of exits collected, to prevent duplicates. Like this:
Code: Select all
SaveData.completion = SaveData.completion or {}
SaveData.completionCount = SaveData.completionCount or 0
function onExit()
-- Initialize the savedata variable if this is the first time we get an exit in this level
if SaveData.completion[Level.filename()] == nil then
SaveData.completion[Level.filename()] = {}
end
-- Check if we already got this exit
if SaveData.completion[Level.filename()][Level.winState()] then
return
end
-- Track the new exit, increment the counter
SaveData.completion[Level.fileName()][Level.winState()] = true
SaveData.completionCount = SaveData.completionCount + 1
Misc.saveGame()
end
If you have these counter variables you can then simply set the achievement's value to that of the counter to keep it up-to-date.