Datastore loading incorrectly

Hello!

I have made a data store script with added print statements.

  • the data the saves is a boolean value
  • When I made the boolean value to false (its through the serverside), and leave the game it prints that the boolean value is false
  • But when I rejoin it prints that the boolean value is true.

Any solutions?

local DS = game:GetService("DataStoreService")
local player_data = DS:GetDataStore("TutorialTest")

local function savePlayerData(player)
	if not player or not player.Parent then return end -- Ensure player exists
	local success, errorMessage = pcall(function()
		player_data:SetAsync(player.UserId, player.TutorialEnabled.Value)
	end)
	if not success then
		warn("Failed to save data for player " .. player.Name .. ": " .. errorMessage)
	else
		print("Successfully saved data for player: ", player.Name)
	end
end

local function loadPlayerData(player)
	local success, data = pcall(function()
		return player_data:GetAsync(player.UserId)
	end)

	if success and data then
		print("Successfully loaded data: ", data)
		player.TutorialEnabled.Value = data
	else
		print("Data loading failed or no data found. Setting default value to true.")
		player.TutorialEnabled.Value = false
	end
end

game.Players.PlayerAdded:Connect(function(player)
	local TutEnable = Instance.new("BoolValue")
	TutEnable.Name = "TutorialEnabled"
	TutEnable.Parent = player

	print("Player added: ", player.Name)
	print("Loading data for UserId: ", player.UserId)
	loadPlayerData(player)
	print("Loaded TutorialEnabled Value: ", player.TutorialEnabled.Value)
end)

game.Players.PlayerRemoving:Connect(function(player)
	print("Player removing: ", player.Name)
	print("TutorialEnabled Value Before Save: ", player.TutorialEnabled.Value)
	savePlayerData(player)
end)

sorry for bump up but i havent got a reply in two hours.

Sorry for late response,

Roblox data stores treat nil and false the same when retrieving data with GetAsync() . If you store false, when you retrieve the value, the DataStore might return nil, making it seem like true (since your default is true).
This means the issue isn’t with saving but with retrieving false values correctly.

if this doesn’t work let me know

local DS = game:GetService("DataStoreService")
local player_data = DS:GetDataStore("TutorialTest")

local function savePlayerData(player)
	if not player or not player.Parent then return end
	local tutorialValue = player:GetAttribute("TutorialEnabled")
	print("Saving TutorialEnabled:", tutorialValue)

	local success, errorMessage = pcall(function()
		player_data:SetAsync(player.UserId, tutorialValue)
	end)

	if not success then
		warn("Failed to save data for", player.Name, ":", errorMessage)
	else
		print("Successfully saved data for", player.Name)
	end
end

local function loadPlayerData(player)
	local success, data = pcall(function()
		return player_data:GetAsync(player.UserId)
	end)

	if success then
		print("Loaded data:", data)
		if data ~= nil then
			player:SetAttribute("TutorialEnabled", data)
		else
			print("Data was nil, setting default value to false.")
			player:SetAttribute("TutorialEnabled", false)
		end
	else
		warn("Failed to load data for", player.Name)
		player:SetAttribute("TutorialEnabled", false)
	end
end

game.Players.PlayerAdded:Connect(function(player)
	print("Player joined:", player.Name)
	loadPlayerData(player)
	print("Final TutorialEnabled Value:", player:GetAttribute("TutorialEnabled"))
end)

game.Players.PlayerRemoving:Connect(function(player)
	print("Player leaving:", player.Name)
	print("TutorialEnabled before saving:", player:GetAttribute("TutorialEnabled"))
	savePlayerData(player)
end)
1 Like

it doesn’t add that boolvalue. Because some other scripts require the boolValue for the tutorial to work.

if data will only proceed to the subsequent code if data is a value that isn’t nil nor false. If you want to narrow it down to check if it’s nil (and subsequently apply the default value), then you should do
if data ~= nil

1 Like

Even with that the boolean value still loads as true when it saves as false.

local DS = game:GetService("DataStoreService")
local player_data = DS:GetDataStore("TutorialTest")

local function savePlayerData(player)
    if not player or not player.Parent then return end -- Ensure player exists
    local success, errorMessage = pcall(function()
        player_data:SetAsync(player.UserId, player.TutorialEnabled.Value)
    end)
    if not success then
        warn("Failed to save data for player " .. player.Name .. ": " .. errorMessage)
    else
        print("Successfully saved data for player: ", player.Name)
    end
end

local function loadPlayerData(player)
    local success, data = pcall(function()
        return player_data:GetAsync(player.UserId)
    end)

    if success and data ~= nil then
        print("Successfully loaded data: ", data)
        player.TutorialEnabled.Value = data
    else
        print("Data loading failed or no data found. Setting default value to true.")
        player.TutorialEnabled.Value = true
    end
end

game.Players.PlayerAdded:Connect(function(player)
    local TutEnable = Instance.new("BoolValue")
    TutEnable.Name = "TutorialEnabled"
    TutEnable.Parent = player
    
    print("Player added: ", player.Name)
    print("Loading data for UserId: ", player.UserId)
    loadPlayerData(player)
    print("Loaded TutorialEnabled Value: ", player.TutorialEnabled.Value)
end)

game.Players.PlayerRemoving:Connect(function(player)
    print("Player removing: ", player.Name)
    print("TutorialEnabled Value Before Save: ", player.TutorialEnabled.Value)
    savePlayerData(player)
end)


ok but if the player left technically it doenst exist right? so thats why it is not saving maybe?

(on the function saveplayerdata the codes starts with “if not player or not player.Parent then return end”, i dont think that code is necessary)

(you could check with print() if that is the issue)

1 Like

Which print statements are firing when you join/leave?

Try to save it in a table like {player.TutorialEnabled.Value}

While the documentation clearly states “This event fires before ChildRemoved does on Players, and behaves somewhat similarly to Instance.DescendantRemoving. Since it fires before the actual removal of a Player”
AVGBrowser_IgQQ9Lsgt6

This statement proves to be false when SignalBehavior is set as “Deferred” under the workspace, as signals fire on the next resumption point when this mode is set.
There was a Roblox announcement claiming “SignalBehavior may improve performance in some experiences” this feature has since been turned on by default in all experiences.

You can either turn this off under your Workspace’s properties tab or just remove the guard clause.