Players[Player] == nil

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.

–! Player table and statusEffects table.

local players = {}
players.statusEffects = {
	["Ragdoll"] = {
		active = false,
		statusTime = 0,
	},
	
	["Slowed"] = {
		active = false,
		statusTime = 0,
		multiplier = 0
	},
}

–! 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)
1 Like

maybe try table.insert & table.remove

1 Like

Where exactly would I replace parts of the code with these functions?

2 Likes

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

then do

players[player] = deepCopy(players.statusEffects)
2 Likes

So then how can I make a metamethod?

So then if I used __index, would this allow it to become a metastable?

image

I tried doing this and annoyingly enough it still returns nil…


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.
image


1 Like

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

@Just2Terrify

1 Like

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;

It errors on line 47.

 ServerStorage.GameModules.StatusEffects:47: attempt to index nil with 'Ragdoll'
	if not playerInTable.Ragdoll.active then playerInTable.Ragdoll.active = true


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;
image
image

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

Add __index as a key in the players table, and set the value to itself.

local players = {}
players.statusEffects = {
	["Ragdoll"] = {
		active = false,
		statusTime = 0,
	},
	
	["Slowed"] = {
		active = false,
		statusTime = 0,
		multiplier = 0
	},
}
players.__index = players

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.

1 Like

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)

If this doesn’t work; try @kexy123’s idea.