Backpack and equipped tool in player character save when he leave or die

Hello,

I trying to save all player tools from player backpack and from character because when player equip tool, then tool is not in backpack.

Sorry for my english if it is bad :smiley:

Here is my script to save data, everything works fine but when player hard close game with cross or when i close game in studio with stop button, then equipped tool from player character will not save.

I think its because it is too fast to save data? idk please help.

and here is video
YouTube Video

-- Importujeme službu DataStoreService
local DataStoreService = game:GetService("DataStoreService")
local toolsDataStore = DataStoreService:GetDataStore("PlayerTools")

-- Funkce pro uložení nástrojů hráče
local function savePlayerTools(player)
	local tools = {}
	local backpack = player:FindFirstChild("Backpack")
	local character = player.Character

	if backpack then
		for _, tool in ipairs(backpack:GetChildren()) do
			if tool:IsA("Tool") then
				table.insert(tools, tool.Name)
			end
		end
	end

	if character then
		for _, tool in ipairs(character:GetChildren()) do
			if tool:IsA("Tool") then
				table.insert(tools, tool.Name)
			end
		end
	end

	toolsDataStore:SetAsync(player.UserId, tools)
	print("data saved", tools)
end

-- Funkce pro načtení nástrojů hráče
local function loadPlayerTools(player)
	local tools = toolsDataStore:GetAsync(player.UserId)
	if tools then
		for _, toolName in ipairs(tools) do
			local tool = game.ReplicatedStorage.Weapons:FindFirstChild(toolName):Clone()
			tool.Parent = player.Backpack
		end
	end
end

-- Event, který se aktivuje, když hráč opustí hru
game.Players.PlayerRemoving:Connect(function(player)
	savePlayerTools(player)
end)

-- Event, který se aktivuje, když se hráč připojí ke hře
game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		loadPlayerTools(player)
	end)
end)

-- Event, který se aktivuje, když hráč zemře
game.Players.PlayerRemoving:Connect(function(player)
	if player.Character then
		savePlayerTools(player)
	end
end)

-- Event, který se aktivuje, když hráč zemře
game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		character:FindFirstChild("Humanoid").Died:Connect(function()
			savePlayerTools(player)
		end)
	end)
end)

-- Function to save tools for all players when the game is closing
local function saveToolsForAllPlayers()
	for _, player in ipairs(game.Players:GetPlayers()) do
		savePlayerTools(player)
	end;
end;

-- Bind to the game close event
game:BindToClose(function()
	saveToolsForAllPlayers()
end);

local function autoSave()
	while true do
		wait(60)  -- Wait for 60 seconds
		saveToolsForAllPlayers()  -- Save tools for all players
	end
end

autoSave()
1 Like

You should use JsonDecode and JsonEncode.
I fixed the code.

-- Importujeme službu DataStoreService
local DataStoreService = game:GetService("DataStoreService")
local toolsDataStore = DataStoreService:GetDataStore("PlayerTools")

-- Funkce pro uložení nástrojů hráče
local function savePlayerTools(player)
	local tools = {}
	local backpack = player:FindFirstChild("Backpack")
	local character = player.Character

	if backpack then
		for _, tool in ipairs(backpack:GetChildren()) do
			if tool:IsA("Tool") then
				table.insert(tools, tool.Name)
			end
		end
	end

	if character then
		for _, tool in ipairs(character:GetChildren()) do
			if tool:IsA("Tool") then
				table.insert(tools, tool.Name)
			end
		end
	end
        tools = game:GetService("HttpService"):JSONEncode(tools)
	toolsDataStore:SetAsync(player.UserId, tools)
	print("data saved", tools)
end

-- Funkce pro načtení nástrojů hráče
local function loadPlayerTools(player)
	local tools = game:GetService("HttpService"):JSONDecode(toolsDataStore:GetAsync(player.UserId))
	if tools then
		for _, toolName in ipairs(tools) do
			local tool = game.ReplicatedStorage.Weapons:FindFirstChild(toolName):Clone()
			tool.Parent = player.Backpack
		end
	end
end

-- Event, který se aktivuje, když hráč opustí hru
game.Players.PlayerRemoving:Connect(function(player)
	savePlayerTools(player)
end)

-- Event, který se aktivuje, když se hráč připojí ke hře
game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		loadPlayerTools(player)
	end)
end)

-- Event, který se aktivuje, když hráč zemře
game.Players.PlayerRemoving:Connect(function(player)
	if player.Character then
		savePlayerTools(player)
	end
end)

-- Event, který se aktivuje, když hráč zemře
game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		character:FindFirstChild("Humanoid").Died:Connect(function()
			savePlayerTools(player)
		end)
	end)
end)

-- Function to save tools for all players when the game is closing
local function saveToolsForAllPlayers()
	for _, player in ipairs(game.Players:GetPlayers()) do
		savePlayerTools(player)
	end;
end;

-- Bind to the game close event
game:BindToClose(function()
	saveToolsForAllPlayers()
end);

local function autoSave()
	while true do
		wait(60)  -- Wait for 60 seconds
		saveToolsForAllPlayers()  -- Save tools for all players
	end
end

autoSave()

Refrence:

1 Like

