How do I put these 2 scripts together and make it work properly?

Basically I want to combine both of these scripts below and make it one script but make it work every single time, and not have it malfunction or not work randomly!

leaderstats save script:

local dataStoreService = game:GetService("DataStoreService")
local DataStore = dataStoreService:GetDataStore("Data")

game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder", player)
	leaderstats.Name = "leaderstats"	
	
	local Pumpkins = Instance.new("IntValue", leaderstats)
	Pumpkins.Name = "Pumpkins"
	
	local Level = Instance.new("IntValue", leaderstats)
	Level.Name = "Level"
	
	local Xp = Instance.new("IntValue", player)
	Xp.Name = "Xp"
	
	local MaxXp = Instance.new("IntValue", player)
	MaxXp.Name = "Max"
	MaxXp.Value = 5
	
	local PetTokens = Instance.new("IntValue", leaderstats)
	PetTokens.Name = "PetTokens"
	
	local pumpkinData
	local levelData
	local xpData
	local MaxXpData
	local PetTokenData
	
	local s, e = pcall(function()
		pumpkinData = DataStore:GetAsync(player.UserId.."-Pumpkins") or 0
		levelData = DataStore:GetAsync(player.UserId.."-Level") or 0
		xpData = DataStore:GetAsync(player.UserId.."-Xp") or 0
		MaxXpData = DataStore:GetAsync(player.UserId.."-Max") or 5
		PetTokenData = DataStore:GetAsync(player.UserId.."-PetTokens") or 0
	end)
	
	if s then
		Pumpkins.Value = pumpkinData
		Level.Value = levelData
		Xp.Value = xpData
		MaxXp.Value = MaxXpData
		PetTokens.Value = PetTokenData
	else
		game:GetService("TestService"):Error(e)  --if not success then we error it to the console
	end
	
end)

game.Players.PlayerRemoving:Connect(function(player)
	local s, e = pcall(function()
		DataStore:SetAsync(player.UserId.."-Pumpkins", player.leaderstats.Pumpkins.Value)
		DataStore:SetAsync(player.UserId.."-Level", player.leaderstats.Level.Value)
		DataStore:SetAsync(player.UserId.."-Xp", player.Xp.Value)
		DataStore:SetAsync(player.UserId.."-Max", player.Max.Value)
		DataStore:SetAsync(player.UserId.."-PetTokens", player.leaderstats.PetTokens.Value)
	end)
	if not s then game:GetService("TestService"):Error(e) end --if not success then error
end)

Tool Save script:

local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("MyDataStore15") -- This can be changed to whatever you want
local ServerStorage = game:GetService("ServerStorage")

local function saveData(player) -- The functions that saves data

	local tableToSave = {
		player.BashHammer2.Value; -- First value from the table
		player.BashHammer3.Value; -- Second value from the table
		player.BashHammer4.Value

	}

	local success, err = pcall(function()
		dataStore:SetAsync(player.UserId, tableToSave) -- Save the data with the player UserId, and the table we wanna save
	end)

	if success then -- If the data has been saved
		print("Data has been saved!")
	else -- Else if the save failed
		print("Data hasn't been saved!")
		warn(err)  
	end
end
game.Players.PlayerAdded:Connect(function(player) -- When a player joins the game
	player.CharacterAdded:Connect(function(chr)

		-- change name of items to whatever you want, but keep it simple
		local BH2 = Instance.new("BoolValue")
		BH2.Name = "BashHammer2"
		BH2.Value = false
		BH2.Parent = player

		local BH3 = Instance.new("BoolValue")
		BH3.Name = "BashHammer3"
		BH3.Value = false
		BH3.Parent = player

		local BH4 = Instance.new("BoolValue")
		BH4.Name = "BashHammer4"
		BH4.Value = false
		BH4.Parent = player

		local data -- We will define the data here so we can use it later, this data is the table we saved
		local success, err = pcall(function()

			data = dataStore:GetAsync(player.UserId) -- Get the data from the datastore
			-- player starts off with no data
		end)
		if success and data then -- If there were no errors and player loaded the data
			BH2.Value = data[1] 
			BH3.Value = data[2] 
			BH4.Value = data[3]

			if BH2.Value == true then
				local tool = ServerStorage.SavedTools:WaitForChild("BashHammer2") -- change this
				tool:Clone().Parent = player.Backpack
			end
			if BH3.Value == true then
				local tool = ServerStorage.SavedTools:WaitForChild("BashHammer3") -- change this
				tool:Clone().Parent = player.Backpack
			end
			if BH4.Value == true then
				local tool = ServerStorage.SavedTools:WaitForChild("BashHammer4") -- change this
				tool:Clone().Parent = player.Backpack
			end

		else -- The player didn't load in the data, and probably is a new player
			print("The player has no data!") -- The default will be set to 0
			player.BashHammer2.Value = false
			player.BashHammer3.Value = false
			player.BashHammer4.Value = false
		end

		-- check if player added anything into backpack
		local equippedTools = {};

		player.Backpack.ChildAdded:Connect(function(child)
			if (child:IsA("Tool")) then
				if (not equippedTools[child.Name]) then
					equippedTools[child.Name] = true;
					local bool = player:WaitForChild(child.Name)
					bool.Value = true					
				end
			end
		end)

		player.Backpack.ChildRemoved:Connect(function(child)
			if (child:IsA("Tool")) then
				if (not equippedTools[child.Name]) then
					equippedTools[child.Name] = true;
					local bool = player:WaitForChild(child.Name)
					bool.Value = false					
				end
			end
		end)
	end)
end)



