How can I implement this into my scripts?

Hi! I want to know how I can implement this idea into my scripts to save a player’s inventory:

I want to Create an initially empty table that fills with a bunch of strings each representing an item.
(I want to try to use a table, as then I will not have to create a value in the script every time I make a new item. There will be lots of items in the game, so I was thinking I could just have the item name be added to the table when unlocked.)
[ITEMS ARE SIMPLE: JUST A BUNCH OF SWORDS YOU CAN BUY. I only need the NAME of the sword saved to the table.]

I need help implimenting this into my current code. Thanks!

Current Code: (I use Suphi’s datastore module)
Script 1: “DataSaving”
image

local datastoremodule = require(game.ServerStorage.DataStoreModule)

local template = {
	--all my in game values are here for data saving. Deleted them cause they dont rly matter
	
	
	
	
}



local function StateChanged(state, datastore)
	while datastore.State == false do 
		if datastore:Open(template) ~= "Success" then task.wait(6) end 
	end
end






game.Players.PlayerAdded:Connect(function(player)
	local datastore = datastoremodule.new("Player", player.UserId)
	datastore.StateChanged:Connect(StateChanged)
	StateChanged(datastore.State, datastore)	
	
end)

game.Players.PlayerRemoving:Connect(function(player)
	local datastore = datastoremodule.find("Player", player.UserId)
	if datastore ~= nil then datastore:Destroy() end
end)

Script 2: “Stats and Values”
image

local datastoremodule = require(game.ServerStorage.DataStoreModule)

local keys = {--values from first script}

local keys2 = {--some other values from first script. (i separated them for game reasons)}

--ADD THE NAME OF A NEW CHARACTER TO KEYS  LIST THEN ALSO UNDER PLAYERADDED
local function StateChanged(state, datastore)
	if state ~= true then return end
	for index, name in keys do
		datastore.PLRSTATSS[name].Value = datastore.Value[name]
		
	end
	for index, name in keys2 do
		datastore.PLRCARDSS[name].Value = datastore.Value[name]
	end
	
	
	
end


game.Players.PlayerAdded:Connect(function(player) 
	local folder = Instance.new("Folder") 
	folder.Name = "PLRSTATSS"
	folder.Parent = player
	
	-------------------------------------------------------------------------------------------
	

	
	local tokens = Instance.new("IntValue")
	tokens.Name = "Tokens"
	tokens.Parent = folder
--just an example of how for every key in "Keys" theres a value under plrstats and plrcards

	
	local cardfolder = Instance.new("Folder") 
	cardfolder.Name = "PLRCARDSS"
	cardfolder.Parent = player
	
	
	local myc = Instance.new("StringValue") 
	myc.Name = "MyCard1"
	myc.Parent = cardfolder

	

	
------------------------------------------------------------------------------------
	local datastore = datastoremodule.new("Player", player.UserId)
	datastore.PLRSTATSS = folder
	datastore.PLRCARDSS = cardfolder
	datastore.StateChanged:Connect(StateChanged)
end)

