Any reason my Datastore is not working

Directory:

  • ServerStorage
    • PlayerData (Folder)

Errors (Something to do with the “prints”)
18:09:25.562 - ServerScriptService.Datastore:33: attempt to concatenate field ‘wallet’ (a nil value)
18:09:47.240 - ServerScriptService.Datastore:43: attempt to concatenate field ‘wallet’ (a nil value)

Code:

--Varibles
local datastoreService = game:GetService("DataStoreService")
local datastorePlayerdata = datastoreService:GetDataStore("datastorePlayerdata")
local datastoreOffences = datastoreService:GetDataStore("datastoreOffences")
local serverStorage = game:GetService("ServerStorage")

--Starting data
local defaultPlayerdata = {
	bank = 4000;
	wallet = 0;
}

--Load data
game.Players.PlayerAdded:Connect(function(player)
	local playerData = datastorePlayerdata:GetAsync(player.UserId, defaultPlayerdata, {"bank", "wallet"})
	local playerdataFolder = Instance.new("Folder")
	local bankValue = Instance.new("NumberValue")
	local walletValue = Instance.new("NumberValue")
	
	playerdataFolder.Name = player.Name
	playerdataFolder.Parent = serverStorage:WaitForChild("PlayerData")
	bankValue.Name = "bank"
	bankValue.Parent = playerdataFolder
	bankValue.Value = 4000
	walletValue.Name = "wallet"
	walletValue.Parent = playerdataFolder
	walletValue.Value = 0
	
	wait(1)
	bankValue.Value = playerData.bank
	walletValue.Value = playerData.wallet
	print("Loaded ".. player.Name.. " data successfully ".."["..playerData.bank.."//"..playerData.wallet.."]")
end)

--Save data
game.Players.PlayerRemoving:Connect(function(player)
	local newPlayerdata = {
		newBank = serverStorage.PlayerData[player.Name].bank.Value;
		newWallet = serverStorage.PlayerData[player.Name].wallet.Value;
	}
	datastorePlayerdata:SetAsync(player.UserId, newPlayerdata)
	print("Saved ".. player.Name.. " data successfully ".. "["..newPlayerdata.bank.."//"..newPlayerdata.wallet.."]")
end)
2 Likes

It seems like datastorePlayerdata:GetAsync is not correctly returning the default values. Perhaps there is bad player data present in the store without a wallet field left over from your previous testing? It would be helpful to see the GetAsync code as well.

Just made the datastore, I don’t think its some type of corrupted data.

If the player joins the first time, they have no saved data. It seems you’re setting the default values anyways? So there is not point in doing :GetAsync(player.UserId, defaultPlayerdata, {"bank", "wallet"}).

Just do :GetAsync(player.UserId) and check if the data exists before setting it:

local playerData = datastorePlayerdata:GetAsync(player.UserId)
if playerData then
    --code here
end

I would also wrap the :GetAsync() in a pcall incase it errors

Also when you save, make sure the indexes in the newPlayerdata are the exact same as the ones where you load data. So I would change newBank to bank and newWallet to wallet.

These are the changes I made and its now printing successfully but its not updating the table values?

--Varibles
local datastoreService = game:GetService("DataStoreService")
local datastorePlayerdata = datastoreService:GetDataStore("datastorePlayerdata")
local datastoreOffences = datastoreService:GetDataStore("datastoreOffences")
local serverStorage = game:GetService("ReplicatedStorage")

--[BANK AND WALLET DATA]--

--Starting data
local defaultPlayerdata = {
	bank = 4000;
	wallet = 0;
}

--Load data
game.Players.PlayerAdded:Connect(function(player)
	local playerData = datastorePlayerdata:GetAsync(player.UserId, defaultPlayerdata, {"bank", "wallet"})
	if playerData then
		local playerdataFolder = Instance.new("Folder")
		local bankValue = Instance.new("NumberValue")
		local walletValue = Instance.new("NumberValue")
	
		playerdataFolder.Name = player.Name
		playerdataFolder.Parent = serverStorage:WaitForChild("PlayerData")
		bankValue.Name = "bank"
		bankValue.Parent = playerdataFolder
		bankValue.Value = 4000
		walletValue.Name = "wallet"
		walletValue.Parent = playerdataFolder
		walletValue.Value = 0
		
		wait(1)
		defaultPlayerdata.bank = tonumber(playerData.bank)
		defaultPlayerdata.wallet = tonumber(playerData.wallet)
		print("Loaded ".. player.Name.. " data successfully ".."["..defaultPlayerdata.bank.."//"..defaultPlayerdata.wallet.."]")
	end
end)

--Save data
game.Players.PlayerRemoving:Connect(function(player)
	datastorePlayerdata:SetAsync(player.UserId, defaultPlayerdata)
	print("Saved ".. player.Name.. " data successfully ".. "["..defaultPlayerdata.bank.."//"..defaultPlayerdata.wallet.."]")
end)

--[OFFENCES DATA]--

Unless it hasn’t been updated in a while, from the normal API page the GetAsync function only accepts a key parameter, the rest is just wasted parameters. But correct me if I’m wrong…

Ah, right. In my reply above I assumed that he was using a data store wrapper module with default values. That is why I asked for the source. Looking closer it seems like a normal datastore, in which case I would agree with you: it only takes the key as a parameter.

1 Like

Tbh I honestly don’t understand, sorry.

Basically when you do:

Two of the variables you pass are wasted. “defaultPlayerdata” and {“bank”, “wallet”}.

If you remove those, it probably won’t immediately fix your problem but putting those variables there anyways is useless.

