How to Edit Table Data Within a DataStore? (Not Associated with leaderstats)

Hey,

I’m trying to set up essentially an inventory system within my game, made out of a multi-dimensional table that is saved/loaded when the player leaves/joins. I have managed to get it to successfully save, however, I have stumbled upon an obstacle that I’m not sure how to solve, and it doesn’t appear like there is a great answer on the web/forum.
The script handling the DataStore is associated with a Module, and one of the module’s functions is to check if a ‘stat’ is present within the player’s ‘inventory’, and if it is, add 1 to its value. If it does not exist, it will add the item into the player’s inventory, and then add 1. The problem is that table.insert does not seem to be working. Currently, I am inserting the new ‘item’ into the save data, as shown below:

function dataMod.CollectMatData(player, name) --name is the name of the value being checked if it exists or not
	local data = DS:GetAsync(player.UserId) --DS is the DataStoreService:GetDataStore(key)
	if not data[name] then
		local newVal = table.insert(data.Materials,name) --data is the loaded save data table
		newVal = 0
		print("No Data Detected For Item '"..name.."'. Creating Data..")
		print(data)
	end
end

I’m not sure how to format the new value being inserted anyway, since the value would look like:

["Value"] = 1 --Unsure how to format brackets, string, and value all at once

If you have any suggestions, please let me know!
Thanks,
-Ro :slight_smile:

1 Like

I’m not sure if I understand 100% what you’re looking for but I think you’re looking to do something like,

if not data then
    data[name] = 0
else
    data[name] += 1
end

-- you could also shorten it by doing something like this which is more idiosyncratic
data[name] = if data[name] then data[name] + 1 else 0

-- or
data[name] = data[name] and data[name] + 1 or 0

In that case data[whatever name is equal to] will be 0 if that entry doesn’t exist, if it does exist then it’ll be incremented by 1.

So suppose ‘name’ is equal to the string "Value", data would now look like:

data = {
    ['Value'] = 0; -- or 1, or 2 etc
}
1 Like

Would that code create the value inside of the table? Or is it working more as a variable?
How would I add this to the table (Currently, I have tried table.insert, but it did not work.)

Here is a little more elaboration:
Here’s kind of what my inventory looks like right now:

playerData = {
				["Stamina"] = 100,
				["Level"] = 1,
				["Combat"] = {
					["Attack"] = 10,
					["Defence"] = 10,
					["CriticalChance"] = 5,
					["CriticalBonus"] = 1.5
				},
				["Weapons"] = {
					["Default"] = {
						["Attack"] = 10,
					}	
				},
				["Materials"] = {}
			}

I’m wanting to add another [“These”] into the table, but it is not being added to the save table. (The problem isn’t the DataStore it is just not being added in general.

Yes it would create the value inside of the table.

If you’re working with data stores it’s probably a good idea to just make a single get call, then cache the data one time when the player joins and append to the cached data instead of getting the value from the data store. If you mutate the table, it won’t actually change inside of the data store until you next call SetAsync/UpdateAsync, but it will be mutated inside of the cache and the next time that cache is indexed it will return the updated value.

So suppose it’s laid out as so:

local dataModule = {}

local data = {}

function dataModule.get(player)
    data[player] = dataStore:GetAsync(player.UserId) or {}

    if not data[player]['someValue'] then -- if the value doesn't exist in the player's data
        data[player]['someValue'] = true
    end
end

function dataModule.append(player, index, value) -- write to their data which will mutate the actual table inside of data[player]
    local data = assert(data[player], 'player\'s data hasn\'t loaded')
    
    data[player][index] = value
end

function dataModule.get(player, index)
    return data[player][index]
end

Anyway the reason that is relevant in your case is because when you go to save, you need to index it through data[player] in order to get the updated value (data[player]), that updated value (table) will contain whichever new values were appended to it earlier. This concept is called mutability; the object can be mutated and it will replicate to any other references. It isn’t a copy of the table but an actual reference to the table itself.

t = {}
t2 = t

t.a = true

print(t2.a) --> true
t2.a = nil
print(t.a) --> nil
1 Like

I think I understand now. Thanks for helping me out! I will reply again if I need to. :slight_smile:

1 Like

It works! Thank you!

Relevant Forum Post:
Click

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