How do you abbreviate your leaderstats?

Hey! I am currently working on a simulator where you click to earn “Clicks”. However, I realized that if people get to 100T+ clicks, the leaderstats just look messy and have errors. I’ve looked all over the place but can’t find a working abbreviation script. Can anyone help me with creating an abbreviation script?
(I know this is pretty short, but I don’t really have anything else to include)

I don’t think you can manipulate the core leader board. Best bet is probably making your own.

It’s definitely possible to abbreviate leaderstats as I have seen multiple games do it, but I have no clue how to lol.

You can try converting it to a string and abbreviating it that way. A common module I’ve seen recommended is the one berezaa made for Miner’s Haven. Here’s his MoneyLib module:

(The relevant function is called “shorten”.)

3 Likes

I’d use Berezaa’s MoneyLib for this.

print(MoneyLib.DealWithPoints(1234)); --> 1.23k

or in (and only for) locale aware cases, International:

print(Intl.toLocaleString(1234, 'en', { notation = "compact" })); --> 1.2K

If you want to sort them, this might help: How can I have custom leaderboard sorting? - #2 by starmaq

1 Like

By the way I’m still unsure about that solution, the guy didn’t respond back. I doubt it would actually end up working.

Another solution I can think of is to quickly change all the leaderstats of all player to IntValues version so they’re sorted and bring them back instanly to string form (assuming that doesn’t change order again). I’m gonna assume that will get noticed though, beacuse the UI has to probably update which might take time (because the server is telling the client to update it, replication).

1 Like

I hate to sound stupid, but i’ve created a module script and pasted the code. I’ve even tried with just the shorten function and the prefix’s etc, it still didn’t work.
(I put the module script in serverscriptservice, i’m not sure if it should be somewhere else)

Does it throw an error and it is a LocalScript or a Script?
And what’s the source code of the ModuleScript
Try something like this (assuming you’ve named the module MoneyLib)

local ServerScriptService = game:GetService("ServerScriptService")
local MoneyLib = require(ServerStorage:WaitForChild("MoneyLib"))
-- Test to see if this prints
print(MoneyLib.DealWithPoints(1234)) --> 1.23k
-- Assign it to a StringValue in the leaderstats folder
[StringValue in the leaderstats folder of a player].Value = MoneyLib.DealWithPoints(value)

I’d put it on the ReplicatedStorage but it’s up to you.

No errors.

ModuleScript source code:

--[[
NOTICE
Copyright (c) 2019 Andrew Bereza
Provided for public use in educational, recreational or commercial purposes under the Apache 2 License.
Please include this copyright & permission notice in all copies or substantial portions of Miner's Haven source code
]]

local MoneyLib = {}


MoneyLib.Suffixes = {"k","M","B","T","qd","Qn","sx","Sp","O","N","de","Ud","DD","tdD","qdD","QnD","sxD","SpD","OcD","NvD","Vgn","UVg","DVg","TVg","qtV","QnV","SeV","SPG","OVG","NVG","TGN","UTG","DTG","tsTG","qtTG","QnTG","ssTG","SpTG","OcTG","NoTG","QdDR","uQDR","dQDR","tQDR","qdQDR","QnQDR","sxQDR","SpQDR","OQDDr","NQDDr","qQGNT","uQGNT","dQGNT","tQGNT","qdQGNT","QnQGNT","sxQGNT","SpQGNT", "OQQGNT","NQQGNT","SXGNTL"}                                              
--                                                  																																															^NEW     ^ 10e123
MoneyLib.CachedShorts = {}

-- 2/3 was TOO HIGH

-- 2/3.5
-- 4/7

-- 2/4 TOO LOW
-- 2/5 is TOO LOW

local function sqrtfac(RB)
	local n = 1000
 	return (math.floor((RB^(4/7) * 5000^(3/7)) / (1000/n) ) * (0.24/n))	
end

MoneyLib.RebornPrice = function(RB)
	local n = 1000
	
	local limRB = RB
	if limRB > 5000 then
		limRB = 5000
	end
	
	local overRB = RB - limRB	
	
	-- 0.23 per 1000 lives
	local low = (math.floor(limRB / (1000/n)) * (0.24/n))
	local high = 0
	
	if RB > 5000 then
		high = sqrtfac(RB) - sqrtfac(5000)
	end
	
	local Expo = 1 + low + high
	local Multi = ((math.floor(RB/5) * 2) + 1) * (1+(math.floor(RB/25)*100)) * (1 + math.floor(RB/500)*1000)
	local Price = (25000000000000000000 * Multi) ^ Expo
	if Price > 2.5 * 10^181 then
		Price = 2.5 * 10^181
	end
	return Price
end

MoneyLib.LifeSkips = function(RB, Money)
	local Cost = MoneyLib.RebornPrice(RB)
	local n = 3
	for i=20,1,-1 do
		local Price = Cost * (10^(n*i))
		if Money > Price then
			return i
		end
	end
	return 0
end


function MoneyLib.HandleLife(Life)
	local Suffix
	local LastDigit = tonumber(string.sub(tostring(Life),string.len(tostring(Life))))
	if Life <= 20 and Life >= 10 then
		Suffix = "th"
	elseif LastDigit == 1 then
		Suffix = "st"
	elseif LastDigit == 2 then
		Suffix = "nd"
	elseif LastDigit == 3 then
		Suffix = "rd"
	else
		Suffix = "th"
	end
	return tostring(Life)..Suffix