game.Players.PlayerRemoving:Connect(function(player) -- When a player leaves

	local success, err  = pcall(function()
		saveData(player) -- Save the data

	end)

	if success then
		print("Data has been saved")
	else
		print("Data has not been saved!")
	end
end)

game:BindToClose(function() -- When the server shuts down
	for _, player in pairs(game.Players:GetPlayers()) do -- Loop through all the players
		local success, err  = pcall(function()
			saveData(player) -- Save the data
		end)

		if success then
			print("Data has been saved")
		else
			print("Data has not been saved!")
		end
	end
end)

The tool not saving video:

3 Likes

Create a data-saving module so you don’t have to write such code for every script that needs to read or write some data. For example:

Although… probably just use one of the modules out there

local DataStoreS = game:GetService("DataStoreService")

local BASH_HAMMER_1_ITEM_ID = 0 --You should have a unique Item ID for every type of inventory item in your game. DO NOT do it like this, it's just an example.

local PlayerData = {}

local DEFAULT_PLAYER_DATA = {
    Inventory = {
        --Do not use a boolvalue for every item in your game to indicate that a player does/doesn't have said item.
        --Instead, store each player's inventory as a list of items that they *do* have.
        {ItemId = BASH_HAMMER_1_ITEM_ID, Count = 1},
    },
    Stats = {
        Level = 1,
        Xp = 0,
        Pumpkins = 0,
        PetTokens = 0,
    },
    --I have no idea what "Max" is, sorry
}

local playerDataStores = setmetatable({}, {"__mode" = "kv"})
local playerCaches = setmetatable({}, {"__mode" = "kv"})

function isPlayer(value)
    return value and value(player) == "Instance" and value:IsA("Player") and value.Parent == game.Players
end

function assertIsPlayer(value, message)
    assert(isPlayer(value), message)
end

function PlayerData:Get(player: Player, key: string)
    assertIsPlayer(player)
    assert(typeof(key) == "string")

    return playerCaches[player][key]
end

function PlayerData:Set(player: Player, key: string, value: any)
    assertIsPlayer(player)
    assert(typeof(key) == "string")

    playerCaches[player][key] = value
end

function PlayerData:Increment(player: Player, key: string, increment: number)
    assertIsPlayer(player)
    assert(typeof(key) == "string")
    assert(typeof(increment) == "number")

    local playerData = playerCaches[player]
    assert(typeof(playerData[key]) == "number")
    playerData[key] = playerData[key] + increment
end

function PlayerData:SaveAsync(player: Player)
    assertIsPlayer(player)
    
    local playerDataStore = playerDataStores[player]
    local playerData = playerCaches[player]
    
    --TODO: Implement retrying
    --TODO: Implement versioning
    playerDataStore:SetAsync("data", playerData)
end

function getPlayerDataStoreKey(player: Player)
    assertIsPlayer(player)
    return player.UserId
end

function setupPlayer(player: Player)
    assertIsPlayer(player)

    local playerDataStoreKey = getPlayerDataStoreKey(player)
    local playerDataStore = DataStoreS:GetDataStore(player.UserId)
    playerDataStores[player] = playerDataStore
   
    local playerData = playerDataStore:GetAsync("data")
    playerCaches[player] = playerData
    
    --Save-on-leave connection
    local c
    c = game.Players.PlayerRemoving:Connect(function(_player)
        if _player ~= player then return end
        c:Disconnect() --Clean up the connection
        task.spawn(PlayerData.SaveAsync, PlayerData, player)
    end)
    
    --Autosave loop
    task.spawn(function()
        wait(AUTOSAVE_INTERVAL_SECONDS)
        while getIsPlayer(player)
            PlayerData.SaveAsync(player)
            wait(AUTOSAVE_INTERVAL_SECONDS)
        end
    end)
end

for _, player in game.Players:GetPlayers() do
    setupPlayer(player)
end
game.Players.PlayerAdded:Connect(setupPlayer)

return PlayerData
1 Like