Properties of "self" returned from a class are nil

Hello, I am currently programming an OOP round system server side. I’ve stumbled upon a problem though. Whenever I try to access “self” in another method of my class, its just nil. Here’s an example and a short snippet of my code (sending full code would be too long since its 300 lines).

function Round.new(intermissionTime, minPlayers)
	local self = setmetatable({}, Round)
	self.intermissionTime = intermissionTime
	self.minPlayers = minPlayers
	self.inProgress = false
	self.startedTick = os.time()

	self:init()

	return self
end

function Round:enoughPlayers()
	print(self.intermissionTime) -- this returns "nil"
	print(self.minPlayers) -- this returns "nil"
	return #Players:GetPlayers() >= self.minPlayers -- attempt to compare nil <= number, since self.minPlayers is "nil" apparently
end

Of course :init() is defined.

Here’s my server script which constructs the class:

local RoundManager = require(script:WaitForChild('RoundManager'))
local Manager = RoundManager.new(5, 2)

I already checked the forum for this issue, and found a few threads. I tried their solution but it didn’t work out for me. Please someone help.

show us where you’re calling the enoughPlayers method

function Round:init()
	CounterType.Value = 'WaitingForPlayers'
	Players.PlayerAdded:Connect(function()
		Round:handlePlayerAdded()
	end)
	Players.PlayerRemoving:Connect(function()
		Round:handlePlayerRemoving()
	end)
	Red.RedPad.TouchPart.Touched:Connect(function(hit)
		Round:touchedRed(hit)
	end)
	Blue.BluePad.TouchPart.Touched:Connect(function(hit)
		Round:touchedBlue(hit)
	end)
end

return Round

That’s not what I asked for, where are you calling enoughPlayers

function Round:handlePlayerAdded()
	if not self:isRunning() and self:enoughPlayers() then
		self:countdown()
	else
		self:displayWaitingForPlayers()
	end
end

function Round:handlePlayerRemoving()
	if self:isRunning() and not self:enoughPlayers() then
		self:endRound()
	end
end

Do you have this at the top of the Round module?

local Round = {}
Round.__index = Round
local Round = {}
Round.__index = Round

Inside of the enoughPlayers method print just self, let’s see if it prints the contents of that object

print(self)

Apparently it only prints the functions in the class.
{
[“__index”] = “*** cycle table reference detected ***”,
[“assignTeams”] = “function”,
[“assignWeapons”] = “function”,
[“checkAlive”] = “function”,
[“countdown”] = “function”,
[“displayWaitingForPlayers”] = “function”,
[“endRound”] = “function”,
[“enoughPlayers”] = “function”,
[“handlePlayerAdded”] = “function”,
[“handlePlayerRemoving”] = “function”,
[“init”] = “function”,
[“isRunning”] = “function”,
[“lightsOff”] = “function”,
[“lightsOn”] = “function”,
[“loadVoting”] = “function”,
[“new”] = “function”,
[“selectRandomSpawn”] = “function”,
[“startRound”] = “function”,
[“touchedBlue”] = “function”,
[“touchedRed”] = “function”
}

replace you’re .new function with this

function Round.new(intermissionTime, minPlayers)
	local self = setmetatable({
      intermissionTime = intermissionTime,
      minPlayers = minPlayers,
      inProgress = false,
      startedTick = os.time()
   }, Round)
	
	self:init()

	return self
end

pattinson-smile

Still, same error. Also I used your method before I made this post.

dang i really thought i had that one, well it looks like it’s printing the functions of the actual Round class itself not properties associated with the object

I never had this issue before even though I have been familiar with OOP for several years. Also in different languages.

The methods within these events need to be called by the instance (using the self keyword). Round does not contain the fields you set in the constructor.

self:handlePlayerAdded()
1 Like

Oh my god, no way I didn’t see that. Sorry, I’m lacking sleep. You are a W man!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.