[V1.1] Leaderstats Plus - Leaderstats have become unimaginably easier

Leaderstats Plus

Leaderstats Plus is a simple service designed to make Data saving and leaderstats easier than ever to use. With built-in data saving and leaderstats, you don’t need to worry about making your own systems to manage this stuff.

Utilising ProfileService, Leaderstats Plus is safe from possible data loss and stress of other DataStore issues.


How to Install

Rojo

To install Leaderstats Plus with Rojo, head into the ServerScriptService folder download the LeaderstatsPlus folder into your ServerScriptService directory.

Roblox

To install Leaderstats Plus with Roblox, download the latest release rbxm file and import it into Roblox Studio.


Usage

Example Code

local leaderstatsPlus = require(game:GetService("ServerScriptService").LeaderstatsPlus)
leaderstatsPlus:setDataValues({Cash = 100})

game:GetService("Players").PlayerAdded:Connect(function(player)
    local playerData = leaderstatsPlus(player)
    
    local currentCash = player:GetAttribute("Cash")
    player:SetAttribute("Cash", currentCash + 100) -- Login Bonus
end)

You should edit leaderstats by doing player:SetAttribute(leaderstatName: string, newValue: any) rather than editing the leaderstat value directly; editing it directly would work, it is not recommended.

15 Likes

Thank you, can you show us an example of using it? With pics and stuff
I want to see if its a LEADER in easy leaderstats plugins :laughing:

I might use this

2 Likes

Hiya !

I’m not 100% sure how to visually show you this module however I can give you some code snippets and examples on what it can do!

image

This module also supports strings, for whatever reason you use strings in a leaderstat!


Give 100 Cash when “Part” is touched

local lsp = require(game:GetService("ServerScriptService").LeaderstatsPlus)
local players = game:GetService("Players")

lsp:setDataValues({Cash = 0})
players.PlayerAdded:Connect(function(player) lsp(player) end)

game.Workspace.Part.Touched:Connect(function(hit: Part) 
    if hit.Parent:IsA("Model") and hit.Parent:FindFirstChild("Humanoid") then
        local character = hit.Parent
        local player = players:GetPlayerFromCharacter(character)
        local currentCash = player:GetAttribute("Cash")

        player:SetAttribute("Cash", currentCash + 100)
    end
end)

Give 100-200 cash every 3 seconds

local lsp = require(game:GetService("ServerScriptService").LeaderstatsPlus)
local players = game:GetService("Players")

lsp:setDataValues({Cash = 0})

players.PlayerAdded:Connect(function(player)
    lsp(player)

    coroutine.wrap(function()
        while true do
            local currentCash = player:GetAttribute("Cash")
            player:SetAttribute("Cash", currentCash + math.floor(math.random(100,200)))
            task.wait(3)
        end
    end)()
end)
3 Likes

dang it
i was planning on releasing some leaderstats service
gg

hope mine is different enough.

1 Like

I like this system, haven’t had any troubles. Is line 2 required for every values within the leaderstats? (is this the default number if no data was previously saved?)

Hey, I don’t quite understand your question sorry.

You should run :setDataValues() once, and that should be at the top of your script after you require the module.

If you want to add more leaderstats, you can just add another index to the dictionary, for example:

lsp:setDataValues({
    Cash = 100,
    Kills = 0,
    Deaths = 0
})

You can safely remove any value from this table and it will no longer display as a leaderstat, it will also wipe any data linked to that leaderstat.

And yes, in my example above, the 100 will be the default value for new players, if the player isn’t new, their data will be automatically loaded instead. A default value must be provided for any new values, it can literally just be 0 or “” depending on what value it is.

Hopefully this answers your question, if not sorry.

1 Like

I want to hopefully expand on this module, adding more features and extra things to help with using Leaderstats Plus.

If you’ve got any suggestions, please do reply to this post, or alternatively make a new issue with the suggestion label.

Thank you!

1 Like

Leaderstats Plus v1.1.0 is here!

What’s new:

  • Added LeaderstatsPlus:setPrefix(valueName, prefix)
  • Now displays long numbers abbreviated, for example, 1,000,000 will now show as 1M


:setPrefix(valueName: string, prefix: string)

The prefix paramater must be a string no longer than 1 character.


Installation

Rojo

To install Leaderstats Plus with Rojo, head into the ServerScriptService folder download the LeaderstatsPlus folder into your ServerScriptService directory.

Roblox

To install Leaderstats Plus with Roblox, download the latest release rbxm file and import it into Roblox Studio.

3 Likes

Hey quick question, why aren’t the leaderstats getting created? There is no error regarding the module, only errors regarding these scripts, since they can’t find the leaderstats folder, because it’s simply not being created.

image

This is the code used in the script handling leaderstats plus.

local leaderstatsPlus = require(game:GetService("ServerScriptService").LeaderstatsPlus)
local badgeservice = game:GetService("BadgeService")

local killbadge = 2129509408
local deathbadge = 2129509414


leaderstatsPlus:setDataValues({
	Kills = 0,
	Deaths = 0
})

--[[
game:GetService("Players").PlayerAdded:Connect(function(player)
	local playerData = leaderstatsPlus(player)

	local currentCash = player:GetAttribute("Cash")
	player:SetAttribute("Cash", currentCash + 100) -- Login Bonus
end) ]]






