This is most likely happening because the character doesn’t exist when PlayerRemoving is fired. It may be more beneficial to store WalkSpeed as a value in player, and then save that value instead.
you can’t save instances / values that are no longer exisiting [whether on joining or removing].
What you could do, is store a value called ‘PlayerSpeed’ [load it in the player whenever he joins], make sure its an int value / number [ depends].
And with that, you could save that value [that value will be inside the player as long as he’s in the game, unlike doing that with the character, which is getting disappeared, so it can’t save anything on removal.]
I think the character still exists when the PlayerRemoving event is fired, maybe add an if statement in front of your saving code an print the results?
PlayerRemoving essentially fires right before the player is removed which is guaranteed, but that doesn’t guarantee the character / humanoid exists.
Then again, this may not be your error. But, more than likely I’m willing to bet if you run game.Players.LocalPlayer:Kick() in your command bar to simulate a player leaving, and then look at your output, you’ll get something along the lines of a nil humanoid error or nil character error
You’re probably not getting this error because you’re pressing “Stop” in the test menu, which means PlayerRemoving is inconsistent as the script doesn’t have enough time to fully run before the play session is shut down.
But even in the real game your speed doesn’t save when you leave after buying speed upgrade. Here Try: Clicking MONSTERS! 👹 [V1.03] - Roblox It saves everything but your speed.
Well yes, my theory is that the error message will persist in a live game as well as it can’t actually find the Humanoid. The only reason you’re not getting the error message is because I assume PlayerRemoving doesn’t have enough time to fully fire.
Is everything else in the character, or is it in the player?
This would most likely line up with my theory then, give this a try and let me know if it changes.
Also I would highly recommend not using the following code for an actual live game, if you plan on converting this to live game code try to add a pcall for the :GetAsync and try to reduce the potential memory leaks that come along with this.
local DSS = game:GetService("DataStoreService")
local PlayerSave = DSS:GetDataStore("Walk")
game.Players.PlayerAdded:Connect(function(plr)
plr.CharacterAdded:Connect(function(char)
local WalkSpeed = PlayerSave:GetAsync("WalkSpeed-"..plr.UserId)
if WalkSpeed == nil then
WalkSpeed = 16
end
local hum = char:WaitForChild("Humanoid")
local NewValue = Instance.new("IntValue")
NewValue.Name = "Walkspeed"
NewValue.Value = WalkSpeed
hum.WalkSpeed = WalkSpeed
NewValue.Parent = plr
hum:GetPropertyChangedSignal("WalkSpeed"):Connect(function()
NewValue.Value = hum.WalkSpeed
end)
end)
end)
game.Players.PlayerRemoving:Connect(function(plr)
PlayerSave:SetAsync("WalkSpeed-"..plr.UserId,plr.Walkspeed.Value)
end)
Ight, lets do this :
[Similar to @alphadoggy111 's solution, but with a pcall]
local DataStore = game:GetService("DataStoreService"):GetDataStore("SpeedData")
game.Players.PlayerAdded:Connect(function(Player)
local speedData = DataStore:GetAsync("WalkSpeed-"..Player.UserId)
local SpeedValue = Instance.new("IntValue",Player)
SpeedValue.Name = "PlayerSpeed"
local success,error = pcall(function()
SpeedValue.Value = speedData
end)
if error then
SpeedValue.Value = 16
end
Player.CharacterAdded:Connect(function(Char)
local hum = Char:WaitForChild("Humanoid")
if hum then
hum.WalkSpeed = SpeedValue.Value
SpeedValue.Changed:Connect(function()
hum.WalkSpeed = SpeedValue.Value
end)
end
end)
end)
game.Players.PlayerRemoving:Connect(function(Player)
local success,error = pcall(function()
DataStore:SetAsync("WalkSpeed-"..Player.UserId,Player.PlayerSpeed.Value)
end)
if not success then
warn(error)
else
print(success)
end
end)