New Players Getting Other Player's Data (DataStore with multiple values)

The issue that I am having is related to loading/saving data using DataStoreService.

For some reason, whenever a NEW player joins my game, anyone NEW that joins afterwards (in the same server) loads the first player’s data instead of creating new data for the player from a template.

I would like to know what the issue is because this bug makes my game completely unplayable. I have researched different methods for loading and saving data with multiple values, but the issue kept occurring no matter what I changed. I could only find one post that dealt with this same issue, but I wasn’t entirely sure what to change in my loading data function that would prevent players from getting other players’ data.

local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")

local ValuesDataStore = DataStoreService:GetDataStore("Values")


-- Data template for all new players
local DefaultData = {

	Data = {
		Deaths = 0,
		Coins = 0
	},

	Badges = {

		Category1 = {},
		Category2 = {},
		Category3 = {},
		Category4 = {},
		Category5 = {},
		Category6 = {}

	},

	Inventory = {},

	Quests = {},

	Codes = {},

	Settings = {},

}



-- Loading from Values Datastore
local function loadValues(Player)
	local success, values = pcall(function()
		return ValuesDataStore:GetAsync(Player.UserId)
	end)
	if success then
		if not values then
			values = DefaultData -- If no data, return the template
		end
		return values
	else
		warn("Error loading Values for " ..Player.Name.. ": " .. values)
		return DefaultData
	end
end


-- Saving to Values Datastore
local function saveValues(Player, Values)
	local success, error = pcall(function()

		-- Individual data
		for _, v in pairs(Player.Stats:GetChildren()) do
			Values["Data"][v.Name] = v.Value
		end

		ValuesDataStore:SetAsync(Player.UserId, Values)

	end)
	if not success then
		warn("Error saving Values for " ..Player.Name.. ": " .. error)
	end
end




-- When player joins, load their data
Players.PlayerAdded:Connect(function(Player)

	-- Load data
	local ValuesData = loadValues(Player)
	print(ValuesData)


	-- Stats folder for individual data inside ValuesData
	local StatsFolder = script.Stats:Clone()
	StatsFolder.Parent = Player


	-- Leaderstats folder to display badge count in player list
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = Player

	local Badges = Instance.new("IntValue")
	Badges.Name = "Badges"
	Badges.Value = 0
	Badges.Parent = leaderstats
	



	-- Loading individual data from ValuesData
	for _, v in pairs(StatsFolder:GetChildren()) do
		v.Value = ValuesData["Data"][v.Name]
	end


	-- Loading badge count for each badge that a player has inside of a category in ValuesData
	for category, badgeCategory in pairs(ValuesData["Badges"]) do
		for num, badgeId in pairs(badgeCategory) do
			Badges.Value += 1
		end
	end
	
	

end)



-- When player leaves, save their data
Players.PlayerRemoving:Connect(function(Player)

	local ValuesData = loadValues(Player)
	
	saveValues(Player, ValuesData)

end)

Any help is greatly appreciated!

the DefaultData variable makes reference to one singular instance of a table that you created at the start of your script, meaning the table is being shared across all your players

the solution is easy, either make a function that creates that template such as

function newTemplate()
	return {

		Data = {
			Deaths = 0,
			Coins = 0
		},

		Badges = {
		...
		}

		...
	}

end

or just use table.clone(DefaultData)

1 Like

Thanks! This seemed to have worked, but I will need to test it a few more times with multiple players to ensure that it stays working. I originally had the DefaultData table as a ModuleScript and referenced that when trying to create new data, not knowing that it was being shared/updated for each player. Appreciate it.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.