function onHumanoidDied(humanoid, player)
	local stats = player:FindFirstChild("leaderstats")
	if stats ~= nil then
		local deaths = stats:FindFirstChild("Deaths")
		local currentD = player:GetAttribute("Deaths")
		player:SetAttribute("Deaths", currentD + 1)
		local killer = getKillerOfHumanoidIfStillInGame(humanoid)
		handleKillCount(humanoid, player)
	end
end

function onPlayerRespawn(property, player)
	if property == "Character" and player.Character ~= nil then
		local humanoid = player.Character.Humanoid
		local p = player
		local h = humanoid
		humanoid.Died:Connect(function()
			onHumanoidDied(h, p)
		end)
	end
end

function getKillerOfHumanoidIfStillInGame(humanoid)
	local tag = humanoid:FindFirstChild("creator")
	if tag ~= nil then
		local killer = tag.Value
		if killer.Parent ~= nil then
			return killer
		end
	end
	return nil
end

function handleKillCount(humanoid, player)
	local killer = getKillerOfHumanoidIfStillInGame(humanoid)
	if killer ~= nil then
		local stats = killer:FindFirstChild("leaderstats")
		if stats ~= nil then
			local kills = stats:FindFirstChild("Kills")
			if killer ~= player then
				local currentKills = player:GetAttribute("Kills")
				player:SetAttribute("Kills", currentKills + 1)
				if not badgeservice:UserHasBadge(player.UserId, killbadge) then
					badgeservice:AwardBadge(player.UserId, killbadge)
				end
			else
				local currentKills = player:GetAttribute("Kills")
				player:SetAttribute("Kills", currentKills - 1)
			end
		end
	end
end

(P.S. Most of that code wasn’t made by me as this isn’t my game, but one of my friends’ game, and they made the original script working for normal datastores, all i did was change stuff to use the attribute things that leaderstatsplus uses)

Probably because you aren’t loading the players leaderstats, simply calling setDataValues won’t make everything magically work, you must call LeaderstatsPlus() on the player when they join.

The code you have commented out in your script is what you need. Uncomment that and remove the last two lines of that function and it should work.

If what I’ve said above doesn’t work, could you possibly send me your place file in DMs so I could have a look at what could be causing any other issues, however my solution above should work.

Hi, yes, you were right! Yesterday, an hour after I posted what I posted, I noticed that and fixed it but forgot to delete my original post.

I am however having an issue and it’s that the leaderstats get created in a random order. Most of the times, it ends up creating my Deaths leaderstat before the Kills one, making the person with most deaths the person on top of the leaderboard instead of the person with most kills. Is there a way to fix this?

Unfortunately, I don’t believe it’s currently possible as of right now.

When you call :setDataValues() and pass through a dictionary, Roblox automatically either randomises the order, or orders it alphabetically (I can’t remember which). Roblox does this because dictionaries aren’t Indexed.

This then means LeaderstatsPlus goes through the dictionary in the order Roblox has passed it in, rather than the way you wrote it.

Maybe there could be a delay between creating the values into the leaderstats folder?

Like for example, in the function, when it passes through the dictionary, add a wait(0.1) or something after it creates the first leaderstat, so that both leaderstats dont get created at the same time and get sorted automatically?

Sorry for the late reply.

Again, this wouldn’t work. When you do

LeaderstatsPlus:setDataValues({
 Kills = 100
 Deaths = 10
})

Roblox alpabetically orders the dictionary when sending it to LeaderstatsPlus, so the module will receive something like this:

{
 Deaths = 10
 Kills = 100
}

Therefore making deaths first, then kills. I would probably be able to make a feature to edit the display order, however I am no longer working on this project nor have the time, if anyone wants to make it and create a pull request I’m more than happy to publish that

Hi! Don’t worry about it, I found out I can just do this with ProfileService (the original module) so I decided to go with that instead, back then I didn’t even know leaderstats were possible to use with ProfileService so I spent ages looking for something like this lol

1 Like

ok so I am trying to make 2 leaderstats save, they both load in but only the first one saves does anyone know how to fix this error code:

local leaderstatsPlus = require(game:GetService("ServerScriptService").LeaderstatsPlus)
leaderstatsPlus:setDataValues({Cash = 100, Gems = 100})

game:GetService("Players").PlayerAdded:Connect(function(player)
    local playerData = leaderstatsPlus(player)
    
    local currentCash = player:GetAttribute("Cash")
	player:SetAttribute("Cash", currentCash + 100) -- Login Bonus
	local playerData = leaderstatsPlus(player)

	local currentCash = player:GetAttribute("Gems")
	player:SetAttribute("Gems", currentCash + 100) -- Login Bonus
end)

There is a few issues with your code. Firstly you are calling leaderstatsPlus() twice, you only need to call it once, which should be at the top of your player added function.

You also use the currentCash variable twice, which probably isn’t a great idea.

This could work:

local leaderstatsPlus = require(game:GetService("ServerScriptService").LeaderstatsPlus)
leaderstatsPlus:setDataValues({Cash = 100, Gems = 100})

game:GetService("Players").PlayerAdded:Connect(function(player)
    local playerData = leaderstatsPlus(player)

	player:SetAttribute("Cash", player:GetAttribute("Cash") + 100) -- Login Bonus
	player:SetAttribute("Gems", player:GetAttribute("Gems") + 100) -- Login Bonus
end)

trying it right now update in like 3 mins

1 Like

wow thanks it does work but also how would I add an amount to the players leaderstat with it on leaderstats and saving that number

I don’t quite understand, your leaderstats will be saved automatically.