Yes, but you have to send new data to the client using remote events. The main reason I used surface guis was because I wanted to demonstrate leaderboards and make it as easy as possible to understand.
Could you kindly go over daily in a bit more depth, I’m kind of struggling with it. I don’t quite understand the if condition (where you’re resetting the value) and am struggling to structure it in a script. Are you storing another variable called lastTimeDataStored?
Here is what my leaderboard DataStore script looks like, I don’t know how I would implement the required if conditions to make sure the Daily etc. are updating correctly.
local ProfileCache = require(game.ServerScriptService.ProfileCacher)
local dateTable_1 = os.date("*t", os.time())
local key_1 = "Y:"..dateTable_1["year"].." M:"..dateTable_1["month"].." D:"..dateTable_1["day"]
--Unique key for each day
local dateTable_2 = os.date("*t", os.time())
local key_2 = "Y:"..dateTable_2["year"].." M:"..dateTable_2["month"]
--Unique key for each month
local dateTable_3 = os.date("*t", os.time())
local key_3 = "Y:"..dateTable_3["year"]
--Unique key for each year
local winsDataStoreAllTime = game:GetService("DataStoreService"):GetDataStore("Test")
local winsDataStoreDaily = game:GetService("DataStoreService"):GetDataStore("Test" .. key_1)
local winsDataStoreMonthly = game:GetService("DataStoreService"):GetDataStore("Test" .. key_2)
local winsDataStoreYearly = game:GetService("DataStoreService"):GetDataStore("Test" .. key_3)
game:GetService("Players").PlayerAdded:Connect(function(player)
if player then
wait(10)
local playerProfile = ProfileCache[player]
local playerKey = "Player_" .. player.UserId
while true do
-- Autosave Wins data from ProfileService to leaderboard DataStore every 30 seconds
local success, err = pcall(function()
winsDataStoreDaily:SetAsync(playerKey, playerProfile.Data.Wins)
print('Saved Value: ' .. tostring(winsDataStoreAllTime:GetAsync(playerKey)))
end)
local success, err = pcall(function()
winsDataStoreDaily:SetAsync(playerKey, playerProfile.Data.Wins)
print('Saved Value: ' .. tostring(winsDataStoreDaily:GetAsync(playerKey)))
end)
local success, err = pcall(function()
winsDataStoreMonthly:SetAsync(playerKey, playerProfile.Data.Wins)
print('Saved Value: ' .. tostring(winsDataStoreDaily:GetAsync(playerKey)))
end)
local success, err = pcall(function()
winsDataStoreYearly:SetAsync(playerKey, playerProfile.Data.Wins)
print('Saved Value: ' .. tostring(winsDataStoreDaily:GetAsync(playerKey)))
end)
wait(30)
end
end
end)
The method you use only ensures that the data loaded has been written on the same day, month, or year.
Say you have a value coins. The player gains 100 coins, and that value is written to the daily leaderboard. However, when the leaderboard resets the next day, and the player gains 100 coins, and they now have 200 coins, if you write 200 coins to the daily leaderboard, you no longer have a daily leaderboard.
There’s two solutions:
Easy: Update the daily value when it changes, so you only get the additional added and not the total value (for example, +100 instead of 200)
Complicated: Store a “daily value” with the player’s data, and add to it when you increment their coins or whatever value. Also save the day timestamp key which you can check, and if it doesn’t match the current one, reset the daily value.
TL;DR: It’s more complicated if you need to reset the value to only track a certain period of time, and the leaderboard won’t do it by itself.
Will this be okay if I have say 4 - 5 leaderboards which are copy and paste? The reason I ask, is because I would be writing to datastores at the same time. Couldn’t this cause dataloss?
Thanks for making this! If I were you I would go into more detail on the first post on how you can make daily leaderboards and stuff. I, myself, found this confusing at first until I read through all 100 posts. It would just help save time if this went into more detail. I could give an example of what you should say if wanted.
My mistake, it’s in the tutorial not the FAQ. Thought you were referring to daily leaderboard or something of that sort, not just a different leaderboard.
Edit: I have updates the FAQ with a section on making different leaderboards.
It appears that the maxValue variable does not have an effect, I’m trying to make it really high but no matter it, it looks like its capped at 9.22e+18.
Here I’m printing the leaderstat value of coins, the maxValue in your script and the coins value being passed in your script upon being updated (same as leaderstats). Why is it only going to 9.22Qn?
When I print the values of coins in the loop that iterates through the data, it returns 9.22e+18 so it seems like the problem is the :GetSortedAsync()? Is there a cap to it? I’ve got it currently set at 10e65 but it doesnt matter what I put it as.
EDIT: Nvm it looks like maxValue is working, but I’m confused as to why it keep resorting to 9.22e+18 in the loop through the data?
local smallestFirst = false--false = 2 before 1, true = 1 before 2
local numberToShow = 100--Any number between 1-100, how many will be shown
local minValue = 1--Any numbers lower than this will be excluded
local maxValue = 10e65--(10^30), any numbers higher than this will be excluded
print('MaxValue: ' .. maxValue)
local pages = dataStore:GetSortedAsync(smallestFirst, numberToShow, minValue, maxValue)
--Get data
local top = pages:GetCurrentPage()--Get the first page
local data = {}--Store new data
for a,b in ipairs(top) do--Loop through data
local userid = b.key--User id
local coins = b.value--Coins
print(coins)
local username = "[Failed To Load]"--If it fails, we let them know
local s,e = pcall(function()
username = game.Players:GetNameFromUserIdAsync(userid)--Get username
end)
if not s then--Something went wrong
warn("Error getting name for "..userid..". Error: "..e)
end
local image = game.Players:GetUserThumbnailAsync(userid, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size150x150)
--Make a image of them
table.insert(data,{username,coins,image})--Put new data in new table
end
This is the loop I’m talking about, b.value prints 9.22e+18
If your game needs to store high value numbers, you can always store it’s power to the 10. For example, 100 would be stored as 2, 10,000 as 4. Since you can’t store decimals, you could also multiply by a precision factor such as 1000 to allow for 3 points of decimal precision. If you need an example look above or if that isn’t enough I can provide a code snippet.
Strings cannot be ordered (at least not in the implementation), and so number values are required for OrderedDatastores. To “encode” numbers so that large ones can fit, you can use the following code:
local base = 10
local precision = 10000
local function encode(number)
return math.floor(math.pow(number, 1 / base) * precision)
end
local function decode(encoded)
return math.pow(encoded / precision, base)
end
local function test(number)
local encoded = encode(number)
local decoded = decode(encoded)
print(string.format('Original: %f Encoded: %f Decoded: %f', number, encoded, decoded))
end
test(100) -- Original: 100.000000 Encoded: 15848.000000 Decoded: 99.941215
test(1000) --Original: 1000.000000 Encoded: 19952.000000 Decoded: 999.687729
test(10000) --Original: 10000.000000 Encoded: 25118.000000 Decoded: 9996.559632
test(100000000) --Original: 100000000.000000 Encoded: 63095.000000 Decoded: 99988360.393047
test(2846893467) --Original: 2846893467.000000 Encoded: 88193.000000 Decoded: 2846696448.133367
You have to sacrifice precision in order to save larger numbers in the same space, but that won’t be an issue if you just want to prefix the first few numbers. This is the only soultion for OrderedDatastores.
The greater the base, the larger numbers you can store. The higher the precision, the smaller numbers you can store. Find a balance that works best for your game.
As a side note, I’d recommend editing your previous replies instead of posting new ones to help reduce clutter.
How did you modify the source code? This is likely due to something you did, as the leaderboard by itself still works completely as expected. Also, money is not something set by the global leaderboard.
I just wrote down the code everything works fine, but it wont be monthly like the leaderboard. It is showing my coins I have, but the thing is I want it to be at zero