What is usually done with GetAsync() is to get the data with a singular key, that being the player’s user id. From there they check if the data that is related to that key, the user id, exists. If it doesn’t exist, it creates a new data folder with default values for the player.

This is what your code is missing. Your code checks if the data exists, but if the data doesn’t exist (like a new player joining your game for the first time) then it doesn’t do anything.

Understood, I’ll check it out.

--Varibles
local datastoreService = game:GetService("DataStoreService")
local datastorePlayerdata = datastoreService:GetDataStore("datastorePlayerdata")
local datastoreOffences = datastoreService:GetDataStore("datastoreOffences")
local serverStorage = game:GetService("ReplicatedStorage")

--[BANK AND WALLET DATA]--

--Starting data
local defaultPlayerdata = {
	bank = 4000;
	wallet = 0;
}

--Load data
game.Players.PlayerAdded:Connect(function(player)
	local playerData = datastorePlayerdata:GetAsync(player.UserId)
	local playerdataFolder = Instance.new("Folder")
	local bankValue = Instance.new("NumberValue")
	local walletValue = Instance.new("NumberValue")
	
	playerdataFolder.Name = player.Name
	playerdataFolder.Parent = serverStorage:WaitForChild("PlayerData")
	bankValue.Name = "bank"
	bankValue.Parent = playerdataFolder
	bankValue.Value = 4000
	walletValue.Name = "wallet"
	walletValue.Parent = playerdataFolder
	walletValue.Value = 0
		
	wait(1)
	if playerData then
                bankValue.Value = playerData.bank
                walletValue.Value = playerData.wallet
		print("Loaded ".. player.Name.. " data successfully ".."["..defaultPlayerdata.bank.."//"..defaultPlayerdata.wallet.."]")
	end
end)

--Save data
game.Players.PlayerRemoving:Connect(function(player)

	local newPlayerdata = {
		bank = serverStorage.PlayerData[player.Name].bank.Value;
		wallet = serverStorage.PlayerData[player.Name].wallet.Value;
	}

	datastorePlayerdata:SetAsync(player.UserId, newPlayerdata)
	print("Saved ".. player.Name.. " data successfully ".. "["..defaultPlayerdata.bank.."//"..defaultPlayerdata.wallet.."]")
end)

Try this.

EDIT: Realised I made a mistake and updated it.

How about this? (Still wont save the values)

Output:
Loaded aIphabox data successfully [4000//0]

19:36:32.361 - Disconnect from notshowingmmyiplol |61134

Saved aIphabox data successfully [4000//0]

--Varibles
local datastoreService = game:GetService("DataStoreService")
local datastorePlayerdata = datastoreService:GetDataStore("datastorePlayerdata")
local datastoreOffences = datastoreService:GetDataStore("datastoreOffences")
local serverStorage = game:GetService("ReplicatedStorage")

--[BANK AND WALLET DATA]--

--Starting data
local defaultPlayerdata = {
	bank = 4000;
	wallet = 0;
}

--Load data
game.Players.PlayerAdded:Connect(function(player)
	local playerData = datastorePlayerdata:GetAsync(player.UserId, defaultPlayerdata)
	local playerdataFolder = Instance.new("Folder")
	local bankValue = Instance.new("NumberValue")
	local walletValue = Instance.new("NumberValue")
	
	playerdataFolder.Name = player.Name
	playerdataFolder.Parent = serverStorage:WaitForChild("PlayerData")
	bankValue.Name = "bank"
	bankValue.Parent = playerdataFolder
	bankValue.Value = 0
	walletValue.Name = "wallet"
	walletValue.Parent = playerdataFolder
	walletValue.Value = 0
	
	if playerData then
		defaultPlayerdata.bank = tonumber(playerData.bank)
		defaultPlayerdata.wallet = tonumber(playerData.wallet)
		print("Loaded ".. player.Name.. " data successfully ".."["..defaultPlayerdata.bank.."//"..defaultPlayerdata.wallet.."]")
	else
		bankValue.Value = 4000
		walletValue.Value = 0
	end
end)

--Save data
game.Players.PlayerRemoving:Connect(function(player)
	datastorePlayerdata:SetAsync(player.UserId, defaultPlayerdata)
	print("Saved ".. player.Name.. " data successfully ".. "["..defaultPlayerdata.bank.."//"..defaultPlayerdata.wallet.."]")
end)

--[OFFENCES DATA]--

Try my code above, tell me if it works.

Doesn’t work sadly. I’ll keep trying

else
bankValue.Value = 4000
walletValue.Value = 0
end

These lines are reached when “playerData == nil”, which occurs when there is no data for a given player (means that the player is joining for the first time). These values are never used before the first time you save data, since you save data with the line

datastorePlayerdata:SetAsync(player.UserId, defaultPlayerdata)

So this means that the first time you save data, you’re saving the “defaultPlayerdata” of

{
bank = 4000,
wallet = 0,
}

as the data for your user. Then, each new time you’re getting the data for the same user, the data for that user has bank=4000, wallet=0, because this is what you saved. So this means that the lines

defaultPlayerdata.bank = tonumber(playerData.bank)
defaultPlayerdata.wallet = tonumber(playerData.wallet)

aren’t doing anything, since playerData.bank=4000 and playerData.wallet=0, but defaultPlayerdata.bank was already 4000 and defaultPlayerdata.wallet was already 0. Basically, you’ve never changing the values of “defaultPlayerdata”.

1 Like

Did some tinkering and got it fixed, thanks!

1 Like