StatsManager is a simplified system for storing a player's stats. It doubles as a data-saving solution method as well as a stats container for managing savable and non savable stats for players. Whether or not data is saved can be decided on a case-by-case basis.
You can think of it a bit like a leaderboard, except more user-friendly.
Why use this module?
Choice between savable and non-savable stats
Detection for stat changes
Set who can access stats
Easily retrieve and modify stats
Works with ProfileService and DataStore2
StatsManager is incredibly easy to use, which makes it a great solution for your project. Additional functionality is provided for those who want it, but it is NOT required.
Updating stats is easy, here is a demo!
print(stats.Cash)
stats.Cash = stats.Cash + 10
‎
Functions
StatsManager
StatsProfile - GetData ( player , timeout )
Get Data for a specified player. Leave blank for LocalPlayer. If no timeout is set, the script will yield until player stats are found
local stats = StatsManager:GetData(player)
stats.Cash = stats.Cash + 10
void - SetTemplate ( dictionary )
Set default value and whether data saves. Customize functionality for each stat.
Edit stats for a user who is not currently in-game. This function will error if the user is currently in the same game, or if it is not called from the server
Set data saving wrapper, can be either "DataStore2" or "ProfileService". Leave blank for to use ProfileService (recommended)
StatsManager:SetWrapper("ProfileService")
void - SetTag ( tag )
This method does not need to be called unless you know what you are doing. Combine a tag (datastore key) for saved stats. Useful for porting from one data-saving solution to another.
StatsManager:SetTag("TagGoesHere")
‎
StatsProfile
RbxScriptSignal - GetUpdateSignal ( statName )
Returns a RbxScriptSignal, that fires when the specified stat is changed.
Under the hood, StatsManager currently uses DataStore2 and ProfileService for saving, however you can choose which wrapper you would like to use. Each wrapper has unique functionality that you can read up on. One main benefit of using ProfileService is that you will have session locking, which is why it is currently a more popular option.
Template Settings
Here is a reference list for changing attributes for each player stat:
Setting
Value
Visibility
"Public" / "Private" / "Server"
DefaultValue
any
Save
true / false
ClientEditBehaviour
"Modify" / "None"
ClientPrivilegeCheck
function
ClientAllowedValues
Array
More information
Visibility - "Public" / "Private" / "Server"
Public - Every user can see your stats, as well as the server
Private - Only the LocalPlayer and the server can see the stats
Server - Only the server can see the stats
DefaultValue - any
This can be any value, and it will be the default value of the stat
Save - true / false
Set’s whether the stat will be saved, for next time the user log’s in. This value defaults to true, so set it to false if you don’t want to save a particular stat.
ClientEditBehaviour - "Modify" / "None" Default’s to none, however if modify is set to “Modify”, a list of allowed value must also be set for the ClientAllowedValues setting.
ClientPrivilegeCheck - function
If a function is defined, and the value returned from it is true, the client will be given permission to edit the specified stat.
ClientAllowedValues - Array
A list of values that the client is allowed to change the value of the stat to.
While definitely a useful module, there’s a couple of pretty major issues.
For one, in the module is a PackageLink owned by you, which prevents people from uploading/publishing games we use this in. It’s easily removable, but still serves as an inconvenience for people who don’t know it exists.
Secondly, leaving and rejoining a server will not restore the saved data, as DataTokens for users are not removed upon leaving. This should fix itself when the player joins a new server, but serves as an issue if a user needs to rejoin a server.
Thirdly, adding a new value to the template, or altering a new value, will break the data stores in their entirety, refusing to update or even load the data. There isn’t a way around this as far as I know, but I’d recommend making use of ProfileService’s :Reconcile() function to fix this.
If these issues were to be fixed, I’d say this is the best and easiest data module out there. It’s simplicity and surprisingly level of flexibility serves as a good introduction to people who are just beginning data stores, while also serving it’s purpose for people who don’t decide to bother (like me). Overall a great module with a few major issues that need sorting out.
StatsManager makes it easy to load and change your stats, without the use of value objects. It has the additional benefit of being compatible with two wrapper modules which are DataStore2 and ProfileService, and replication is handled for values that you might not want to share between different clients.
Hey everyone, I’ve updated the module and applied some major fixes, so if you were having any issues, they shouldn’t be present anymore after updating the module!
Hey everyone, I’ve just added support for a new settings for stats called ClientPrivilegeCheck! This allows you to specify a function which checks if the client input from a player is valid, rather than relying on a list of pre-determined values. This can be useful in more arbitrary cases, where you are checking multiple conditions.
Basic example usage:
TeamPreference = {
Visibility = "Public",
DefaultValue = "Survivor",
ClientEditBehaviour = "Modify",
ClientPrivilegeCheck = function(value)
if value == "Survivor" or value == "Zombie" then
return true
end
return false
end,
};
What’s up again, I’ve made some more useful changes to the module to improve the workflow! This includes more detailed context for error messages.
Also a welcome addition, stats which are given permission to be modified by the client, have relevant data sent to the client upon initialization. This helps reduce network traffic as well as provide context to more error messages.
Error messages
[STATS MANAGER] Invalid method ':FindFirstChild()'. Try index stats using 'stat.StatName' [STATS MANAGER] Invalid method ':WaitForChild()'. Try index stats using 'stat.StatName'
Trying to call methods on a player’s stats such as :WaitForChild() or :FindFirstChild() will now error. Instead you will be told to use stats.StatName instead.
ERROR: [STATS MANAGER] Cannot edit data not owned by LocalPlayer
Attempting to edit the value of another player’s stats from the client will return an error. If you want a player to be able to modify another player’s stats, do this from the server instead!
ERROR: [STATS MANAGER] Client does not have access to stat statName
This error will appear when trying to change a value of the local player’s stats and the ClientEditBehaviour setting is not set to “Modify”. This setting defaults to “None” so ensure you have set it up correctly. Refer to Tutorial.
ERROR: [STATS MANAGER] Stat 'StatName' does not exist. Not present within stats template
In the table where you have configured the stats, the specified stat’s functionality has not been defined. Because of this the data cannot be edited because it does not exist in the stats profile.
As a reminder, I can’t stress enough, how much this will lower the amount of code you have to write, as well as being easy to use. If you are a new user and you’re looking for a data saving solution, please take the time to check out StatsManager.
That’s just an example I used if a player wants to set their own team from the client. If you want to know about it, under-the-hood, the server handles the requests and makes sure the are legitimate and match the type of values you expect.
I’m a bit confused about the phrasing of this question, but if you’re asking about reading each player’s stats on a case by case basis, I can definitely help you there.
Use the target player as the parameter for the person who’s stats you are trying to read/write from. Optionally, you can leave it blank and it will automatically fetch the stats for the LocalPlayer if the code is being run on the client.
Been a while since the StatsManager system was last updated. I’ve added support for DataStore tags, which are useful if you are converting from an existing DataStore solution!
I’ve realised that most people don’t really need or want to complete extra setup to use the module, therefore the following API Methods, SetTemplate, and GetData are the only ones required!
Additionally, some values in the template do not to be set. Therefore the bare minimum required is Visibility, DefaultValue, and Save.
Also, it’s crucial that you update your module if you are having trouble saving, a bug was fixed, where the save value in a template is always seen as false, even if users had set it to true.
Porting over to StatsManager
Some DataStore solutions require the user to supply a tag to combine their data. If this is the case, StatsManager includes an optional :SetTag() method.
Simply write in Lua code:
StatsManager:SetTag("YourTagGoesHere")
This will combine the defined tag to your data, and you will be able to access old save-data.
As always, updating the module won’t affect any save data, so it is highly encouraged!
hey gamma its me adam, im pretty sure you remember me.
but is this a DataStore module or a Stats/Leaderboard Maker & Datastore? im pretty confused on this even though roblox has major issues with datastores, thats why i came here.
Wassup Adam! StatsManager can be used for creating leaderboards, however it also lets you chose whether or not you want specific stats to be saved. Hopefully this clears that up for you.
ProfileService and DataStore2 are incorporated into this module, which means that backups are automatically created. It’s highly unlikely for data to be lost unless you are mis-using datastores. You can trust that this module won’t corrupt any player’s data, and I am currently using it in some of my own games. I’m hoping that I can build trust with you and other developers that can safely rely on this module.