All Data Resets when Player Resets

In the datastore below, all data is resetting when the player dies/resets, but returns to normal when rejoining. Anybody know the problem?

local DataStoreService = game:GetService("DataStoreService")
local buttonProgressDataStore = DataStoreService:GetDataStore("ButtonProgress")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local buttonCountUpdated = Instance.new("RemoteEvent")
buttonCountUpdated.Name = "ButtonCountUpdated"
buttonCountUpdated.Parent = ReplicatedStorage

local pressedButtonsDataStore = DataStoreService:GetDataStore("PressedButtons")

-- Function to load the ButtonCount for a player
local function loadButtonCount(player)
	local success, result = pcall(function()
		return buttonProgressDataStore:GetAsync(player.UserId)
	end)

	if success and result then
		return result
	else
		return 0 -- Default to 0 if no data exists or error occurs
	end
end

-- Function to load the pressed buttons for a player
local function loadPressedButtons(player)
	local success, result = pcall(function()
		return pressedButtonsDataStore:GetAsync(player.UserId)
	end)

	if success and result then
		-- Convert the list of ButtonID values back into a table format
		local pressedButtons = {}
		for _, buttonID in pairs(result) do
			pressedButtons[buttonID] = true
		end
		return pressedButtons
	else
		return {} -- Default to an empty table if no data exists or error occurs
	end
end

-- Function to save the ButtonCount for a player
local function saveButtonCount(player, count)
	local success, errorMessage = pcall(function()
		buttonProgressDataStore:SetAsync(player.UserId, count)
	end)

	if not success then
		warn("Error saving ButtonCount for player " .. player.Name .. ": " .. errorMessage)
	end
end

-- Function to save the pressed buttons for a player
local function savePressedButtons(player, pressedButtons)
	-- Convert `pressedButtons` table to a list of ButtonID values
	local pressedButtonIDs = {}
	for buttonID, _ in pairs(pressedButtons) do
		table.insert(pressedButtonIDs, buttonID)
	end

	local success, errorMessage = pcall(function()
		pressedButtonsDataStore:SetAsync(player.UserId, pressedButtonIDs)
	end)

	if not success then
		warn("Error saving PressedButtons for player " .. player.Name .. ": " .. errorMessage)
	end
end

-- Listen for updates from the client and save progress
buttonCountUpdated.OnServerEvent:Connect(function(player, count, pressedButtons)
	saveButtonCount(player, count)
	savePressedButtons(player, pressedButtons)
end)

-- Handle when a player joins and load their progress
game.Players.PlayerAdded:Connect(function(player)
	local buttonCount = loadButtonCount(player)
	local pressedButtons = loadPressedButtons(player)
	-- Send the loaded progress and pressed buttons to the client
	buttonCountUpdated:FireClient(player, buttonCount, pressedButtons)
end)

-- Handle when a player leaves (save progress)
game.Players.PlayerRemoving:Connect(function(player)
	local buttonCount = loadButtonCount(player)
	local pressedButtons = loadPressedButtons(player)
	saveButtonCount(player, buttonCount)
	savePressedButtons(player, pressedButtons)
end)

1 Like

hello,

what do you mean “returns to normal when rejoining.”? as in it goes back to the correct amount of buttons pressed?

if so, it could just be an issue with displaying the data. if the buttons or button count are displayed on ui, make sure that the ScreenGui’s ResetOnSpawn’s property is set to false.

if you wouldn’t mind elaborating on your problem, that would be great

Thanks for your response.

by “returning back to normal” I mean that any player data that was there before the player resets returns when rejoining; almost like they never reset and lost everything.

In my game, I have a textlabel (ButtonCount) that displays the amount of buttons the player has pressed, and makes sure they can’t press the same button twice and have it add to the buttonscore. So if the player clicked 6 buttons, it would display 6/25. if they rejoined it would display 6/25 again. The same thing happens to the button clicking, where they shouldnt be able to click it twice and have it added on to the buttonscore

ResetOnSpawn is off on every GUI being used.

if it helps, here’s the localscript that goes along with this script:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local buttonCountUpdated = ReplicatedStorage:WaitForChild("ButtonCountUpdated")

-- Handles the strings in the WorldStrings folder in Worlds file in workspace
local worldFrame = script.Parent
local buttonCountLabel = worldFrame:WaitForChild("ButtonCount") -- TextLabel for Button Count
local worldNameLabel = worldFrame:WaitForChild("WorldName") -- TextLabel for World Name

