Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Can someone help me out with fixing my OOP-based script?

I'm working on a script that uses a pseudo-OOP (Object Oriented Programming) system much like the one on this wiki page.

However, whenever I run the script, I receive this error:

23:03:02.602 - Workspace.Script:38: attempt to index local 'self' (a nil value)
23:03:02.603 - Stack Begin
23:03:02.603 - Script 'Workspace.Script', Line 38 - field AccumulateForces
23:03:02.603 - Script 'Workspace.Script', Line 49 - method TimeStep
23:03:02.604 - Script 'Workspace.Script', Line 93
23:03:02.604 - Stack End

The 'self' argument doesn't seem to be working correctly in that method, but it does work in the "Init" method, can anyone shed some light on what may be the problem, and how I could fix it?

Here's the entire script for your study. the relevant lines are:

1-76 -- the pseudo-OOP object and related methods

38 -- the error
49 -- part of the error
93 -- ditto

62 -- The Init method

local ParticleSystem = {}
ParticleSystem.__index = ParticleSystem

function ParticleSystem.new(ROOTP,PARTICLES,m_x,m_oldx,m_a,m_vGravity,m_fTimeStep)
	return setmetatable(
		{
			ROOTP = ROOTP;
			PARTICLES = PARTICLES;
			m_x = m_x;
			m_oldx = m_oldx;
			m_a = m_a;
			m_vGravity = m_vGravity;
			m_fTimeStep = m_fTimeStep;
		},
		ParticleSystem
	)
end

-- Verlet Integration Step
function ParticleSystem:Verlet(self)
	for i = 1,#self.PARTICLES do
		local x = self.m_x[i]
		local temp = x
		local oldx = self.m_oldx[i]
		local a = self.m_a[i]
--		x = x + ( x-oldx+a*sef.fTimeStep*self.fTimeStep )
		self.m_x[i] = x + ( x - oldx + a * self.m_fTimeStep * self.m_fTimeStep )
		self.m_oldx[i] = temp
	end
end

--account for gravy
function ParticleSystem:AccumulateForces()
	for i,_ in pairs(self.PARTICLES) do
		-- gravity
		self.m_a[i] = self.m_vGravity
	end
end

-- satisfy any constraints
function ParticleSystem:SatisfyConstraints(self)
	--dolater
end

--time step
function ParticleSystem:TimeStep()
	self.AccumulateForces()
	self.Verlet()
	self.SatisfyConstraints()
end

function ParticleSystem:Draw()
	for i,v in pairs(self.PARTICLES) do
		local root = self.ROOTP
		if self.ROOTP:IsA("BasePart") then
			root = self.ROOTP.Position
		end
		v.Position = root + self.m_x[i]
	end
end

function ParticleSystem:Init()
	local l1 = {}
	local l2 = {}
	local root = self.ROOTP
		if self.ROOTP:IsA("BasePart") then
			root = self.ROOTP.Position
		end
	for i = 1,#self.PARTICLES do
		table.insert(l1,self.PARTICLES[i].Position - root)
		table.insert(l2,Vector3.new(0,0,0))
	end
	self.m_x = l1
	self.m_a = l2
	self.m_oldx = {}
end

local ver = ParticleSystem.new(
	game.workspace.ROOTP,
	{game.workspace.Particle},
	{},
	{},
	{},
	Vector3.new(0,-196.2,0),
	0.1
)

ver:Init()

while wait(0.1) do
	ver:TimeStep()
	ver:Draw()
end

1 answer

✓ Accepted answer

The method syntax a:b() is sugar for doing a.b(a).

Similarly,

function obj:method(x)
end

is sugar for

function obj.method(self, x)
end

You should not be using a named self parameter in a method declaration.


Your calls to the methods on lines, e.g., 47-49, don't use :, they're using ..

That makes them act like property accesses, which happen to be functions, which happen to be called with no arguments RATHER THAN method calls.

If you want to invoke a method, you should always use :.

1 comment

0

Thank you! I hadn't noticed I used a.b() instead of a:b()

This discussion is preserved as it was. New answers, comments, and votes are closed.