Still don’t work when player have equipped tool :sweat_smile: just when he leaving game, when he died it works perfectly fine

Okey i finally make it and i want to share it with you.

And i used Promise module script here:
Promise module

Here is module script:

local DataStoreService = game:GetService("DataStoreService")
local Promise = require(script.Parent.Promise)

local ToolsDataStore = DataStoreService:GetDataStore("PlayerTools")

local PlayerDataManager = {}

-- Function to get all tools from a player's backpack and character
local function getPlayerTools(player)
	local tools = {}

	-- Get tools from backpack
	for _, tool in pairs(player.Backpack:GetChildren()) do
		if tool:IsA("Tool") then
			table.insert(tools, tool.Name)
		end
	end

	-- Get tools from character
	if player.Character then
		for _, tool in pairs(player.Character:GetChildren()) do
			if tool:IsA("Tool") then
				table.insert(tools, tool.Name)
			end
		end
	end

	return tools
end

-- Function to save player's tools
function PlayerDataManager.savePlayerTools(player)
	local tools = getPlayerTools(player)
	return Promise.new(function(resolve, reject)
		local success, err = pcall(function()
			ToolsDataStore:SetAsync(player.UserId, tools)
		end)
		if success then
			resolve()
		else
			reject(err)
		end
	end)
end

-- Function to load player's tools
function PlayerDataManager.loadPlayerTools(player)
	return Promise.new(function(resolve, reject)
		local success, tools = pcall(function()
			return ToolsDataStore:GetAsync(player.UserId)
		end)
		if success and tools then
			for _, toolName in pairs(tools) do
				local tool = game.ServerStorage:FindFirstChild(toolName)
				if tool then
					local clonedTool = tool:Clone()
					clonedTool.Parent = player.Backpack
				end
			end
			resolve()
		else
			reject(tools)
		end
	end)
end

return PlayerDataManager

and here is server script:


local ReplicatedStorage = game:GetService("ReplicatedStorage");
local Modules = ReplicatedStorage:WaitForChild("Modules");

local PlayerDataManager = require(Modules.PlayerDataManager)

local AUTOSAVE_INTERVAL = 60
local SAVE_DEBOUNCE_TIME = 1

-- Function to debounce saving
local function createDebouncedSave(player)
	local debounce = false
	return function()
		if debounce then return end
		debounce = true
		wait(SAVE_DEBOUNCE_TIME)
		PlayerDataManager.savePlayerTools(player):catch(function(err)
			warn("Failed to save tools for player " .. player.Name .. ": " .. err)
		end)
		debounce = false
	end
end

-- Function to start autosave
local function startAutosave(player)
	while player.Parent do
		PlayerDataManager.savePlayerTools(player):catch(function(err)
			warn("Failed to save tools for player " .. player.Name .. ": " .. err)
		end)
		wait(AUTOSAVE_INTERVAL)
	end
end

-- Function to handle player respawn
local function onCharacterAdded(character)
	local player = game.Players:GetPlayerFromCharacter(character)
	if player then
		character:WaitForChild("Humanoid").Died:Connect(function()
			PlayerDataManager.savePlayerTools(player):catch(function(err)
				warn("Failed to save tools for player " .. player.Name .. ": " .. err)
			end)
		end)

		-- Load tools into backpack when character respawns
		character:WaitForChild("HumanoidRootPart")
		PlayerDataManager.loadPlayerTools(player):catch(function(err)
			warn("Failed to load tools for player " .. player.Name .. ": " .. err)
		end)
	end
end

-- Player added event
game.Players.PlayerAdded:Connect(function(player)
	PlayerDataManager.loadPlayerTools(player):catch(function(err)
		warn("Failed to load tools for player " .. player.Name .. ": " .. err)
	end)

	-- Debounced save function for the player
	local debouncedSave = createDebouncedSave(player)

	-- Autosave in a separate thread
	spawn(function()
		startAutosave(player)
	end)

	-- Save tools on player removing (leaving the game)
	player.AncestryChanged:Connect(function(_, parent)
		if not parent then
			PlayerDataManager.savePlayerTools(player):catch(function(err)
				warn("Failed to save tools for player " .. player.Name .. ": " .. err)
			end)
		end
	end)

	-- Connect to character added event
	player.CharacterAdded:Connect(onCharacterAdded)

	-- Watch for new tools in the backpack
	player.Backpack.ChildAdded:Connect(function(child)
		if child:IsA("Tool") then
			debouncedSave()
		end
	end)

	-- Watch for tool removal from backpack to handle edge cases
	player.Backpack.ChildRemoved:Connect(function(child)
		if child:IsA("Tool") then
			debouncedSave()
		end
	end)
end)

-- Player removing event (for hard quit)
game.Players.PlayerRemoving:Connect(function(player)
	PlayerDataManager.savePlayerTools(player):catch(function(err)
		warn("Failed to save tools for player " .. player.Name .. ": " .. err)
	end)
end)

-- Save tools when game is shutting down
game:BindToClose(function()
	for _, player in pairs(game.Players:GetPlayers()) do
		PlayerDataManager.savePlayerTools(player):catch(function(err)
			warn("Failed to save tools for player " .. player.Name .. ": " .. err)
		end)
	end
end)

It was hard 2 or 3 days xD

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.