How do i store my inventory system into a data store?

For example, instead of directly adding the button to the DataStore like what you did here:

			if v:IsA("GuiButton") then
				table.insert(v)
			end

You can do something like this:

	if v:IsA("GuiButton") then
		local ButtonTable = {}
		table.insert(ButtonTable, v.Name)
		table.insert(ButtonTable, v.Text)
		--etc.. Instead replace with the properties you need to store inside the table. Store the table inside the DataStore btw.
	end

Hope this helps!

1 Like

Hmmm, oh and i forgot to say, i’m not that good in datastores, like i know just how to store values and that’s it, i even needed to watch a tutorial, so uhhhh, i need to learn more about datastores…

1 Like

Yes, I was like you and I personally hate datastores honestly.
You must also take things like security and multiserver editting cuz you never want to lose player data right?

I recommend instead of you making datastores look into something like a external module (ProfileService, DataStore v2). There are multiple tutorials on this and I use something like this with ProfileService:
image
Look into those and also look into methods of serialization. Just searching it up will bring tons of videos and forums!

I hope this helps!

3 Likes

Wait a second, profile service… HMMM this is interesting

1 Like

Yes, I love this
Its like a 2000 line module service made by another professional developer which handles most of the chaotic things of datastores:

  • Data Loss
  • Multi-Server Editting and Serverlocking
  • Key Versioning
    And more!
1 Like

Look into this link, and also search more videos:

Btw I used videos and forums to help me out, this is a stage of development. Don’t feel bad of using such sources!

2 Likes

Bro… WHAT THE HECK IS THIS:

-- ProfileTemplate table is what empty profiles will default to.
-- Updating the template will not include missing template values
--   in existing player profiles!
local ProfileTemplate = {
    Cash = 0,
    Items = {},
    LogInTimes = 0,
}

----- Loaded Modules -----

local ProfileService = require(game.ServerScriptService.ProfileService)

----- Private Variables -----

local Players = game:GetService("Players")

local ProfileStore = ProfileService.GetProfileStore(
    "PlayerData",
    ProfileTemplate
)

local Profiles = {} -- [player] = profile

----- Private Functions -----

local function GiveCash(profile, amount)
    -- If "Cash" was not defined in the ProfileTemplate at game launch,
    --   you will have to perform the following:
    if profile.Data.Cash == nil then
        profile.Data.Cash = 0
    end
    -- Increment the "Cash" value:
    profile.Data.Cash = profile.Data.Cash + amount
end

local function DoSomethingWithALoadedProfile(player, profile)
    profile.Data.LogInTimes = profile.Data.LogInTimes + 1
    print(player.Name .. " has logged in " .. tostring(profile.Data.LogInTimes)
        .. " time" .. ((profile.Data.LogInTimes > 1) and "s" or ""))
    GiveCash(profile, 100)
    print(player.Name .. " owns " .. tostring(profile.Data.Cash) .. " now!")
end

local function PlayerAdded(player)
    local profile = ProfileStore:LoadProfileAsync("Player_" .. player.UserId)
    if profile ~= nil then
        profile:AddUserId(player.UserId) -- GDPR compliance
        profile:Reconcile() -- Fill in missing variables from ProfileTemplate (optional)
        profile:ListenToRelease(function()
            Profiles[player] = nil
            -- The profile could've been loaded on another Roblox server:
            player:Kick()
        end)
        if player:IsDescendantOf(Players) == true then
            Profiles[player] = profile
            -- A profile has been successfully loaded:
            DoSomethingWithALoadedProfile(player, profile)
        else
            -- Player left before the profile loaded:
            profile:Release()
        end
    else
        -- The profile couldn't be loaded possibly due to other
        --   Roblox servers trying to load this profile at the same time:
        player:Kick() 
    end
end

----- Initialize -----

-- In case Players have joined the server earlier than this script ran:
for _, player in ipairs(Players:GetPlayers()) do
    task.spawn(PlayerAdded, player)
end

----- Connections -----

Players.PlayerAdded:Connect(PlayerAdded)

Players.PlayerRemoving:Connect(function(player)
    local profile = Profiles[player]
    if profile ~= nil then
        profile:Release()
    end
end)

Haha
Use a tutorial here as I cant fully explain this in details. All I know is that these functions go inside of a script called:
image

These functions connect the Profile Service, and it is like the connection hub for profile service.
I recommend you use a vid tho as the documentation tutorials on ProfileService is pretty confusing especially for beginners.
There are TONS of videos out there, so you can use those

2 Likes

Uhhh, ok this is hard, how the heck am i gonna do this inventory datastore, this is more hard than i expected it to be!!!

And for your record of how hard it is, i spent almost 1 FREAKING HOUR TRYING TO FIND A WAY TO DO THIS AND I DIDN’T EVEN STARTED

Oh and i need to leave, i need to take a break from my computer, cya later

1 Like

So first setup the profile service.

[Use a tutorial - Video before reading this tho]
Once you setup that using a video, somewhere you will make a module script along the lines of:
image

This as stated in one of the vids would be where the baseline data would be. Here is a sniplet of mine:

local Template = {}
Template.CurrencyData = {
	Money = 0,
}
Template.LevelingData = {
	Level = 1,
	XP = 0,
	RXP = 1000
}

Template.SettingsData = {
	
}

return Template

Now to access the ProfileStore, there is a script called:
image
This script holds the phyiscal “Profiles” or Player Data for the entire server. To access you must get in the table of profiles inside the Manager:
image
In here, you also add functions such as Client reading (NOT EDITTING) and Write:

	return Manager.Profiles[Player].Data
end

