I’m trying to create a status effects module but I’m currently having issues with setting the metatable of players[player] (table) to the players table/module. Using setmetatable does NOT give the player table the status effects table.
–! Code that manages the players and their respective statusEffect tables.
--\\ Functions : Players //--
game.Players.PlayerAdded:Connect(function(player)
players[player] = {} setmetatable(players[player], players)
print(players[player])
task.spawn(function()
while task.wait(.25) do
print(players[player])
end
end)
end)
game.Players.PlayerRemoving:Connect(function(player)
if players[player] then
players[player] = nil
end
end)
well first off it might be easier to do this if its a blank table by default
players[player] = setmetatable({}, players)
Additionally, the dictionary you have in the players table doesn’t contain any meta methods so it has no meta table to copy
as for a fix this should work:
make a new function at the top of the script:
local function deepCopy(original)
if type(original) == "table" then
local copy = {}
for key, value in pairs(original) do
copy[key] = deepCopy(value)
end
return copy
else
return original
end
end
If I may ask, why do you want this to be a metastable? You could easily add the table like this;
--\\ Functions : Players //--
local players = {}
game.Players.PlayerAdded:Connect(function(player)
if not table.find(players,player.Name) then
players[player.Name] = {
["Ragdoll"] = true,
["Description"] = "yes",
["User Id"] = player.UserId
}
end
end)
game.Players.PlayerRemoving:Connect(function(player)
if table.find(players,player.Name) then
players[player.Name] = nil
end
end)
while task.wait(.75) do
print(players)
end
This worked perfectly for me. I’m not sure you can add an instance to the table with it being easily able to find; so I just added the players name as a replacement and it worked perfectly for me.
Adding an Instance
I tried adding it as an instance and it popped up like this; showing both can work. I’d say to try moving the players table out of the game.Players.PlayerAdded function; and try again.
Hey, if you’re still online I didn’t include this for some reason but there is a function inside of the module that I am trying to execute but that’s where it says the player is equal to nil.
local statusEffects = {}
local players = {}
--\\ Functions : Players //--
game.Players.PlayerAdded:Connect(function(player)
if not table.find(players, player.Name) then
players[player.Name] = {
["Ragdoll"] = {
active = false,
statusTime = 0,
},
["Slowed"] = {
active = false,
statusTime = 0,
multiplier = 0
},
}
end
end)
game.Players.PlayerRemoving:Connect(function(player)
if table.find(players, player.Name) then
players[player.Name] = nil
end
end)
task.spawn(function()
while task.wait(2) do
print(players)
end
end)
--\\ Functions : Status Effects //--
--\\ Status Effects : Buffs //--
--\\ Status Effects : Debuffs //--
statusEffects.Ragdoll = function(player, timeSet)
local playerInTable = table.find(players, player.Name)
print(playerInTable)
if not playerInTable.Ragdoll.active then playerInTable.Ragdoll.active = true
for index, joint in pairs(player.Character:GetDescendants()) do
if joint:IsA("Motor6D") then
local socket = Instance.new("BallSocketConstraint")
local a1 = Instance.new("Attachment")
local a2 = Instance.new("Attachment")
a1.Parent = joint.Part0
a2.Parent = joint.Part1
socket.Parent = joint.Parent
socket.Attachment0 = a1
socket.Attachment1 = a2
a1.CFrame = joint.C0
a2.CFrame = joint.C1
socket.LimitsEnabled = true
socket.TwistLimitsEnabled = true
joint.Enabled = false
if playerInTable.Ragdoll.statusTime ~= 0 then timeSet += playerInTable.Ragdoll.statusTime end
-- if ragdoll already active then add more time to timeSet
task.wait(timeSet)
joint.Enabled = true
socket:Destroy()
a1:Destroy()
a2:Destroy()
end
end
else
playerInTable.Ragdoll.statusTime += timeSet
end
end
I had no issue with it, no errors; or anything in-between. I’d need to know what line is erroring, I’d also recommend removing the task.spawn(function() here;
Whenever you’re looking for something in a table, make sure you do a check to see if the table is actually there… else it will print nil one time, and break.
This should now work perfectly, I also added a variable that you can enable when you want to see the ragdoll table… that way you don’t always have that while loop running;
Script Fixed
local statusEffects = {};local players = {};local PrintRagdollTable = false
--\\ Functions : Players //--
game.Players.PlayerAdded:Connect(function(player)
if not table.find(players, player.Name) then
players[player.Name] = {
["Ragdoll"] = {
active = false,
statusTime = 0,
},
["Slowed"] = {
active = false,
statusTime = 0,
multiplier = 0
},
}
end
end)
game.Players.PlayerRemoving:Connect(function(player)
if table.find(players, player.Name) then
players[player.Name] = nil
end
end)
--\\ Functions : Status Effects //--
--\\ Status Effects : Buffs //--
--\\ Status Effects : Debuffs //--
statusEffects.Ragdoll = function(player, timeSet)
local playerInTable = table.find(players, player.Name)
if playerInTable and not playerInTable.Ragdoll.active then
playerInTable.Ragdoll.active = true
for index, joint in pairs(player.Character:GetDescendants()) do
if joint:IsA("Motor6D") then
local socket = Instance.new("BallSocketConstraint")
local a1 = Instance.new("Attachment")
local a2 = Instance.new("Attachment")
a1.Parent = joint.Part0
a2.Parent = joint.Part1
socket.Parent = joint.Parent
socket.Attachment0 = a1
socket.Attachment1 = a2
a1.CFrame = joint.C0
a2.CFrame = joint.C1
socket.LimitsEnabled = true
socket.TwistLimitsEnabled = true
joint.Enabled = false
if playerInTable.Ragdoll.statusTime ~= 0 then timeSet += playerInTable.Ragdoll.statusTime end
-- if ragdoll already active then add more time to timeSet
task.wait(timeSet)
joint.Enabled = true
socket:Destroy()
a1:Destroy()
a2:Destroy()
end
end
elseif playerInTable then
playerInTable.Ragdoll.statusTime += timeSet
end
end
if PrintRagdollTable then
while task.wait(10) do
print(players)
statusEffects.Ragdoll(game.Players.Just2Terrify)
end
end
Idk if I’m just doing something wrong but when I put:
local mod = require(game.ServerStorage.GameModules.StatusEffects) mod.Ragdoll(game.Players.StarJ3M, 5)
Into the command box, it didn’t work, there weren’t any errors or anything but the player didn’t ragdoll.
Do you think it’s because I changed it to look like this?
local statusEffects = {}
local players = {}
--\\ Functions : Players //--
game.Players.PlayerAdded:Connect(function(player)
if not table.find(players, player.Name) then
players[player.Name] = {
["Ragdoll"] = {
active = false,
statusTime = 0,
},
["Slowed"] = {
active = false,
statusTime = 0,
multiplier = 0
},
}
end
end)
game.Players.PlayerRemoving:Connect(function(player)
if table.find(players, player.Name) then
players[player.Name] = nil
end
end)
--\\ Functions : Status Effects //--
--\\ Status Effects : Buffs //--
--\\ Status Effects : Debuffs //--
statusEffects.Ragdoll = function(player, timeSet)
local playerInTable = table.find(players, player.Name)
if playerInTable and not playerInTable.Ragdoll.active then
playerInTable.Ragdoll.active = true
for index, joint in pairs(player.Character:GetDescendants()) do
if joint:IsA("Motor6D") then
local socket = Instance.new("BallSocketConstraint")
local a1 = Instance.new("Attachment")
local a2 = Instance.new("Attachment")
a1.Parent = joint.Part0
a2.Parent = joint.Part1
socket.Parent = joint.Parent
socket.Attachment0 = a1
socket.Attachment1 = a2
a1.CFrame = joint.C0
a2.CFrame = joint.C1
socket.LimitsEnabled = true
socket.TwistLimitsEnabled = true
joint.Enabled = false
if playerInTable.Ragdoll.statusTime ~= 0 then timeSet += playerInTable.Ragdoll.statusTime end
-- if ragdoll already active then add more time to timeSet
task.wait(timeSet)
joint.Enabled = true
socket:Destroy()
a1:Destroy()
a2:Destroy()
end
end
elseif playerInTable then
playerInTable.Ragdoll.statusTime += timeSet
end
end
return statusEffects
The reason why you get nothing when you print out the players[player] table is because it doesn’t look for anything in __index (Mostly to prevent a table inside itself). But if you use an unidentified key in the players[player] table, it looks in __index instead and searches for one.
You’re sending the instance, not the player’s name… which is how I have it set-up. I’m not sure how your module is set-up… but once you send the PlayersName into the table… just make sure it fires and changes the value… after that; you can make the ragdoll work properly.
Try this,
local mod = require(game.ServerStorage.GameModules.StatusEffects) mod.Ragdoll(game.Players.StarJ3M.Name, 5)