What do you want to achieve? I have a point system for my juice bar that rewards a staff member with a point every time they mop a spill. Pretty self explanatory but I figured I should explain it anyway.
What is the issue? There isnât really an issue, but more of an inconvenience/a desire. I would like to configure it so that if you are below a specific rank (e.g. if you are below Junior Barista), your points will be shown as âN/Aâ.
What solutions have you tried so far? Iâve tried replacing specific parts of the code with other parts that I thought could have worked, but it didnât.
I do have the whole code but I wonât be posting everything here.
if Player:GetRankInGroup(7664258) >= 4 then
Points.Value = DS:GetAsync(Player.UserId)
DS:SetAsync(Player.UserId, Points.Value)
else if Player:GetRankInGroup(7664258) < 4 then
Points.Value = DS:GetAsync(Player.UserId)
DS:SetAsync(Player.UserId, "N/A")
end
end
I would like you to know that I am not experienced with programming whatsoever, so youâre gonna have to bear with me here. I thank you in advance.
Iâm not familiar with DS2, but if I had to guess these are the problems.
if Player:GetRankInGroup(7664258) >= 4 then
-- I assume Points is a StringValue
-- here you are getting a value from a DS and then immediately setting the same value to the DS, so the second like is redundant
Points.Value = DS:GetAsync(Player.UserId)
DS:SetAsync(Player.UserId, Points.Value) -- (redundant line)
else if Player:GetRankInGroup(7664258) < 4 then
Points.Value = DS:GetAsync(Player.UserId) -- setting Points.Value to DS
DS:SetAsync(Player.UserId, "N/A") -- setting DS to N/A (Points.Value won't be N/A)
-- I assume at this point you expect Points.Value to be N/A, but it won't since
-- you set it to whatever value was in the DS, and then after you set Points you
-- then set the DS to N/A
-- if you switch those two lines around you will be setting DS to N/A and then setting Points.Value to DS (which will be N/A)
end
end
again, I donât have the full context this is me assuming you want Points.Value to = N/A
In terms of your group, instead of saving as âN/Aâ, it may be better to simply showcase there point value as N/A when they join.
One possible use case on why this is better is because if someone were to join your group, then leave it, then return at a later date, none of there points from when they used to work there would save. Also, it looks like youâre saving data whenever they gain a point which isnât recommended. Generally speaking itâs a much better option to save the players data when they leave the game. Instead of saving data whenever they mop a spill, simply edit the value of there points leaderstat with:
player.leaderstats.Points.Value += 1
Anyways, here is a quick example of loading in IntValues for specfic group roles, and then loading in StringValues for users not authorized to gain points.
local Players = game:GetService("Players")
local DSS = game:GetService("DataStoreService")
local PointsDS = DSS:GetDataStore("Points")
Players.PlayerAdded:Connect(function(player) -- generate leaderstats and get points
local succ, result = pcall(function()
return PointsDS:GetAsync(player.UserId)
end)
local PointsValue
if succ then
if result ~= nil then
PointsValue = result
else
PointsValue = 0
end
end
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
if player:GetRankInGroup(7664258) >= 4 then
local points = Instance.new("IntValue")
points.Name = "Points"
points.Parent = leaderstats
points.Value = PointsValue
else -- if they are lower than RoleSet 4 this will fire instead
local points = Instance.new("StringValue")
points.Name = "Points"
points.Parent = leaderstats
points.Value = "N/A"
end
end)
game.Players.PlayerRemoving:Connect(function(player) -- instead of saving to the datastore every time they gain a point, simply just save them whenever a player leaves.
-- if you save it every single time a player gains a point, depending on how many players you have some requests may be dropped and not actually save.
if player:GetRankInGroup(7664258) >= 4 then
PointsDS:SetAsync(player.userId, player.leaderstats.Points.Value)
end
end)
Correct, I do want Points.Value being set to N/A for those under a specific rank. Thank you so much for attempting to help, but I will go forward with sorifyâs idea.
ohhh, I just reread the thread. For some reason I thought you were using DataStore2 ignore my first post.
Anyway glad you got the answer, and expanding on what sorify said
You should always read and write data to a proxy (a table or ValueBase) because of two huge bugs that can occur.
Surpassing the Datastore call budget, if you call to a Datastore too many times the requests will get queued and then dropped resulting in data loss. (big problem)
Race condition bugs, where some code reads from a Datastore after the Datastore should be changed but since itâs an Async call it hasnât been changed yet. This can be very problematic since players can exploit this (or it can happen by mistake) to duplicate money/items. (big problem)
Loleris has a good module for streamlining data saving called ProfileService
You are still allowed to push to the datastore after an action happens (you may need to do this in server wide messages or global leaderboards) But you should never read and write values directly to the Datastore.