local function RecursiveSearchAndEdit(Table, Index, Value, Set)
	for i,v in pairs(Table) do
		if i == Index then
			print(Table[i])
			if type(Table[i]) == "number" then
				if Set == true then
					Table[i] = Value
				else
					Table[i] += Value
				end
			elseif type(Table[i]) == "boolean" or type(Table[i]) == "string" then
				Table[i] = Value
			end
		end

		if typeof(v) == "table" then
			RecursiveSearchAndEdit(v,Index,Value,Set)
		end
	end
end

function Manager.Write(Player,Index,Value,Set)
	--Profile
	local ClientData = Manager.Profiles[Player].Data
	RecursiveSearchAndEdit(ClientData,Index,Value,Set)
	
	--Physical Value
	for i, Descendant in pairs(ClientsDataFolder:WaitForChild(Player.Name):GetDescendants()) do
		if Descendant.Name == Index then
			if type(Descendant.Value) == "number" then
				if Set == true then
					Descendant.Value = Value
				else
					Descendant.Value += Value
				end
			elseif type(Descendant.Value) == "boolean" or type(Descendant.Value) == "string" then
				Descendant.Value = Value
			end
		end
	end
end

--Connections
ReadDataRemote.OnServerInvoke = function(Player)
	return Manager.Read(Player)
end
1 Like

Ignore some of this code, just focus on the main parts
Cya!

2 Likes

Hello! Instead of storing instances, you could use HTTP Service to do JSONEncode on a table containing information about the item you want to store so that you can store it in Datastore as a string.

For example, if you wanted to store the name of an item and its value, you can do this.

local Item = {
 ["Name"] = "Apple",
 ["Value"] = 1
}

local toStore = game:GetService("HttpService"):JSONEncode(Item)

Then you can store toStore in Datastore.

To get the dictionary again, you can do

local decodedStore = game:GetService("HttpService"):JSONDecode(ItemInDatastore)

Hope this helped!

2 Likes

Even thats actually smart!

Read on HTTP and DSS too
*DSS - DataStoreService

1 Like

Hello!
I see you have already gotten A LOT of help by the previous people, but I just came here to tell my opinion.

So I think in roblox you can’t actually serialize data. Serialization is when you convert an object into plain text. The method we use to save data here isn’t serialization, we just take the main properties and store them in a table.

Like for example, if, let’s say you want to store the position of a part. (Suppose it’s moveable and a player moved it). You would just save the Part.Position or Part.CFrame value. You won’t actually serialize it. And suppose you have a building system, you would then store the BrickColor, CFrame, etc. etc. You get my point. (hopefully)

I’m not writing all the code because i’m lazy but it would be something like this
DISCLAIMER: THIS IS TRASH CODE, DO NOT USE THIS! IT IS ONLY FOR THE PURPOSE OF SHOWING MY POINT.

-- Saving the data
local data = {Part.Position, Part.Color}
Datastore:SetAsync(key, data)

-- Retrieving the data
local data = Datastore:GetAsync(key)
local partPosition = data[1] --It's a table, so we access the data by indexing the table
local partColor = data[2]

Part.Position = partPosition
Part.Color = partColor

So that’s basically it. My code is terrible, it doesn’t use pcalls or BindToClose, heck, it doesn’t even connect to the PlayerAdded or PlayerRemoved functions, but i hope this helps!

1 Like

Question, where do i add this into my line of code?

local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("InventoryDataStore")

local TableToStore = {}
local Data = nil

function SaveData(Player, StoreStuff)
	
end

game.Players.PlayerAdded:Connect(function(Player)
	Player.PlayerGui.InventoryUI.CharacterFrame.CharacterList.Changed:Connect(function()
		for i, v in pairs(Player.PlayerGui.InventoryUI.CharacterFrame.CharacterList:GetChildren()) do
			if v:IsA("GuiButton") then
				local ButtonTable = {}
				table.insert(ButtonTable, v.Name)
				table.insert(ButtonTable, v.Text)
			end
		end
	end)
end)

game.Players.PlayerRemoving:Connect(function(Player)
	
end)

Hello, i’m back, i’m trying to see the other peoples solutions and idk if it’s gonna to work

1 Like

Hey friend, i think i did it, first of all i don’t know if this code will work, second of all, what do i write on the If Success and Data then on the player added function:

local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("InventoryDataStore")

--local TableToStore = {}
local Data = nil

local ToStore = nil

function SaveData(Player)
	local DecodedStore = game:GetService("HttpService"):JSONDecode(ToStore)
	local Success, Err = pcall(function()
		DataStore:SetAsync(Player.UserId, DecodedStore)
	end)
	
	if Success then
		print("Data has been succefully saved!")
	else
		warn(Err)
	end
end

game.Players.PlayerAdded:Connect(function(Player)
	Player.PlayerGui:WaitForChild("InventoryUI").CharacterFrame.CharacterList.Changed:Connect(function()
		for i, v in pairs(Player.PlayerGui.InventoryUI.CharacterFrame.CharacterList:GetChildren()) do
			if v:IsA("GuiButton") then
				local Item = {
					["Name"] = v.Name
				}
				ToStore = game:GetService("HttpService"):JSONEncode(Item)
			end
		end
	end)
	
	local Success, Err = pcall(function()
		Data = DataStore:GetAsync(Player.UserId)
	end)
	
	if Success and Data then
		
	end
end)

game.Players.PlayerRemoving:Connect(function(Player)
	local Success, Err = pcall(function()
		SaveData(Player)
	end)
	
	if Success then
		print("Inventory saved!")
	else
		warn(Err)
	end
end)

Did the tutorial have the pcall?
edt: nvm ur not using profiles

1 Like