Hello, I am attempting to incorporate OOP into my new game. While I am familiar with how OOP works in actual OOP-languages, I am not entirely familiar with how they work with meta tables, and I am getting some errors in the process. Below are the two module scripts, a regular script, and the output.
The concept: a SmallBoy is an class that belongs to the class Boat.
Boat Module Script
local Boat = {}
Boat.__index = Boat
function Boat.new(obj, config)
return setmetatable({
--Organization
Obj = obj, --The actual instance of the boat (parent-most model).
Name = config.Name, --USS_Boat_Name or CHINA_Boat_Name
Faction = config.Faction, --USN/Hostile
Unit = config.Unit, --CSGI/CSGIII/Hostile
Alive = true, --True/False
--Location
Spawned = true, --By default, the boat has not spawned, but for testing it has.
InPort = true, --By default, the boat will be set to nil, but for testing it is in port.
--Statistics
Kills = 0, --The number of boats sank by this boat.
--Damage Specifics
MaxHealth = config.MaxHealth, --Max HP of the boat.
CurrentHealth = config.MaxHealth, --Current HP of the boat, just spawned, so maxHealth.
Repairing = false, --Is the boat currently under repairs?
--Propulsion Specifics
EngineCount = config.EngineCount, --Number, how many engines.
PropCount = config.PropCount, --Number, how many propellers.
MaxSpeed = config.MaxSpeed, --Max speed the boat will go.
CurrentSpeed = 0, --Boat is not moving when created.
Acceleration = config.Acceleration, --How fast can the boat speed/stop?
TurnSpeed = config.TurnSpeed, --How fast can the boat turn?
}, Boat)
end
--Propulsion
function Boat:Start()
print(self.Name, " starting up.")
end
--Damage Control
function Boat:Damage(hp)
local newHp = self.CurrentHealth - hp
if newHp < 0 then
newHp = 0
self.Alive = false
else
self.CurrentHealth = newHp
end
print(newHp)
end
function Boat:Repair(hp)
local newHp = self.CurrentHealth + hp
if newHp <= self.MaxHealth then
self.CurrentHealth = newHp
end
end
return Boat
SmallBoy Module Script
local ServerScriptService = game:GetService("ServerScriptService")
local Classes = ServerScriptService["Classes"]
local Boat = require(Classes["Boat"])
local SmallBoy = {}
SmallBoy.__index = SmallBoy
setmetatable(SmallBoy,{__index = Boat})
function SmallBoy.new(obj, config)
return setmetatable({
self = Boat.new(obj, config)
}, SmallBoy)
end
return SmallBoy
Initialize Script within a Boat
local ServerScriptService = game:GetService("ServerScriptService")
local Classes = ServerScriptService["Classes"]
local SmallBoy = require(Classes["SmallBoy"])
SmallBoy.new(script.Parent, require(script.Parent.Configuration))
SmallBoy:Start()
SmallBoy:Damage(5)
Config Module
return {
["Name"] = "USS_SmallBoy",
["Faction"] = "USN",
["Unit"] = "CSGI",
["MaxHealth"] = 1000,
["EngineCount"] = 1,
["PropCount"] = 2,
["MaxSpeed"] = 70,
["Acceleration"] = 0.5,
["TurnSpeed"] = 0.02999999999999999889,
}
Output (with errors):
nil starting up.
[21:39:00.309 - ServerScriptService.Classes.Boat:46: attempt to perform arithmetic (sub) on nil and number](rbxopenscript://www.dummy.com/dummy?scriptGuid=%7BA98737B7%2D8A42%2D4517%2D83CB%2DE85C5FE9E26C%7D&gst=3#46)
21:39:00.309 - Stack Begin
[21:39:00.310 - Script 'ServerScriptService.Classes.Boat', Line 46 - function Damage](rbxopenscript://www.dummy.com/dummy?scriptGuid=%7BA98737B7%2D8A42%2D4517%2D83CB%2DE85C5FE9E26C%7D&gst=3#46)
[21:39:00.310 - Script 'Workspace.USS_SmallBoy.Initilize', Line 8](rbxopenscript://www.dummy.com/dummy?scriptGuid=%7B17B4018E%2DF437%2D4FB0%2DAB5C%2D9A512F97A60E%7D&gst=3#8)
21:39:00.311 - Stack End
I have looked at many different videos, and I cannot figure out why the properties are not being set, or at least not being retrieved when using self. When I print out the inputs in the Boat Module Script, they are correct, so I know this is an issue with either storing or retrieving.
Any guidence would help!