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)
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
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
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
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