How should I store data in a table/module while using metatables?

Usually I store data in folders and values under the player instance but I know that really isn’t a good practice since it’s outdated an unnecessary. I was thinking of storing data in a table/module that can be accessed on the server and sent to the client via remotes when necessary, and I was going to use the __index metamethod on a default data table so that if I were to add a new stat, I could access the default values even though they’re not saved in the player’s table.
However, to my knowledge __index will just refer to the default table and not actually add the value into the player’s table, so when it comes time to save the data and access it again, it would just give the default value.
Is there a better way to store and handle datastores than this? Or is there a way to add a new value into the table when __index fires?

I resolved my issue! I didn’t know you could create a function in the index method and thought you could only add a default table. :sweat_smile:

My little test code if you’re interested:

local dss = game:GetService('DataStoreService')
local ds = dss:GetDataStore('TestStore')
--//
local playerdata
playerdata = ds:GetAsync('testkey1') or {pie = "apple", cake = "vanilla"}
--//
print(playerdata, playerdata.breakfast)
--//
local defaultdata = {pie = 'apple', cake = 'vanilla', icecream = 'chocolate', breakfast = 'bagel'}
--//
local metatable_ = setmetatable(playerdata, {__index = function(playerdatatable, attemptedindex)
	playerdatatable[attemptedindex] = defaultdata[attemptedindex]
	return playerdata[attemptedindex]
end,})
--//
print(playerdata, playerdata.breakfast)
--//
ds:SetAsync('testkey1', playerdata)
1 Like