As long as you are using a server script, the code runs on the server.
They are both normal scripts. So would that mean they are server scripts?
Yes, that means they are server scripts.
My point is that when adding “Souls” to yourself, you need to do it through the server.
Yes I get that. So what in my script needs changing in order to accomplish that.
You shouldn’t need to change anything in your code to get it to run on the server, i’m trying to explain that when you give yourself “Souls” to test the selling and saving, that needs to be done on the server, but incase im misunderstanding the problem you’re having, i’ll give you the placefile with the changes i made to fix the problems you had.
DataTest.rbxl (32.9 KB)
The scripts are exactly the same, though yours works, and mine doesn’t. I’m sorry if i’m not understanding correctly is just what am i doing wrong?
The reason why it isn’t saving is the because the server is shutting before it can. To stop this you add BindToClose
This causes the server to complete the function specified before it closes.
Here is my script
local DataStoreService = game:GetService("DataStoreService")
local playerData = DataStoreService:GetDataStore("playerData")
local function onPlayerJoin(player)
local QuestsFolder = Instance.new("Folder")
QuestsFolder.Name = "QuestsFolder"
QuestsFolder.Parent = player
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local gold = Instance.new("IntValue")
gold.Name = "Gold"
gold.Parent = leaderstats
local level = Instance.new("IntValue")
level.Name = "Level"
level.Parent = leaderstats
local kills = Instance.new("IntValue")
kills.Name = "Kills"
kills.Parent = leaderstats
local xp = Instance.new("IntValue")
xp.Name = "XP"
xp.Parent = leaderstats
local maxXP = Instance.new("IntValue")
maxXP.Name = "MaxXP"
maxXP.Parent = player
local playerUserId = player.UserId
local data = playerData:GetAsync("Player_"..playerUserId)
if data then
gold.Value = data['Gold']
level.Value = data['Level']
kills.Value = data['Kills']
xp.Value = data['XP']
else
gold.Value = 50
level.Value = 1
kills.Value = 0
xp.Value = 0
end
end
local function onPlayerExit(player)
local player_stats = {}
if player then
for i, stat in pairs(player:WaitForChild("leaderstats"):GetChildren()) do
player_stats[stat.Name] = stat.Value
end
playerData:SetAsync("Player_"..player.UserId, player_stats)
end
end
game.Players.PlayerAdded:Connect(onPlayerJoin)
game.Players.PlayerRemoving:Connect(onPlayerExit)
game:BindToClose(function()
for i, player in pairs(game:GetService("Players"):GetPlayers()) do
onPlayerExit()
end
end)
The script will still work if you test it in a regular server but this also helps with server crashes and testing in studio. I would reccommend it.
I put the bind to close script into it. Though it still doesn’t work!
Did i implement it into the script correctly?
local DataStoreService = game:GetService("DataStoreService")
local playerData = DataStoreService:GetDataStore("PlayerData")
local function onPlayerJoin(player) -- Runs when players join
local leaderstats = Instance.new("Folder") --Sets up leaderstats folder
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local souls = Instance.new("IntValue") --Sets up value for leaderstats
souls.Name = "Souls"
souls.Parent = leaderstats
local coins = Instance.new("IntValue") --Sets up value for leaderstats
coins.Name = "Coins"
coins.Parent = leaderstats
local playerUserId = "Player_" .. player.UserId --Gets player ID
local data = playerData:GetAsync(playerUserId) --Checks if player has stored data
if data then
souls.Value = data['Souls']
coins.Value = data['Coins']
else
-- Data store is working, but no current data for this player
souls.Value = 0
coins.Value = 0
end
end
local function create_table(player)
local player_stats = {}
for _, stat in pairs(player.leaderstats:GetChildren()) do
player_stats[stat.Name] = stat.Value
end
return player_stats
end
local function onPlayerExit(player) --Runs when players exit
local player_stats = create_table(player)
local success, err = pcall(function()
local playerUserId = "Player_" .. player.UserId
playerData:SetAsync(playerUserId, player_stats) --Saves player data
end)
if not success then
warn('Could not save data!')
end
end
game.Players.PlayerAdded:Connect(onPlayerJoin)
game.Players.PlayerRemoving:Connect(onPlayerExit)
game.Players.PlayerAdded:Connect(onPlayerJoin)
game.Players.PlayerRemoving:Connect(onPlayerExit)
game:BindToClose(function()
for i, player in pairs(game:GetService("Players"):GetPlayers()) do
onPlayerExit()
end
end)
why do you have multiple of the same things?
I would recommend doing my script ignore the call to create table.
So use your script but replace your variables with mine?
If you want to but it works for me.
alright…
local DataStoreService = game:GetService("DataStoreService")
local playerData = DataStoreService:GetDataStore("playerData")
local function onPlayerJoin(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local souls = Instance.new("IntValue")
souls.Name = "Souls"
souls.Parent = leaderstats
local coins = Instance.new("IntValue")
coins.Name = "Coins"
coins.Parent = leaderstats
local playerUserId = player.UserId
local data = playerData:GetAsync("Player_"..playerUserId)
if data then
souls.Value = data['Souls']
coins.Value = data['Coins']
else
souls.Value = 50
coins.Value = 1
end
end
local function onPlayerExit(player)
local player_stats = {}
if player then
for i, stat in pairs(player:WaitForChild("leaderstats"):GetChildren()) do
player_stats[stat.Name] = stat.Value
end
playerData:SetAsync("Player_"..player.UserId, player_stats)
end
end
game.Players.PlayerAdded:Connect(onPlayerJoin)
game.Players.PlayerRemoving:Connect(onPlayerExit)
game:BindToClose(function()
for i, player in pairs(game:GetService("Players"):GetPlayers()) do
onPlayerExit()
end
end)
figured I would do it just cause I had it formatted. Sorry if I wasted your time a bit.
Thanks for the script. Though it doesn’t work. It may be because a different script of mine isn’t working.
basically in the game you kill mobs and the starter weapon is a stick. And when i kill something i get an error message on line 38.
Players.trueblockhead101.Backpack.Stick.Slash:38: attempt to index nil with ‘FindFirstChild’
Part that is giving an error message:
local humanOther = partOther.Parent:FindFirstChild("Humanoid")
Full Script:
local tool = script.Parent
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local InputService = game:GetService("UserInputService")
local InputType = Enum.UserInputType
local animation = nil
local slashAnimation = nil
tool.Equipped:Connect(function()
animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://7132227504"
slashAnimation = humanoid:LoadAnimation(animation)
end)
tool.Unequipped:Connect(function()
animation:Destroy()
slashAnimation = nil
end)
local debounce = false
InputService.InputBegan:Connect(function(input, processed)
if input.UserInputType == InputType.MouseButton1 and slashAnimation and not processed then
if debounce == false then
debounce = true
slashAnimation:Play()
local Connection
local tool = script.Parent
local function onTouch(partOther)
local humanOther = partOther.Parent:FindFirstChild("Humanoid")
if not humanOther then return end
if humanOther.Parent == tool then return end
humanOther:TakeDamage(5)
if humanOther.Health <= 0 then
player.leaderstats.Souls.Value = player.leaderstats.Souls.Value + 1
humanOther.Parent:Destroy()
end
end
Connection = tool:WaitForChild("Handle").Touched:Connect(onTouch)
slashAnimation.Stopped:Wait()
debounce = false
Connection:Disconnect()
wait(.2)
debounce = false
end
end
end)
you are not passing along a value.
Give me a second to look at my sword script
no problem
Alright, first off you have a debounce which is really good.
But the issue lies in the Connection = tool:WaitForChild(“Handle”).Touched:Connect(onTouch)
In my script I have it coded differently but I see how this would work.