Modules and OOP

When designing my classes, they often need further modularisation, and as such I end up doing things like this:

local DealDamage = require(script.DealDamage)

function Sword:DealDamage(damage, target)
   DealDamage(self, damage, target)
end

I find this fairly ineloquent and thought there was probably a better way, but I can’t think of what it is. I also tried

Sword.DealDamage = require(script.DealDamage)

but the problem with this is that I obviously can’t access self in DealDamage. I could do something like

Sword.DealDamage = require(script.DealDamage)(self)

and inject it in as I’m currently doing, but that’ll make the code in DealDamage quite messy.

Anyone have any ideas?

1 Like

I assume you have a lot of different weapons that need to use DealDamage? If so, then this is a good case for having a super-class abstraction (e.g. “Weapon”) that implements the DealDamage method. Then other sub-classes (such as “Sword”) extend from the Weapon class, and thus already have the DealDamage method inherited.

This thread goes into good detail regarding OOP, including the basics on implementing inheritance.


Here’s a simple example demonstrating what I’m talking about:

-- "Weapon" is the abstract class that implements generic stuff like "DealDamage"
local Weapon = {}
Weapon.__index = {}

function Weapon.new()
	local self = setmetatable({

	}, Weapon)
	return self
end

function Weapon:DealDamage(damage, target)
	-- Deal damage
end

--------------------------------------------------

local Weapon = require(somewhere.Weapon)

local Sword = {}
Sword.__index = Sword
setmetatable(Sword, Weapon)

function Sword.new()
	local self = setmetatable({}, Sword)
	return self
end

-- Example:
local sword = Sword.new()
sword:DealDamage(10, player)
9 Likes

I was actually just looking for short hand for the code I posted! I’m not making a combat game right now, Sword:DealDamage was just whatever came to my head and I am already experienced with inheritance - I do appreciate your effort though

I think @Crazyman32’s suggestion still applies. You could simply do this at the top of your sword class module:

Sword = require(game.ServerStorage.Weapon):extend() 

And it will have it’s __index will be set so that mySword:DealDamage() will work and self will be set appropriately.

Anyways, I gtg since my class started but a word of advice to the wise: don’t give in to OOP. It lies.

You say “obviously” here but that’s actually not true at all. When you define a function with the : operator like that all it does is add this as a hidden first argument. It’s exactly equivalent to a normal function with the self first argument explicitly declared.

So that assignment statement require style would actually work, and work exactly like you want it to at least in that specific case.

2 Likes