-- Path to the WorldStrings folder
local worldStrings = workspace:WaitForChild("Worlds"):WaitForChild("World1"):WaitForChild("WorldStrings")

-- Get the values of NumberofButtons and WorldName
local numberOfButtons = worldStrings:WaitForChild("NumberofButtons")
local worldName = worldStrings:WaitForChild("WorldName")

-- Table to track which buttons have been pressed (prevents double counting)
local pressedButtons = {}

-- Initialize ButtonCount label to show the current progress (initialize to 0/NumberofButtons)
buttonCountLabel.Text = "0/" .. numberOfButtons.Value

-- Initialize the WorldName label to reflect the name in the WorldName string value
worldNameLabel.Text = worldName.Value

-- Variable to hold the saved ButtonCount value
local currentButtonCount = 0

-- Function to update the ButtonCount display
local function updateButtonCount()
	-- Update the text on the ButtonCount label
	buttonCountLabel.Text = currentButtonCount .. "/" .. numberOfButtons.Value
	-- Send the updated button count and pressedButtons to the server for saving
	buttonCountUpdated:FireServer(currentButtonCount, pressedButtons)
end

-- Function to handle when a button is clicked
local function onButtonClicked(button)
	-- Get the ButtonID value of the button
	local buttonID = button:FindFirstChild("ButtonID") and button.ButtonID.Value

	-- Check if ButtonID exists and hasn't already been pressed
	if buttonID and not pressedButtons[buttonID] then
		pressedButtons[buttonID] = true -- Mark the button as pressed using ButtonID
		currentButtonCount = currentButtonCount + 1 -- Increment the button count
		updateButtonCount() -- Update the ButtonCount text
	end
end

-- Function to initialize the click detectors for all buttons
local function setupButtonClickDetectors()
	local buttonsFolder = workspace:WaitForChild("Worlds"):WaitForChild("World1"):WaitForChild("Buttons")

	for _, button in pairs(buttonsFolder:GetChildren()) do
		if button:IsA("Part") then
			-- Ensure each button has a ClickDetector
			local clickDetector = button:FindFirstChildOfClass("ClickDetector")

			-- If it does not have a ClickDetector, create one
			if not clickDetector then
				clickDetector = Instance.new("ClickDetector")
				clickDetector.Parent = button
			end

			-- Connect the MouseClick event to the handler
			clickDetector.MouseClick:Connect(function()
				onButtonClicked(button)
			end)
		end
	end
end

-- Initialize button click detectors
setupButtonClickDetectors()

-- Optionally, monitor for any newly added buttons during the game
workspace.Worlds.World1.Buttons.ChildAdded:Connect(function(button)
	if button:IsA("Part") then
		-- Ensure each button has a ClickDetector
		local clickDetector = button:FindFirstChildOfClass("ClickDetector")

		-- If it does not have a ClickDetector, create one
		if not clickDetector then
			clickDetector = Instance.new("ClickDetector")
			clickDetector.Parent = button
		end

		-- Connect the MouseClick event to the handler
		clickDetector.MouseClick:Connect(function()
			onButtonClicked(button)
		end)
	end
end)

-- When the player joins, load their saved progress
buttonCountUpdated.OnClientEvent:Connect(function(savedCount, savedPressedButtons)
	currentButtonCount = savedCount or 0 -- Default to 0 if no saved count
	pressedButtons = savedPressedButtons or {} -- Default to an empty table if no saved pressed buttons
	buttonCountLabel.Text = currentButtonCount .. "/" .. numberOfButtons.Value
end)

sorry, this is actually the correct datastore script. I posted the wrong one.

local DataStoreService = game:GetService("DataStoreService")
local buttonProgressDataStore = DataStoreService:GetDataStore("ButtonProgress")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local buttonCountUpdated = Instance.new("RemoteEvent")
buttonCountUpdated.Name = "ButtonCountUpdated"
buttonCountUpdated.Parent = ReplicatedStorage

local pressedButtonsDataStore = DataStoreService:GetDataStore("PressedButton")

-- Function to load the ButtonCount for a player
local function loadButtonCount(player)
	local success, result = pcall(function()
		return buttonProgressDataStore:GetAsync(player.UserId)
	end)

	if success and result then
		return result
	else
		return 0 -- Default to 0 if no data exists or error occurs
	end
end

-- Function to load the pressed buttons for a player
local function loadPressedButtons(player)
	local success, result = pcall(function()
		return pressedButtonsDataStore:GetAsync(player.UserId)
	end)

	if success and result then
		-- Convert the list of ButtonID values back into a table format
		local pressedButtons = {}
		for _, buttonID in pairs(result) do
			pressedButtons[buttonID] = true
		end
		return pressedButtons
	else
		return {} -- Default to an empty table if no data exists or error occurs
	end
