Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Why doesn't this datastore work?

Hey. Within my mainscript for my game, I have a frequent use of DataStores. I must not be using them correctly, because they don't seem to work. It doesn't give me any "BlitzCredits" for winning. I do not earn a win on my leaderboard. Everything worked fine until I tried to use the datastores.

Heres where I set up the datastores...

function playeradded(player)
	
	local mydata = datastore:GetAsync(player.userId) or {}
	mydata.wins = mydata.wins or 0
	mydata.BC = mydata.BC or 0
	mydata.hyperlaser = mydata.hyperlaser or 0
	
	playerdata[player.userId] = mydata
	
	
	local leaderstats = Instance.new("Model")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	
	
	local wins = Instance.new("IntValue")
	wins.Name = "Wins"
	wins.Value = mydata.wins
	wins.Parent = leaderstats
	
	local hyperlaser = Instance.new("IntValue")
	hyperlaser.Name = "Hyperlaser"
	hyperlaser.Value = mydata.hyperlaser
	hyperlaser.Parent = player
	
	local BC = Instance.new("IntValue")
	BC.Name = "BlitzCreditz"
	BC.Value = mydata.BC
	BC.Parent = player
	
	
	
	
end
game.Players.PlayerAdded:connect(playeradded)
for _, player in pairs(game.Players:GetPlayers()) do
	playeradded(player)
end 

Heres my variables...

local datastore = game:GetService("DataStoreService"):GetDataStore("PlayerData")
local serverstorage = game:GetService("ServerStorage")
local replicatedstorage = game:GetService("ReplicatedStorage")
local debris = game:GetService("Debris")
local maps = serverstorage:WaitForChild("Maps")
local mapholder = game.Workspace:WaitForChild("MapHolder")
local gear = serverstorage:WaitForChild("Gear")
local statustag = replicatedstorage:WaitForChild("Status")
local timertag = replicatedstorage:WaitForChild("TimerTag")
local Winner = replicatedstorage:WaitForChild("Winner")
local resulttag = replicatedstorage:WaitForChild("result")
local event = replicatedstorage:WaitForChild("RemoteEvent")
local firstrun = true

local playerdata = {}

Here's the "Award Win" and "Award Credit" functions

function awardwin(players)
    for _, players in pairs do
		if players.Name == Winner.Value then

			local mydata = playerdata[players.userId]
            if players:FindFirstChild('leaderstats') and mydata then
				mydata.wins = mydata.wins + 1
				local winsvalue = players.leaderstats:FindFirstChild("Wins")
				if winsvalue then
					winsvalue.Value = mydata.wins
				end
            end
        end
    end
end



function awardcredit(players, credits)
    for _, players in pairs do
		if players.Name == Winner.Value then

			local mydata = playerdata[players.userId]
            if players:FindFirstChild('leaderstats') and mydata then
				mydata.BC = mydata.BC + credits
				local bcvalue = players:FindFirstChild("BlitsCreditz")
				if bcvalue then
					bcvalue.Value = mydata.BC
				end
            end
        end
    end
end

Some more datastore stuff...

function permsave(player)
	if player then
		local mydata = playerdata[player.userId]
		if mydata then
			datastore:SetAsync(player.userId, mydata)
		end
	end
end

game.Players.PlayerRemoving:connect(function(player)
	if player then
		permsave(player)
		playerdata[player.userId] = nil
	end
end)

game.OnClose = function()
	for i, v in pairs(playerdata) do
		datastore:SetAsync(i, v)
	end
end

Finally, here's when those functions are called...

for _, player in pairs(contestants) do
	if player and player.Character then
		local humanoid = player.Character:FindFirstChild("Humanoid")
		local matchtag = player:FindFirstChild("MatchTag")
		if matchtag and #activecontestants == 1 then
			Winner.Value = player.Name
			resulttag.Value = "Winner"
			awardcredit(Winner.Value, 4)
			awardwin(player)
		end

That's it! Sorry that that was a lot lol. I didn't wanna post the whole 300 line code, so I tried to break it up. Also, using the DataStores a gui is supposed to reflect the amount of BlitzCreditz a player has, but I assumed it wasn't working because the Datastores weren't working properly.

Thanks for all your help!

1 answer

✓ Accepted answer

To fix, im not positive but I think you have to use the UpdateAsync() method to override what is stored in order to set the new values, example below. So first you get the datastore service, then you get the datastore, then when changing the amount you first UpdateAsync() to retrieve the value previous and update it with the new value. In your script, your going to want to use UpdateAsync() to change the player points when the player wins.

local DataStore = game:GetService("DataStoreService"):GetDataStore("Points")
 
game.Players.PlayerAdded:connect(function(player)
	local key = "user_" .. player.userId
	--we want to give 50 points to users each time they visit
	DataStore:UpdateAsync(key, function(oldValue)
		local newValue = oldValue or 0 --oldValue might be nil
		newValue = newValue + 50
		return newValue
	end)
end)

6 comments

0

So do you mean when I set up the datastores, I use UpdateAsync instead of GetAsync?

0

GetAsync to retrieve data, SetAsync to change data, UpdateAsync to change data when the previous value is still important, in this script they use the previous value oldValue and apply the new value as newValue

0

Wait, how does it know what oldValue is?

0

oldvalue is the value retrieved by UpdateAsync, your changing that to a new value, but you still want to use it in this case to add on the new value to it, leave a rep please if this helped!

0

One more thing- sorry im so needy lol. Why do I need the return thing? will that be used somewhere else?

0

I believe it its returning the value to the function UpdateAsync()

This discussion is preserved as it was. New answers, comments, and votes are closed.