OOP: Implentation Review

As someone who discovered OOP very recently, I’m not sure if I’m implenting it correctly into my scripts. I’m working on a projectile system (incomplete of course) using OOP and I want to know if it’s alright. If it’s not, what can I do to fix it or make it more efficient? Are there better ways to approach this? Of course, what I’m doing is working, but I’m worried that it could be a bad practice or something along those lines.

Server / Main Script

local replicatedStorage = game.ReplicatedStorage
local projectiles = replicatedStorage.Projectiles
local utility = require(game:GetService("ServerScriptService").Utility)

local modules = {}
for _, module in pairs(script:GetChildren()) do
	modules[module.Name] = require(module)
end

local projectile = {}
projectile.__index = projectile

function projectile.new(name, cframe)
	local newProjectile = {}
	
	newProjectile.Name = name
	newProjectile.Model = projectiles[name]:Clone()
	newProjectile.PrimaryPart = newProjectile.Model.PrimaryPart
	newProjectile.PrimaryPart.CFrame = cframe
	
	return modules[name].new(newProjectile, projectile)
end

function projectile:Explode(force)
	print("The projectile exploded with a force of "..tostring(force))
end

local newProjectile = projectile.new("Missile", CFrame.new(0, 400, 0))
newProjectile.Model.Parent = workspace

Module Script

local missile= {}
missile.__index = missile

function missile.new(newProjectile, projectile)
	setmetatable(newProjectile, projectile)
	
	newProjectile.PrimaryPart.Touched:Connect(function(collision)
		print("An collision occured.")
		newProjectile:Explode(100)
	end)
	
	return newProjectile
end

return missile

Output

-- >> An collision occured.
-- >> The projectile exploded with a force of 100

Not quite. It looks like you define the base object of a projectile in the server code and then make an object subclassing it in the module.

What you want is 1 modulescript = 1 object. You want to define the whole object in the module script and then utilize those objects in your server and local scripts.

Like this:

local projectile = {}
projectile.__index = projectile

function projectile.new(name, cframe)
	local newProjectile = {}
    setmetatable(newProjectile, projectile)
	
	newProjectile.Name = name
	newProjectile.Model = projectiles[name]:Clone()
	newProjectile.PrimaryPart = newProjectile.Model.PrimaryPart
	newProjectile.PrimaryPart.CFrame = cframe

    newProjectile.PrimaryPart.Touched:Connect(function(collision)
		print("An collision occured.")
		newProjectile:Explode(100)
	end)
	
	return newProjectile
end

function projectile:Explode(force)
	print("The projectile exploded with a force of "..tostring(force))
end

return projectile

Then you would simply utilize this modulescript (object) in server and local scripts. If you want to subclass it, do it in another modulescript that requires it, and then call that. I don’t recommend trying to create objects from within local and server scripts.

See this post for more info.

1 Like