Other scripts (my method used for whenever I want to update a value. (eg. a player unlocks something)

dsmodule = require(game.ServerStorage.DataStoreModule)

local plr = "(However I end up getting the Player Instance)"

		local data = dsmodule.find("Player", plr.UserId)
		if data == nil then return end
		if data.State ~= true then return end

		data.Value.Exp += 100
		data.PLRSTATSS.Exp.Value = data.Value.Exp

Alright, From what I’m understanding of saving a player inventory, which might have multiple data under it?

I would recommend OOP (object-oriented programming) If you use this, you will be able to add an object to a table, and if it’s sorted with ID, you could add data with an O(1) time complexity (which, if you don’t know, is really good and will take one time).

Here’s a basic rundown:

  • Adding an item → Super fast! (Takes the same amount of time no matter how many items you have—O(1)).
  • Finding an item by ID → Also very fast (O(1)), because dictionaries let you look up items instantly. If you’re using a sorted list instead of a dictionary, you can use Binary Search (O(log n)), which is faster than checking every item one by one (O(n)).
  • Deleting an item → If using a dictionary, deleting is also O(1).

Of course you want efficiency. I did pull out terms you might not know, but the terms just mean speed, and If you know basic graphs, then you will understand it well; there are enough resources out there, and this is just Data Strucutres.

Lua is unique for its dictionaries and is amazing to have a high speed already, so unlike other programming languages having set-size arrays. (Don’t quote me on that, I don’t know if I’m right.)

Lastly, I’m not a professional, so of course take the information and research, and this is just my understanding.

If your just a beginner, then use tables (dictionaries) to store your data so you will have a mutli array data format, and you can do that too, like:

local table = {
[ToolName] = {Amt = 1, Name = "Tool", itemDesc = "Im a Tool"}, 
[ToolName2] = {Amt = 12, Name = "Tool2", itemDesc = "Im a Tool2"},
}

-- Save it to datastore by doing JSONEncode.
3 Likes

hi @nebrska0

Here is something:

:warning: Warning!,I never tested script :warning:

Server Script:

When player joins,Folder named Inventory is created in player’s instance and requires module

local Players = game:GetService("Players")

local Module = require(script:FindFirstChild("Module"))

Players.PlayerAdded:Connect(function(plr)
	local Inventory = Instance.new("Folder")
	Inventory.Name = "Inventory"
	Inventory.Parent = plr
	Module.LoadInventory(Inventory,plr)
end)

Players.PlayerRemoving:Connect(function(plr)
	local Inventory = plr:FindFirstChild("Inventory")
	Module.SaveInventory(Inventory,plr)
end)

Module Script:
Function module.LoadInventory(Folder,plr) loads table that would look like

{
Tool1 = 6,
Tool2 = 10,
}

And create IntValues based on content of table

function module.SaveInventory gets all children of original folder and gets data and saves in DataStore.

local DataStoreService = game:GetService("DataStoreService")

local InventoryDataStore = DataStoreService:GetDataStore("Inventory_DataStore")

local module = {}
local SuccessfullyLoaded = {}

function module.LoadInventory(InventoryFolder,plr:Player)
	local Success,Data = pcall(function()
		return InventoryDataStore:GetAsync(plr.Name.."__"..plr.UserId)
	end)
	
	if Success then
		
		if Data then
			for Name,Number in pairs(Data) do
				local NewValue = Instance.new("IntValue")
				NewValue.Value = Number
				NewValue.Name = Name
				NewValue.Parent = InventoryFolder
			end
		end
		
		SuccessfullyLoaded[plr] = true
	else
		plr:Kick("Failed to load inventory")
	end
	
end

function module.SaveInventory(InventoryFolder:Folder,plr:Player)
	
	if SuccessfullyLoaded[plr] then
		local Data = {}
		
		for _,IntValue in pairs(InventoryFolder:GetChildren()) do
			if IntValue:IsA("IntValue") then
				Data[IntValue.Name] = IntValue.Value
			end
		end
		
		local Success,ErrorMsg = pcall(function()
			InventoryDataStore:SetAsync(plr.Name.."__"..plr.UserId,Data)
		end)
	end
end

return module

ServerScriptService
image

Notes:

  1. Every stat need to have specific name,not same
  2. My Scripts on default will save nothing because i didn’t provide script that adds IntValue in folder you can just add new instance using
    local NewItem = Instance.new("IntValue") NewItem.Parent = Inventory
  3. It must be IntValue adding in folder
  4. I havent provided Incrementing system so you need to do by yourself!
2 Likes

Method 1 doesn’t make sense to me. Don’t boolvalues just store true or false?

Method 2 is how you wanna go about it. You can store the IDs of items as strings. And depending on your case, you may need to store other properties, like the quantity of a particular item the player has, metadata for the item, and whatnot. The schema all depends on what you’re storing.

2 Likes

So the thing is, I am trying to implement method 2 into my current code which I can drop here in a second. There will be no quantity, the only thing that makes items different would be type. (Melee, ranged, etc.) also rarity. Just need help with implementing the new code

I know how to do this, and was going to as a backup if I end up not being able to figure out the table method. My current save data already has a folder under the player instance with boolValues representing other unlockables in game. Would making more reduce performance?

added my code to original post

You don’t need JSONEncode for datastores anymore by the way, atleast I didn’t need it last time I tried my inventory system.

1 Like

Generally, you want to encode the item as a table with as little data as possible, i.e. the minimum needed to fully define it, and quantity. Then, encode the table as a JSON blob with HttpService and store it to a datastore.

If your items are from a simple, finite set that you define, your minimal save data may be as simple as a dictionary of item Ids and quanity. But, if your data includes things like unique items with loot-rolled stats, or user-created items, etc… your tables can easily get more complex. Still, it’s usually simplest to try to store each item as a dictionary table, and use the JSONEncode to validate that the size is within datastore limits and that all data types are valid to store.

Got it, my inventory items are not at all complex, I just want to know how to implement a table within my “template” table in my DataSaving script. I also only need simple strings saved in the table

I already have the datastore stuff situated, just need to know how to implement my idea!

Item descriptions and all are just in a folder in replicatedstorage. To show them in the inverntory I can loop through the player’s table and search for the item name in the rep storage folder. I only need strings in the table guys

This is how I would personally handle Inventory. I like this approach because each item is represented as a number rather than a string. In addition, you could have a ModuleScript that could just have a bunch of these Items and have a function that returns either all of them, or a certain one if you pass an id (number)

--!strict
type InventoryElement = {
	id: number,
	amount: number
}

type ItemElement = {
	{
		name: string,
		description: string
	}
}

local InventoryDataStruct = {
	{
		id = 1,
		amount = 1
	}
} :: {InventoryElement}

local ItemStruct = {
	{
		name = "nebrska0's Sword",
		description = "A sword once held by the almight nebrska0"
	}
} :: ItemElement

So could I do this if i wanted to use my own scripts?

(DataSaving)

local template = {
	--all my in game values are here for data saving. Deleted them cause they dont rly matter
	
	InventoryItems = {}
	
	
}

(When updating a table)

tdsmodule = require(game.ServerStorage.DataStoreModule)

local plr = "(However I end up getting the Player Instance)"

		local data = dsmodule.find("Player", plr.UserId)
		if data == nil then return end
		if data.State ~= true then return end

		table.insert(data.InventoryItems , "TestItem")

I get an error when i try to update the table

No, you would be doing this if you want to to insert an item into your Inventory

table.insert(data.InventoryItems, {
	id = 1,
	amount = 1
})

Also, I would have a function that checks if a player already has an item in their inventory by comparing its id and using table.find()


getting an error
also, don’t need any other info other than the item name which is a string

Nevermind guys I’'m reading the forum post on Suphi’s datastore module to help me. Thank you all for the help and I apologize if I wasted anybody’s time.

1 Like

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