end

-- Function to save the ButtonCount for a player
local function saveButtonCount(player, count)
	local success, errorMessage = pcall(function()
		buttonProgressDataStore:SetAsync(player.UserId, count)
	end)

	if not success then
		warn("Error saving ButtonCount for player " .. player.Name .. ": " .. errorMessage)
	end
end

-- Function to save the pressed buttons for a player
local function savePressedButtons(player, pressedButtons)
	-- Convert `pressedButtons` table to a list of ButtonID values
	local pressedButtonIDs = {}
	for buttonID, _ in pairs(pressedButtons) do
		table.insert(pressedButtonIDs, buttonID)
	end

	local success, errorMessage = pcall(function()
		pressedButtonsDataStore:SetAsync(player.UserId, pressedButtonIDs)
	end)

	if not success then
		warn("Error saving PressedButtons for player " .. player.Name .. ": " .. errorMessage)
	end
end

-- Listen for updates from the client and save progress
buttonCountUpdated.OnServerEvent:Connect(function(player, count, pressedButtons)
	saveButtonCount(player, count)
	savePressedButtons(player, pressedButtons)
end)

-- Handle when a player joins and load their progress
game.Players.PlayerAdded:Connect(function(player)
	local buttonCount = loadButtonCount(player)
	local pressedButtons = loadPressedButtons(player)
	-- Send the loaded progress and pressed buttons to the client
	buttonCountUpdated:FireClient(player, buttonCount, pressedButtons)
end)

-- Handle when a player leaves (save progress)
game.Players.PlayerRemoving:Connect(function(player)
	local buttonCount = loadButtonCount(player)
	local pressedButtons = loadPressedButtons(player)
	saveButtonCount(player, buttonCount)
	savePressedButtons(player, pressedButtons)
end)

I mean you could try using ProfileStore - Save your player data easy (DataStore Module)
since it seems like you got Problems with DataStore.

1 Like

no worries!

i think what might be happening is the local script is restarting and since it only updates to the data store when the player joins it is being set to zero.

the thing is, i dont really know why this is happening if you have the local script inside of a frame with the screengui’s reset on spawn off.

if you replace the zeros in this section of the local script:

local pressedButtons = {}

-- Initialize ButtonCount label to show the current progress (initialize to 0/NumberofButtons)
buttonCountLabel.Text = "0/" .. numberOfButtons.Value

-- Initialize the WorldName label to reflect the name in the WorldName string value
worldNameLabel.Text = worldName.Value

-- Variable to hold the saved ButtonCount value
local currentButtonCount = 0

with results from the datastore instead, does anything change?

not too sure what you meant by replacing the 0’s with datastore results, but I replaced the 0 with a random number instead, which was one (unless this is what you meant lol). before I had 8/25. After reset, I had 1/25, and not 0/25.

sorry, i meant replace the zeros with the button count.

you might need to create a remote function so that you can request the server to give you the button count, and then change the zeros to it.

alright, hopefully I did it right, but it defaulted the ButtonCount to 25/25, and when resetting it would say 25/25

if this doesn’t sound right I can send over a video of the processes

thats odd…

how are you resetting it? try adding the line

savePressedButtons(coolbobcat45, {})

to anywhere in the datastore script, then playtest, then remove that line.

I did that and noticed no change.

just to clarify, by resetting I mean the player resetting.

Want me to send a video of the general process to help narrow down the issue?

also want to say thank you for the help so far, I’m going half crazy trying to figure this out and I appreciate the help

hello again!

apologies for the long wait, i was really tired so i just went to bed

yes, that would be great!

no problem! thats what the devforum is for : )

Here’s the video of the main problem:

gui problem

Where’s the local script located?

image

-- Listen for updates from the client and save progress
buttonCountUpdated.OnServerEvent:Connect(function(player, count, pressedButtons)
	saveButtonCount(player, count)
	savePressedButtons(player, pressedButtons)
end)

This is where your error is,

Make the StarterGui not ResetOnSpawn…

image

To me, you made this whole script horribly wrong. [but that’s just my opinion] anyway this should fix it.

The gui has to be Stored inside StarterGui. for this to work,
since the Folder you have is also being Reset on Spawn.

Turn the folder into ScreenGui, and ResetOnSpawn Disabled, for it to work.

The folder was the issue! Thanks!

and hey… as long as it works, right? :joy: