This one is an interesting problem, for me at least. So basically what is supposed to be happening in these scripts is a player buys a 'level' from the shop. Upon buying it (if he has the funds), the "ownsmadhats" value in PlayerGui is changed to true (Mad Hats is the level name), and 100 'SpeedCoin' is deducted (my game currency. 100 because that is the price). However, whenever I leave the game after doing so the DataStore doesnt save these changes as it should. I should note that other changes are saved, like the gaining of SpeedCoin. Why?
DataStore Script
local datastore = game:GetService("DataStoreService")
local value1 = datastore:GetDataStore("Value1data")
local value2 = datastore:GetDataStore("Value2data")
local value3 = datastore:GetDataStore("Value3data")
local value4 = datastore:GetDataStore("Value4data")
local value5 = datastore:GetDataStore("Value5data")
local fvalue = datastore:GetDataStore("fvaluedata")
local katanavalue = datastore:GetDataStore("katanavaluedata")
local timevalue = datastore:GetDataStore("timevaluedata")
local totaltimevalue = datastore:GetDataStore("totaltimevaluedata")
local parent = script.Name
local madhatsvalue = datastore:GetDataStore("madhatsvaluedata")
game.Players.PlayerAdded:Connect(function(plr)
local leaderstats = Instance.new("Folder", plr)
local levels = Instance.new("Folder", plr)
local secrets = Instance.new("Folder", plr)
local otherstats = Instance.new("Folder", plr)
local v1 = Instance.new("IntValue",leaderstats)
local v2 = Instance.new("IntValue",otherstats)
local v3 = Instance.new("IntValue",leaderstats)
local v5 = Instance.new("StringValue",leaderstats)
local v4 = Instance.new("StringValue",leaderstats)
local timeval = Instance.new("NumberValue",otherstats)
local totaltimeval = Instance.new("NumberValue",otherstats)
local fcomplete = Instance.new("BoolValue", levels)
local katana = Instance.new("BoolValue", secrets)
local madhatsval = Instance.new("BoolValue", otherstats)
leaderstats.Name = "leaderstats"
otherstats.Name = "OtherStats"
secrets.Name = "Secrets"
levels.Name = "Levels"
v1.Name = "SpeedCoin"
v2.Name = "TotalAttempts"
v3.Name = "Attempts"
v4.Name = "Level"
v5.Name = "Mode"
fcomplete.Name = "ForestPack"
katana.Name = "Katana"
timeval.Name = "TimeSpent"
totaltimeval.Name = "TotalTimeSpent"
madhatsval.Name = "ownsmadhats"
v1.Value = value1:GetAsync(plr.userId) or 0
v2.Value = value2:GetAsync(plr.userId) or 0
totaltimeval.Value = totaltimevalue:GetAsync(plr.userId) or 0
v4.Value = value4:GetAsync(plr.userId) or "Lobby"
v5.Value = "Normal"
fcomplete.Value = fvalue:GetAsync(plr.userId) or false
madhatsval.Value = madhatsvalue:GetAsync(plr.userId) or false
katana.Value = katanavalue:GetAsync(plr.userId) or false
end)
game.Players.PlayerRemoving:Connect(function(player)
value1:SetAsync(player.userId, player.leaderstats.SpeedCoin.Value)
value2:SetAsync(player.userId, player.OtherStats.TotalAttempts.Value)
value3:SetAsync(player.userId, player.leaderstats.Attempts.Value)
value4:SetAsync(player.userId, player.leaderstats.Level.Value)
value5:SetAsync(player.userId, player.leaderstats.Mode.Value)
fvalue:SetAsync(player.userId, player.Levels.ForestPack.Value)
katanavalue:SetAsync(player.userId, player.Secrets.Katana.Value)
totaltimevalue:SetAsync(player.userId, player.OtherStats.TimeSpent.Value)
madhatsvalue:SetAsync(player.userId, player.OtherStats.ownsmadhats.Value)
end)
Script that handles purchase
function Click()
local Player = game:GetService("Players").LocalPlayer
local Character = Player.Character
if Player.leaderstats.SpeedCoin.Value >= 100 and Player.OtherStats.ownsmadhats.Value == false then
Player.leaderstats.SpeedCoin.Value = Player.leaderstats.SpeedCoin.Value - 100
Player.OtherStats.ownsmadhats.Value = true
Player.PlayerGui.purchase:Play()
script.Parent.Text = "Success! View your new level from the Levels tab/building!"
script.Parent.TextSize = 25
script.Parent.Parent.Parent.levels1.madhats.Visible = true
script.Parent.Parent.Parent.levels1.madhatslocked.Visible = false
wait(5)
script.Parent.Text = "Purchase"
script.Parent.TextSize = 60
else
Player.PlayerGui.error:Play()
script.Parent.Text = "Insufficient Funds/Already Purchased"
script.Parent.TextSize = 25
wait(3)
script.Parent.Text = "Purchase"
script.Parent.TextSize = 60
end
end
script.Parent.MouseButton1Down:connect(Click)
Please, ask any other additional questions you need answers for. Im stumped as to what to do. I just want the boolvalue and intvalues change to be saved.

2 comments
Note: Sorry for messy code. Im a very beginner level scripter.
I'm surprised your data saves at all, the name of the player's id property is UserId, not userId. Also, dont make your sound have the same name as a function ("error")