local statKey = "Template"
local statValues = {Coins = 0, Kills = 0}
local metaStatTable = {
__newindex = function(a, p)
print(a, p)
return p
end,
}
local statTable = {}
setmetatable(statTable, metaStatTable)
And then I added a function to address the table, adding the stats to it:
local function customStats(player)
if (statTable ~= nil) then
local tableindexkey = statKey .. "_" .. player.UserId
statTable[tableindexkey] = {}
statTable[tableindexkey].data = statValues
return tableindexkey
end
end
And I keep getting this weird error on the line where I assign a data variable to my players stats: ServerScriptService.Sparkz.Main:100: attempt to index nil with ādataā
Not only that but the __newindex function runs as well and printsā¦ So Iām at a loss here I just donāt know what Iām doing wrong at this point. Does anyone know what Iām doing wrong or what Iām missing?
Youāre literally trying to index something that doesnāt exist. statTable[tableindexkey] is a table, and it doesnāt have any keys yet.
EDIT:
I may have misunderstood what youāre trying to do, and what I said doesnāt make any sense, ignore it. Instead of declaring it that way, why not use a table literal? Itās faster, as it automatically allocates the memory for the table when itās declared, and this time it may not error!
@2jammers Iāll try that thanks for the help @Den_vers Idk what you mean I set the tableindexkey to a table. Then i assigned it another table as a variable named data.
Right here you override the behavior of the creation of new table keys. So when you try to add a key (in this case, tableindexkey) it does nothing.
(Also not sure what return p is for, __newindex doesnāt have anything special happen to return values AFAIK)
If you want it to also add the keys in, you need to add a rawset call.
Also, itās no different from saying a.b = c. Itās inserting a key into a dictionary. Actually, preferably you would only use that method if youāre inserting anything into a table. a.b = c should be used for only strings.
Yeah @2jammers that didnāt fix my error still happened. I think maybe he might not understand that thereās different ways to index stuff in a table.
@Den_vers This kind of solved my issue but another errors popping up now in an area where Iām trying to add the coins to the stats.
Error: ServerScriptService.Sparkz.Main:147: ServerScriptService.Sparkz.Main:128: attempt to index nil with ādataā
Hereās the part where I do that:
local indexkey = customStats(player)
while true do
task.wait(1)
statTable[indexkey]["data"].Coins += 1
print(statTable[indexkey]["data"].Coins)
end
I think @majdTRM is right. You should mark him as solution, my system is only working now because youāre not directly indexing the table, only assigning it a value, now. But when you try to index it, it errors because it doesnāt exist.
Doesnāt make much of a difference. Your method is probably faster, because it adds it in the table creation process, and it doesnāt need to look up the keys in the table.
The problem was that overriding __newindex made it so that adding keys did nothing.
@majdTRM This helped I actually didnāt do any formatting wrong. Do you know why it only runs once though? Isnāt newIndex supposed to run every time something is indexed? Or am I supposed to use a different metamethod for that?
__newindex āfiresā whenever a new index is inserted into a table. The only reason my system didnāt error is because I created the table and inserted a value into that same table at the same time. Therefore not needing to index nil.
Well Iām using __newindex because I tried __index but it doesnāt really fire when Iām adding an index or just changing one. Iām looking for a metamethod that will fire whenever I need to update a value in the table. The reason Iām trying to find something like this is so I can update my leaderboard stats at ease for my framework Iām working on.
Ahh that is a little bit more complicated. See, __newindex only runs when creating new keys, not setting existing ones.
But what you can do is trick it by creating an intermidiary table. Instead of setting the values onto the same table, set it onto another one and add an __index method to return the values correctly.
Here is what I mean:
local statInternal = {}
local metaStatTable = {
__newindex = function(t, k, v)
print(k, v) -- Do other fancy stuff here
statInternal[k] = v
end,
__index = function(t, k)
return statInternal[k]
end,
}
local statTable = {}
setmetatable(statTable, metaStatTable)
But Iām not sure about setting values to nil (EDIT: Thankfully it does)
Iād give that a try but honestly I thought itād be simpler than that. Iām still a beginner at metatables so I think Iāll just use the __call metamethod on the table which will fire refreshing the leaderboard whenever a values changed. And I can just check the name of the parameter in the __call metamethod to be able to determine if the stat is inside of the players leaderstats.
Unfortunately for you, Luaās metatables are very rudimentary. Which means that yes, the best solution to the problem has to get a little dirty and involved. Alas, there is no __indexset metamethod` (although, if you find it of value, you could try creating an RFC @ Roblox/Luau GitHub. But I donāt see a problem with the common solution to the problem. I donāt see it done any different way elsewhere.
Not sure how this will help but if you seem to know what you are doing, go ahead.