How to make tables with attributes?

Well, I want to make tables with the attributes but I honestly don’t know how to do them, or it is even possible to make tables with the attributes, for example:

player:SetAtributte("other")
local other = player:GetAtributte("Other")
print(other)

–Print result:

other
Configurations

WaterQuality = “Low”;

Data

Coins = 0;
Gems = 0;

Or something like that, I think you understand me

1 Like

Like any other table.
Just have the keys/fields represent those attributes.

local attTable = {["Attribute1"] = {}, ["Attribute2"] = {}}

Another example:

local outerTable = {["innerTable"] = {}}

How exactly would this change anything?

You’re probably replying to an outdated edit. If you’re responding with an entire page of text, save yourself the time.

I could be reading this wrong, but do you need this?

Instance:GetAttributes()

I had forgotten to put the SetAttribute before the GetAttribute

Rather than assign a player an attribute, you can use their player instance as a key on a bigger table. For example:

(ModuleScript, this uses OOP)

local PlayerAttributes = {}
PlayerAttributes.__index = PlayerAttributes
local Players = {}

function PlayerAttributes.CreatePlayer(plr)
	local self = {}
	self.__index = PlayerAttributes
	Players[plr] = self

	return self
end

function PlayerAttributes.RemovePlayer(plr)
	Players[plr] = nil
end

function PlayerAttributes.GetPlayerTable(plr)
	return Players[plr]
end

function PlayerAttributes:GetAttribute(attribute)
	if self then
		return self[attribute]
	end
	return nil
end

function PlayerAttributes:SetAttribute(attribute,value)
	if self then
		self[attribute] = value
	end
end

return PlayerAttributes

Then, all you have to do is require it.

local Players = game:GetService("Players")
local PlayerStorage = {}
local PlayerAttributes = require(game:GetService("ServerScriptService"):WaitForChild("PlayerAttributes")) -- wherever the module is

Players.PlayerAdded:Connect(function(plr)
	PlayerStorage[plr] = PlayerAttributes.CreatePlayer(plr)
end)

Players.PlayerRemoving:Connect(function(plr)
	PlayerStorage[plr] = nil
	PlayerAttributes.RemovePlayer(plr)
end)

-- Modify attribute
local PlrTable = PlayerStorage[Players.ExamplePlayer] or PlayerAttributes.GetPlayerTable(plr)
if PlrTable then
	PlrTable:SetAttribute("HigherDamage",true)
	task.wait(10)
	-- Get Attribute
	PlrTable:GetAttribute("HigherDamage")
end

I just threw this together and I don’t have access to studio, so I’m not 100% sure there’s no bugs or if it’s well written. This wouldn’t make too much sense to use since you can directly modify tables anyway, but it works if you really want to use :GetAttribute and :SetAttribute

2 Likes

GetAttributes() just gets every attribute of an instance

{
    Attribute1 = true,
    Attribute2 = Color3.new(1, 1, 1)
}
1 Like

He lets me in the studio, so I’ll try that

I know, I just forgot to put the SetAttribute

1 Like

Make sure to use the edited version, since I just edited my reply

1 Like

I changed the script a bit because as you gave it to me it gave me an error, so now it should work. and yes, it does not give an error, however, it does not give me the attributes

local Players = game:GetService("Players")
local PlayerStorage = {}
local PlayerAttributes = require(script.ModuleScript) -- wherever the module is

Players.PlayerAdded:Connect(function(plr)
	local PlrTable = PlayerStorage[Players:WaitForChild(plr.Name)] or PlayerAttributes.GetPlayerTable(plr)
	if PlrTable then
		PlrTable:SetAttribute("HigherDamage",true)
		task.wait(10)
		-- Get Attribute
		PlrTable:GetAttribute("HigherDamage")
	end
end)

Players.PlayerRemoving:Connect(function(plr)
	PlayerStorage[plr] = nil
	PlayerAttributes.RemovePlayer(plr)
end)

How about you print it? slightly changing the script

local Players = game:GetService("Players")
local PlayerStorage = {}
local PlayerAttributes = require(script.ModuleScript) -- wherever the module is

Players.PlayerAdded:Connect(function(plr)
	local PlrTable = PlayerStorage[plr] or PlayerAttributes.GetPlayerTable(plr)
	if PlrTable then
		PlrTable:SetAttribute("HigherDamage",true)
		task.wait(10)
		-- Get Attribute
		local HigherDamage = PlrTable:GetAttribute("HigherDamage")
		print(HigherDamage)
	end
end)

