Question about OOP!

Hello! I’m really new, literally, 10 mins ago with OOP, so let’s suppose I wanted to have a class for all the players

local module = {}

module.__index = module

function module:NewPlayer()
	local PlayerData = {}
	local MetaTable = setmetatable(PlayerData, module)

	return PlayerData
end

function module:AddHealth(health)
	self.Health = self.Health + health
end

return module

What if I wanted to, make, like,

self.Character.Humanoid.Health = 

Is there a way to have like the PlayerData as the player object, if you understand what I mean, or Maybe a PART, but having like
self.Position = Vector3.new(0,0,0)
What I mean is, having like playerdata as player objecy

1 Like

OOP is great to learn, I think you want something like this:

Module Script:

local module = {}

module.__index = module

function module.new(player)
	local playerData = {
		player = player;
		health = 100;
	}
	setmetatable(playerData, module)

    return self
end

function module:AddHealth(health)
	self.health = self.health + health
end

return module

And in your script, you’d have something like this:

local mod = require(script.whatever)

game.Players.PlayerAdded:Connect(function(p)
	local player = mod.new(p)
	player:AddHealth(10)
end)
1 Like

So, if I wanted, for example, to kill the player, what can I do

function module:Kill()
self.Player.Character.Humanoid.Health = 0
end

?

1 Like

Yeah absolutely, but I’d suggest :BreakJoints()

To add on, it doesn’t seem like a very constructive use of OOP, all of this could be done with just normal events.

You really only want a player object if you’re keeping track of something, I use OOP for things like combat heals, when I want to detect if a heal on a player is triggered from combat.

1 Like

Yes, I kind of wanted to know how to add an object, not gonna use that just to make my script looks more professional lol, but, I didn’t understand what
.__index I guess it’s a methametod but what it does? And why self doesn’t works without it

1 Like

__index is fired whenever Lua tries to index an object in a table.

We use that to redirect calls to the new table we made.

I’m not great at explaining it, but this guide should do a better job I believe:

Also, sorry, i’m asking you a lot, but I just want to learn about, it has been difficult for me to learn it lol

local module = {}

module.__index = module

function module:NewPlayer(player)
	local PlayerData = {
		player = player
		
	}
	local MetaTable = setmetatable(PlayerData, module)
	

	return PlayerData
end

function module:AddHealth(health)
	self.Player.Character.Humanoid.Health = self.Player.Character.Humanoid.Health - health
end

return module

It’s not working, saying that
Line 17 - method AddHealth
attempt to index field ‘Player’ (a nil value)

1 Like

should be self.player because you defined it as “player” in PlayerData.

o didn’t noted that, well, thank you so much, O it didn’t worked lol

function module:NewPlayer(ok)
	local PlayerData = {
		player = ok
		
	}
	local MetaTable = setmetatable(PlayerData, module)
	

	return PlayerData
end

function module:AddHealth(health)
	self.player.Character.Humanoid.Health = self.player.Character.Humanoid.Health - health
end

ReplicatedStorage.OOP.ModuleScript:17: attempt to index field ‘player’ (a nil value)

it should be:

function module.new(player)
local PlayerData = {
player = player
}
setmetatable(PlayerData, module)
return PlayerData
end

Where do you call NewPlayer? You’re probably calling it with a period instead of a colon or something.
@Meta_data. The name of the function doesn’t matter, it’s the fact he’s defining it as a method.

2 Likes
local mod = require(game.ReplicatedStorage.OOP.ModuleScript)

game.Players.PlayerAdded:Connect(function(p)
	local player = mod.NewPlayer(p)
	mod:AddHealth(100)
end)

The issue is the fact you are calling it with the . notation.

a:b(...) is syntax sugar (a nicer way to write something) for a.b(a, ...).

Define the function with . notation and call it with . notation. The newPlayer function is not actually meant to be used as a method here, but rather as a constructor. A constructor defines how to create an instance of a class.

Tbh I wouldn’t even use OOP here. You are not using it for anything big here, it’s only overcomplicating something as simple as subtracting health.

1 Like

NewPlayer is a method. your using a “:” when you defined the function in the module. But in the script that your creating the object, you are using “.”

Edit: Didn’t realize someone answered it already.

Yes, I was just testing incase, I will change it too

Still, it’s not working, saying
00:34:10.070 - ReplicatedStorage.OOP.ModuleScript:17: attempt to index field ‘player’ (a nil value) I changed . to :

What did you change? If it’s the same error, you probably didn’t change the right thing. Show the full line, not just one char.

2 Likes
local mod = require(game.ReplicatedStorage.OOP.ModuleScript)

game.Players.PlayerAdded:Connect(function(p)
	local player = mod:NewPlayer(p)
	mod:AddHealth(100)
end)

Again, you need to be calling local player = mod.NewPlayer(p) there. As it’s a constructor, and not meant to be called as a method.