How to save item like pets , trails , tools if player purchased it

how to save item like pets , trails , tools if player purchased it

2 Likes

Through DataStores. I’d recommend reading up on them, and then putting your data in a dictionary and saving that to the DataStore.

4 Likes

i just see data store can only store value cant store an object

You cannot store objects to datastores, You would have to substitute the object for something like a string in a table and save that.

I recently created a module for this exact purpose! I would gladly post the whole thing here if you would like to see it.

This module works by creating sub-tables for each type of item you want to save such as Pets, Trails or Tools. It works with anything really. In each sub-table it adds strings that represent the objects you want to save.

It would look kinda like this.
Data → Player_Key → SubTable → String

To save data use the UpdateValue function. Pass the player you wish to save data to, the sub-table you want to save the data in and the string to represent the object you wish to save.

To retrieve data you simply use the CheckInTable function. Pass the player you wish to check, the sub-table you want to check in and the string name you want to check for. If the string exists the function will return true otherwise it will return false.

Module Script

--Make sure to add a new blank SubTable below line 46 every time you add a new catagory

local ItemSaveManager = {}

local DataStore = game:GetService("DataStoreService")
local playerData = DataStore:GetDataStore("ItemSaveSystem")

local Players = game:GetService("Players")

local AUTOSAVE_INTERVAL = 120

local DataTable = {}

function ItemSaveManager:UpdateValue(player, subTable, value)
    local playerUserId = "Player_" .. player.UserId	

    table.insert(DataTable[playerUserId][subTable], value)

end

function ItemSaveManager:CheckInTable(player, subTable, value)
    local playerUserId = "Player_" .. player.UserId
    local sendBack = false
    for _, v in pairs(DataTable[playerUserId][subTable]) do
        if v == value then
	        sendBack = true
        end
    end
    return sendBack
end

Players.PlayerAdded:connect(function(player)
    local playerUserId = "Player_" .. player.UserId

    local success, data = pcall(function()
        return playerData:GetAsync(playerUserId)
    end)
    if success then
        if data then
            DataTable[playerUserId] = data
        
        else
            DataTable[playerUserId] = {}

            DataTable[playerUserId]["Pets"] = {} --Here are the sub-tables. 
            DataTable[playerUserId]["Trails"] = {} --you must create one for every type of object you wish to save

            playerData:SetAsync(playerUserId, DataTable)        
        end
    else
        warn("Cannot acces data store for player:" .. player.UserId)
    end
end)

local function savePlayerData(playerUserId)
    if DataTable[playerUserId] then
	    local success, err = pcall(function()
	        playerData:SetAsync(playerUserId, DataTable[playerUserId])
	    end)
	    if not success then
		    warn("Cannot save data for player!")
	    end
    end
end

local function saveOnExit(player)
    local playerUserId = "Player_" .. player.UserId
    savePlayerData(playerUserId)
    print(player.name .. "s data saved")
end

local function autoSave()
    while wait(AUTOSAVE_INTERVAL) do
	    for playerUserId, data in pairs(DataTable) do
		    savePlayerData(playerUserId)
	    end
	    print("Auto Saved")
    end
end

spawn(autoSave)

game.Players.PlayerRemoving:Connect(saveOnExit)

return ItemSaveManager

This module is fairly basic as there is no way to remove data as of right now and I have not created a function to return and entire sub-table (this would not be to hard to do however)

Here is an example of how to save data with this module. Remember this module can only be required by a script on the server. If a local script needs to save data it must use a RemoteEvent.
like the example shows.

Local Script Example

button.MouseButton1Click:Connect(function()
    purchasePetEvent:FireServer(player, cost, petName)
end)

Save the data from above.
Server Script Example

local function onPurchasePetEvent(player, cost, petName)
    if player.leaderstats.Cash.Value >= tonumber(cost) then --Make sure player can afford the purchase
        player.leaderstats.Cash.Value = player.leaderstats.Cash.Value - tonumber(cost) --subtract the cost of the purchase
        ItemSaveManager:UpdateValue(player, "Pets" , petName)  --Save data (petName) for player in "Pets" sub-table 
        print("Purchase done!")
    end
end

purchasePet.OnServerEvent:Connect(onPurchasePetEvent)

Example of checking if a player has a specific item.

game.Players.PlayerAdded:Connect(function(player)
    if ItemSaveManager:CheckInTable(player, "Pets", "Dog") then
        print(player.. " has dog")
    end
end)

I hope this helps you and others understand how to save “Objects” using DataStores. You can copy the module to use if you want but the examples are not meant to be copied as I created them here and they are incomplete. Good Luck!

10 Likes

You need to convert the item from an Instance into a Lua table. Then save the Lua table

is it able to make two data save script in one game?

