Why isn't my datastore working?

Hey Roblox devs. I’m making a datastore system in my game, but it doesn’t seem to be working for some reason. It’s not giving me any errors, so I don’t really understand why it wouldn’t work…
Here is my script:

local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local PlayerData = DataStoreService:GetDataStore("PlayerData")
local MultiplayerData = DataStoreService:GetDataStore("MultiplayerData")


Players.PlayerAdded:Connect(function(player)
	
	local leaderstats = Instance.new("Folder", player)
	leaderstats.Name = "leaderstats"

	local Coins = Instance.new("IntValue", leaderstats)
	Coins.Name = "Coins"
	local XP = Instance.new("IntValue", leaderstats)
	XP.Name = "XP"
	local Level = Instance.new("IntValue", player)
	Level.Name = "Level"
	local Rank = Instance.new("IntValue", player)
	Rank.Name = "Rank"

	local GunsUnlocked = Instance.new("Folder", player)
	GunsUnlocked.Name = "GunsUnlocked"
	--add each unlockable gun as a bool value

	local GunLevels = Instance.new("Folder", player)
	GunLevels.Name = "GunLevels"
	local BlackoutLevel = Instance.new("IntValue", GunLevels)
	BlackoutLevel.Name = "BlackoutLevel"
	local MP7Level = Instance.new("IntValue", GunLevels)
	MP7Level.Name = "MP7Level"

	local campaignLevel = Instance.new("IntValue", player)
	campaignLevel.Name = "campaignLevel"

	local CurrentObjective = Instance.new("IntValue", player)
	CurrentObjective.Name = "CurrentObjective"
	
	local playerID = player.UserId
	local data = nil
	pcall(function()
		data = PlayerData:GetAsync(playerID)
	end)
	
	if data~= nil then
		Coins.Value = data
		XP.Value = data
		Level.Value = data
		Rank.Value = data
		
		BlackoutLevel.Value = data
		MP7Level.Value = data
		
		campaignLevel.Value = data
		CurrentObjective.Value = data
		
		print("og player")
	else
		Coins.Value = 0
		XP.Value = 0
		Level.Value = 0
		Rank.Value = 0
		
		BlackoutLevel.Value = 0
		MP7Level.Value = 0

		campaignLevel.Value = 0
		CurrentObjective.Value = 0
		
		print("new player to game")
	end
	
end)

Players.PlayerRemoving:Connect(function(player)
	local playerID = player.UserId
	
	local Coins = player.leaderstats.Coins.Value
	local XP = player.leaderstats.XP.Value
	local Level = player.Level.Value
	local Rank = player.Rank.Value
	local BlackoutLevel = player.GunLevels.BlackoutLevel.Value
	local MP7Level = player.GunLevels.MP7Level.Value
	local campaignLevel = player.campaignLevel.Value
	local CurrentObjective = player.CurrentObjective.Value
	
	local data = {
		Coins,
		XP,
		Level,
		Rank,
		
		BlackoutLevel,
		MP7Level,
		
		campaignLevel,
		CurrentObjective,
	}
	
	PlayerData:SetAsync(playerID, data)
end)

game:BindToClose(function()
	for i, player in pairs(game.Players:GetPlayers()) do
		if player then
			player:Kick("This game is shutting down")
		end
	end
	
	wait(5)
end)

please let me know if something is wrong with it.

1 Like

Change this below

	local playerID = player.UserId
	local data = nil
	pcall(function()
		data = PlayerData:GetAsync(playerID)
	end)

to this

	local playerID = player.UserId
	local data = nil
	local success, err = pcall(function()
		data = PlayerData:GetAsync(playerID)
	end)
        if success then print("got data") else print("failed to get data") end

let me know what happens

1 Like

It prints “got data” but when I leave and join back my data doesn’t save. This is my problem.

Is the script which increments these values in a local script or script

server script, you can’t do data stores on a local script

No what is incrementing your leaderstat values

I have a part with a proximity prompt and a local script attatched to it, so when its triggered it adds your coins by 25

I only have this for testing purposes.

local script, sorry I didn’t understand

It isn’t saving because the values are set by the client not the server

1 Like

Can you send me your whole entire local script contents please and I will create a remote function event which will make it work

I can make one myself but I’ll give it to you just in case I’ll have problems. Thanks though, I didn’t think of that.

local proximityPrompt = game.Workspace.click.ProximityPrompt

wait(1)
proximityPrompt.Triggered:Connect(function()
	game.Players.LocalPlayer.leaderstats.Coins.Value = game.Players.LocalPlayer.leaderstats.Coins.Value + 25
	
end)

put this in the local script, change the entire thing

local proximityPrompt = game.Workspace.click.ProximityPrompt

wait(1)
proximityPrompt.Triggered:Connect(function()
    game:GetService("ReplicatedStorage"):FindFirstChild("RE"):FireServer() -- make a remoteevent in replicated storage called RE
end)

put a script in serverscriptservice, this will monitor the remote events


game:GetService("ReplicatedStorage"):FindFirstChild("RE").OnServerEvent:Connect(function(plr)
	plr.leaderstats.Coins.Value = plr.leaderstats.Coins.Value + 25
end)
1 Like

I’ve done the same thing already and it works. Thanks for helping though I was starting to lose hope.

Np just make sure to put that the topic is solved, any hearts would be appreciated :smirk_cat:

2 Likes

actually that doesn’t fix the problem. The remote event works and everything but it still doesn’t save my data when I leave and join back

nvm I just made a little error

The problem is the way you save and load the data.

You are saving the data as an array, which is fine but not optimal. However when loading the data you set the value of each value to the same variable? That does not make sense.

Instead of saving the data as array you can use a dictionary:

local DataToSave = {
 Coins = Coins.Value,
 Points = Points.Value,
 -- and so on
}

When loading you can then just index the value by the key:

Coins.Value = data.Coins
Points.Value = data.Points
-- and so on

If you have questions, let me know.

Enjoy lol and good luck on your game

I know. I used the dictionary originally and it gave me an error. I’ll trying to index the value by the key though.

You don’t need to use a RemoteEvent for Proximity Prompts, if you do it on a server script it already returns the player that triggers it.