Metatable - metamethod & self variables (Error)

Good morning/afternoon,

I have this bug to do with metatables, that I’m struggling to debug.

Module:

-- Services --
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")

-- Constants --

-- Variables --

-- Module --
local Vehicle = {}
Vehicle.__index = Vehicle

-- Constructor --
function Vehicle.new(Model :Model)
	local self = setmetatable({}, Vehicle)
	
	self.SuspensionMaxLength = Model:GetAttribute("SuspensionMaxLength")
	self.SuspensionStiffness = Model:GetAttribute("SuspensionStiffness")
	self.SuspensionDamping = Model:GetAttribute("SuspensionDamping")
	
	self.WheelRadius = Model:GetAttribute("WheelRadius")
	self.Chassis = Model.PrimaryPart
	
	self.Connection = nil
	
	self.WheelPositions = {
		FL = Model:GetAttribute("WheelFL"),
		FR = Model:GetAttribute("WheelFR"),
		RL = Model:GetAttribute("WheelRL"),
		RR = Model:GetAttribute("WheelRR")
	}
	
	self.PreviousSpringLengths = {
		FL = 0.5,
		FR = 0.5,
		RL = 0.5,
		RR = 0.5,
	}
	
	return self
end

function Vehicle:Calculate(DeltaTime :number)


	--[[ Expected:
		Vehicle = {
			["Chassis"] = Part,
            ["PreviousSpringLengths"] =  ▶ {...},
            ["SuspensionDamping"] = 2,
            ["SuspensionMaxLength"] = 1.3,
            ["SuspensionStiffness"] = 70,
            ["WheelPositions"] =  ▶ {...},
            ["WheelRadius"] = 0.5,
			["Calculate"] = "function",
            ["Destroy"] = "function",
            ["__index"] = "*** cycle table reference detected ***",
            ["new"] = "function"
		}
	]]


	--[[ Actual:
		Vehicle = {
			["Calculate"] = "function",
			["Destroy"] = "function",
			["__index"] = "*** cycle table reference detected ***",
			["new"] = "function"
    	}
	]]

	for Wheel, Origin in self.WheelPositions do -- ERROR: attempt to iterate over a nil value (self.WheelPositions == nil)
		-- ...
	end
end

function Vehicle:Destroy()
	if (self.Connection and not self.Connection.Disconnected) then
		self.Connection:Disconnect()
	end
end

-- Return --
return Vehicle

Init Script > Function:

local function InitVehicle(Model :Model)
	local self = Vehicle.new(Model)
	
	print(self) -- Prints expected output (???)
	--[[ 
		Vehicle = {
			["Chassis"] = Part,
            ["PreviousSpringLengths"] =  ▶ {...},
            ["SuspensionDamping"] = 2,
            ["SuspensionMaxLength"] = 1.3,
            ["SuspensionStiffness"] = 70,
            ["WheelPositions"] =  ▶ {...},
            ["WheelRadius"] = 0.5,
			["Calculate"] = "function",
            ["Destroy"] = "function",
            ["__index"] = "*** cycle table reference detected ***",
            ["new"] = "function"
		}
	]]
  	]]
	
	self.Connection = RunService.Heartbeat:Connect(function(DeltaTime)
		Vehicle:Calculate(DeltaTime)
	end)
end

Error:
ServerStorage.Modules.Vehicle:46: attempt to iterate over a nil value - Server - Vehicle:46

The intended behaviour is that the code doesn’t error (obviously) and self.WheelPositions is equal to what it should theoretically be.

My friend noticed that I put Vehicle instead of self:

I was referring to the base module instead of the object.

Fixed code:

self.Connection = RunService.Heartbeat:Connect(function(DeltaTime)
		self:Calculate(DeltaTime)
	end)

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