end

MoneyLib.ShortToLong = function(MoneyShort)
	if MoneyLib.CachedShorts[MoneyShort] ~= nil then
		return MoneyLib.CachedShorts[MoneyShort]
	end
	local result
	local eCutoff = string.find(MoneyShort,"e%+")
	if eCutoff ~= nil then
		local Coeff = tonumber(string.sub(tostring(MoneyShort),1,1))
		local Zeros = tonumber(string.sub(tostring(MoneyShort),eCutoff+2))
		result = Coeff * 10^Zeros
	else	
		for i,v in pairs(MoneyLib.Suffixes) do
			local Cutoff = string.find(MoneyShort,v)
		--	print(string.sub(MoneyShort,string.len(MoneyShort)-string.len(v)+1),v)
			if Cutoff ~= nil and string.sub(MoneyShort,string.len(MoneyShort)-string.len(v)+1) == v then
				local Moneh = string.sub(MoneyShort,1,string.len(MoneyShort)-string.len(v))
				local Answer = tonumber(Moneh) * 10^(3*i)
				result = Answer
			end
		end
	end
	MoneyLib.CachedShorts[MoneyShort] = result
	return result
end


local function shorten(Input)
	local Negative = Input < 0
	Input = math.abs(Input)

	local Paired = false
	for i,v in pairs(MoneyLib.Suffixes) do
		if not (Input >= 10^(3*i)) then
			Input = Input / 10^(3*(i-1))
			local isComplex = (string.find(tostring(Input),".") and string.sub(tostring(Input),4,4) ~= ".")
			Input = string.sub(tostring(Input),1,(isComplex and 4) or 3) .. (MoneyLib.Suffixes[i-1] or "")
			Paired = true
			break;
		end
	end
	if not Paired then
		local Rounded = math.floor(Input)
		Input = tostring(Rounded)
	end

	if Negative then
		return "-"..Input
	end
	return Input
end

MoneyLib.HandleMoney = function(Input)
	local Negative = Input < 0
	if Negative then
		return "(-$"..shorten(math.abs(Input))..")"
	end
	return "$"..shorten(Input)	
end



function MoneyLib.DealWithPoints(Input)
	return shorten(Input)
end

return MoneyLib

Am I meant to include a localscript or script?

What I did was have the values on my leaderstats be StringValue and add a NumberValue and make the StringValue the NumberValue’s parent. Then I followed this tutorial on youtube:

If I want to add values to the leaderstats, I will have the NumberValue.Value added first, then choose abbreviation from the table (local Abbreviations = {}) and make the StringValue the abbreviation (With the use of the NumberValue)

For reference:

AddTap.OnServerEvent:Connect(function(plr)
	if plr.leaderstats.Taps.Taps_NumberValue.Value < 999 then
		plr.leaderstats.Taps.Taps_NumberValue.Value = plr.leaderstats.Taps.Taps_NumberValue.Value + (2^(plr.leaderstats.Rebirths.Rebirths_NumberValue.Value) * plr.Values.TapAccretion.Value * (plr.Values.TapsMultiplier.Value))
		plr.leaderstats.Taps.Value = plr.leaderstats.Taps.Taps_NumberValue.Value
	elseif plr.leaderstats.Taps.Taps_NumberValue.Value > 999 then
		plr.leaderstats.Taps.Taps_NumberValue.Value = plr.leaderstats.Taps.Taps_NumberValue.Value + (2^(plr.leaderstats.Rebirths.Rebirths_NumberValue.Value) * plr.Values.TapAccretion.Value * (plr.Values.TapsMultiplier.Value))
		local Taps_String = tostring(plr.leaderstats.Taps.Taps_NumberValue.Value)
		local ChosenAbbreviation
		for Abbreviation, Digits in pairs(Abbreviations) do
			if (math.floor(math.log10(Taps_String) + 1) >= Digits) and (math.floor(math.log10(Taps_String) + 1) < (Digits + 3)) then
				ChosenAbbreviation = Abbreviation
				break
			end
		end
		if ChosenAbbreviation then
			local Digits = Abbreviations[ChosenAbbreviation]
			local Taps_Numbers_Abbreviated = string.format("%.1f", (plr.leaderstats.Taps.Taps_NumberValue.Value / (10^(Digits - 1))))
			plr.leaderstats.Taps.Value = Taps_Numbers_Abbreviated..ChosenAbbreviation
		else
			plr.leaderstats.Taps.Value = plr.leaderstats.Taps.Taps_NumberValue.Value
		end
	end
end)
1 Like

Anyone ever find a solution for this? None of the replies work here.

For the leaderstats you could use a StringValue which is the formatted one with a IntValue inside it which is the full equivalent.

So you are saying create a StringValue (abbreviated number), parent it to leaderstats. Then, create an IntValue (full number) and parent that to the StringValue? It doesn’t sort correctly for me when doing so.

Well the String Value will be the value which will be displayed for example 1K and the IntValue inside of it will be the number equivalent 1000, and the leaderstats script will sync them.

Not working for me

image

Crowns = StringValue, whos value’s are set to 100K/20K
Value = IntValue, whos value’s are set to 100000/20000

image