Assuming you’re a newcomer to LUA, and I myself am not a “professional” at all, nor is anyone really, you can always learn new methods when it comes to scripting! DataStores for Models, Tools, Hats, Armours, Trails, etc, are USUALLY saved with things called BooleanValues or BoolValues. And saving them really isn’t as difficult a task as some may believe.

The post above, regarding the DataStore(DS) System that that programmer created is an excellent source, but if you’re new, it can/could be over complicated. I will provide you with a link below of a DevForum post in which I’ve found out to be extremely helpful when I was learning the new way of tool persistence or DataStoring tools.

This is the Tools Link, for saving TOOLS ONLY

Secondly, DataStoring values, boolean values, need to be done via a Table.

local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local BoolTestDataStore = DataStoreService:GetDataStore("emp44")

local data = {
	--// Tools \\--
	["Sword"] = false,

	--// Trails \\--
	["FireTrail"] = false,

	--// Pets \\--
	["Puffle"] = false,
-- etc
}

Players.PlayerAdded:Connect(function(Player)
	local BoolDataStore = nil
	
	local bools = Instance.new("Folder")
	bools.Name = "Bools"
	bools.Parent = Player
	
	for name, value in pairs(data) do
		local new = Instance.new("BoolValue")
		new.Name = name
		new.Value = value
		new.Parent = bools
	end
	
	local s, e = pcall(function()
		BoolDataStore = BoolTestDataStore:GetAsync("uid-" .. Player.UserId)
	end)
	
	if s then
		print("Getting Bool Data For: " .. Player.Name)
		if BoolDataStore then
			for name, value in pairs(BoolDataStore) do
				Player.Bools[name].Value = value
			end
			print("Bool Data Loaded For: " .. Player.Name)
		else
			print("Created New Bool Data For: " .. Player.Name)
		end
	else 
		warn("Error Getting Bool Data For: " .. Player.Name)
	end
end)

Players.PlayerRemoving:Connect(function(Player)
	local BoolDataStore = {}
	
	for name, value in pairs(Player.Bools:GetChildren()) do
		BoolDataStore[value.Name] = value.Value
	end
	
	local success = pcall(BoolTestDataStore.SetAsync, BoolTestDataStore, "uid-" .. Player.UserId, BoolDataStore)
	
	if success then
		print("Successfully Saved Bool Data For: " .. Player.Name)
	end
end)

What I have provided you with, is an example of a way I datastore my boolean values. This way can be found, online, as there’s multiple different ways to do this.
In order to communicate this with a server, you need to have a RemoteEvent inside of a shop gui (assuming this is how you’re doing it), which communicates with this RemoteEvent which fires(LocalScript inside the Button in the UI), then a ServerScript in ServerScriptService which then communicates with the DataStore, example;

game.ReplicatedStorage.CharStoreRemote.OnServerEvent:Connect(function(player,char,price)
	player.Bools:FindFirstChild(char).Value = true
	player.stats.Bloxcoins.Value = player.stats.Bloxcoins.Value - price
end)

Above is a ServerScript which communicates with the DataStore Script, after the UI Button has been pressed, and the remote event fires.

If I was unclear, or you need deeper explanation, please contact me via here, or discord, BryanFehr#3070. Hopefully I could be of service for you, and everyone else asking the same questions.

NOTE This script provided is for educational/learning purposes only!! This is in NO WAY a “given” or “free” script, and is for YOUR LEARNING PURPOSE ONLY.

4 Likes

If you want to save more than one group of objects, like Pets, Trails etc. Just make a new sub table in the module script.

Add more here. this comes from inside the PlayerAdded function

    else
        DataTable[playerUserId] = {}

        DataTable[playerUserId]["Pets"] = {} --Here are the sub-tables. 
        DataTable[playerUserId]["Trails"] = {} --you must create one for every type of object you wish to save
        --add more sub-tables here

        playerData:SetAsync(playerUserId, DataTable)        
    end

Also @BryanFehr 's example could be use full for leaning but if you expand your range of data his example could get very messy. While I did say you can copy the module I provided, I would recommend learning about tables and DataStores and maybe making your own module so you learn how to do this type of thing. I provided my scripts as a means to getting you and your game started but understanding the logic will really help you out!

If you have more questions let me know.

2 Likes

My example requires you to know what you doing to expand, but, is a good learning example for newcomers. Of course, if you’re just looking for a pastebin, and know nothing about scripting, no datastore example will work at all, because you need to have at least a baseline of knowledge about it.

Your example is clean though, nice work. I simply posted due to the fact author seems new, and my example works well, and is easy to follow/edit. Especially for new comers.

1 Like

I agree entirely. Perhaps my example is a bit to deep but between the two of our examples @XxAwesomeDabxX should be able to get something that will work for him.

1 Like