# How can I record stats and make achievements?

I am making my first game (a Browser Idle/Incremental game) and I don't know how to save records of all the actions that the player does in order to get achievements.

I mean, if you know what is an Idle game you'd also know that Idle games have a lot of recorded stats (time since started play, online time, offline time, time since last soft reset, amount of soft reset done, fastest soft reset, gold get, enemy killed, upgrades puchased, areas completed, etc...) and with some of those recorded stats achievements are done (play since a year, be offline for more than 100 hours, reach the level 1000, get a million of coins, etc...), but I'm not sure how to implement the record of those stats.

Actually this is my best aproach: It works, but I don't like it.

function updateLogic(time) { // Each time this is updated, all the logic of the game is updated
record("time", time) // Increase total time played record
game.cache.energyProduction = energyProduction(); // Calculate your energy (equivalent of Gold in other games) production in this second. (I use this a lot of times so I only calculate it one time per update and I store the variable in a "cache" to use later)
player.coinEnergy += game.cache.energyProduction; // Give energy to the player
record("totalEnergy", game.cache.energyProduction); // Increase total energy earned in record
dimensionAbilitiesUpdate(); // Do other things...
}


And then I have a record function:

function record(type, amount=null) {
if (type == "time") {
player.stats.time.online.setSeconds(player.stats.time.online.getSeconds() + amount); // Record total time played
player.stats.ascension.time.online.setSeconds(player.stats.ascension.time.online.getSeconds() + amount); // Record total time in this soft reset (you could think this as the total time in this level or area)
} else if (type == "totalEnergy") {
player.stats.ascension.totalEnergy += amount; // Record total energy earned in this ascension
player.stats.forever.totalEnergy += amount; // Record total energy earned since always
} else if (type == "ascension") { // Other stuff that I am tracking record...
player.stats.forever.ascentionTimes += 1;
}
}


I could add achievement (I haven't done it yet) adding some conditionals inside each conditional, eg:

[...]
if (type == "time") {
player.stats.time.online.setSeconds(player.stats.time.online.getSeconds() + amount); // Record total time played
player.stats.ascension.time.online.setSeconds(player.stats.ascension.time.online.getSeconds() + amount); // Record total time in this soft reset (you could think this as the total time in this level or area)
if (player.stats.time.online > 9999) {
player.archivements.youPlayedALotOfTime = true; // Or something similar
}
} else if [...]


I dislike this idea because it makes somewhat difficult the usage of the record function, actually, the first parameter only has three options (time, totalEnergy, ascension), but if I keep adding more it will become difficult to understand. But if I make one function for each stat there will be a lot of functions and maybe that could turn the scope into a mess (or at least I think).

Also, I've done some research and I found that in C# (so, I am not sure if it's possible in JavaScript) you can use some kind of "notifier". I mean, each time something happens program "throws to the air" (scope? log?) a message with the action done, and then a background function that is always searching for these messages takes it, process the record and deletes the message. (I tried to do something similar but instead of "throw the messages" I call the record function, maybe I could append that message to a list, and then a background function take the messages from it and process them).

Am I doing this... correctly? Is my attempt the common way of saving records? Shall I have only one function to do all the "records" (like I am doing) or shall I have one function per record? Shall I instead don't have a record function, just add those lines inside updateLogic? Maybe do my last question for records but achievement be checked in a separate function one time per update (or second, they aren't too important)? Shall I do something completely different? I am too new to this, so I don't have any idea.

P.S: If my code has an error exception don't pay attention, I did a quick resume of my code to be easier to understand (for example, I tried to remove the usage of decimals.js).

• I'm not sure if I completely understand your question, but I think you can use regular javascript event handlers to act as the C# notifiers. But as far as the data persistance goes, have you thought about how you want to store your data? Like, do you want to write it to a file somewhere or do you want to store it as cookies? – sjoerd216 Mar 6 '18 at 7:30
• @sjoerd216 Ok, but I am not sure how Javascript handlers will help me. Right now, my idea is to store the data in the game save as a dictionary (the game save is stored with local storage). – Ender Look Mar 6 '18 at 14:29