Players.PlayerRemoving:Connect(function(plr)
	PlayerStorage[plr] = nil
	PlayerAttributes.RemovePlayer(plr)
end)

also, if you can save a table as an attribute, you can use JSONEncode and JSONDecode in it, you save it with JSONEncode and you get it with JSONDecode

Example
local Target =		-- Instance
local Table = {"A", 2}
local Service = game:GetService("HttpService")

local Success, String = pcall(Service.JSONEncode, Service, Table)
if Success and String then
	Target:SetAttribute("HigherDamage", String)
else
	warn(String)
end

in another script

local Target =		-- Same instance
local Attribute = Target:GetAttribute("HigherDamage") or "[]"
local Service = game:GetService("HttpService")

local Success, Table = pcall(Service.JSONDecode, Service, Attribute)
if Success then
	print(Table)
else
	warn(Table)
end

keep in mind that they must be simple tables.

1 Like

Well, I suppose it should work, although it doesn’t give me the print so I suppose the condition is not met.
I thought this would give a solution, but not really:

local Players = game:GetService("Players")
local PlayerStorage = {}
local PlayerAttributes = require(script.ModuleScript) -- wherever the module is

Players.PlayerAdded:Connect(function(plr)
	local PlrTable = PlayerStorage[plr] or PlayerAttributes.GetPlayerTable(plr)
	if not PlrTable then
		repeat wait(0.1)
			PlrTable = PlayerStorage[plr] or PlayerAttributes.GetPlayerTable(plr)
		until PlrTable or (not plr.Parent)
	end
	if PlrTable then
		PlrTable:SetAttribute("HigherDamage",true)
		task.wait(10)
		-- Get Attribute
		local HigherDamage = PlrTable:GetAttribute("HigherDamage")
		print(HigherDamage)
	end
end)

Players.PlayerRemoving:Connect(function(plr)
	PlayerStorage[plr] = nil
	PlayerAttributes.RemovePlayer(plr)
end)

What happened is that OOP was misused, I slightly changed the scripts

Script
local Players = game:GetService("Players")
local PlayerAttributes = require(script.ModuleScript) -- wherever the module is

Players.PlayerAdded:Connect(function(plr)
	local PlrTable = PlayerAttributes.Player(plr)
	PlrTable:SetAttribute("HigherDamage",true)
	task.wait(10)
	
	-- Get Attribute
	local HigherDamage = PlrTable:GetAttribute("HigherDamage")
	print(HigherDamage)
end)

Players.PlayerRemoving:Connect(function(plr)
	PlayerAttributes.Player(plr):Remove()
end)
Module
local PlayerAttributes, Players = {}, {}
PlayerAttributes.__index = PlayerAttributes

function PlayerAttributes.Player(plr)
	--	Get player if exists
	if Players[plr] then
		return Players[plr]
	end

	--	Create
	local Entry = setmetatable({}, PlayerAttributes)
	Entry.Player = plr
	Entry.Attributes = {}
	
	Players[plr] = Entry
	return Entry
end

function PlayerAttributes:Remove()
	Players[self.Player] = nil
end
function PlayerAttributes:GetAttribute(attribute)
	return self.Attributes[attribute]
end

function PlayerAttributes:SetAttribute(attribute, value)
	self.Attributes[attribute] = value
end

return PlayerAttributes
1 Like

Darn. I never was the greatest with OOP. Now that I look at it, I definitely did it badly. I can’t believe I forgot to set the metatable, especially…

Excellent job redoing it, looks much better

2 Likes

You want this?

local function makeAttributeTableForInstance(instance)
  local proxy = newproxy(true)
  local mt = getmetatable(proxy)

  function mt:__index(k)
    return instance:GetAttribute(k) or nil --GetAttribute doesn't return nil
  end

  function mt:__newindex(k, v)
    instance:SetAttribute(k, v)
  end
 
  return proxy
end

local PartAttributes = makeAttributeTableForInstance(workspace.Part)
PartAttributes.foo = "bar"
print(PartAttributes.foo, workspace.Part:GetAttribute("foo"))

If what you want is to add GetAttribute and SetAttribute to tables themselves, it’s kinda pointless because you can just directly index table values (or set them) like this

local t = {}
t.foo = 1 --same as SetAttribute
print(t.bar) --same as GetAttribute
1 Like

Use folders as table and put attributes there
Like this
local stats = StatsFolder
stats:SetAttribute(“Coin”,5)