OOP Module is not differentiating even though it has been created by different users

  1. What do you want to achieve?
  • Hi, for some reason I’m getting a pretty weird bug. It can be seen in the attached video.
  1. What is the issue?
  • It seems that for some reason they share the Module, since if one of the two (Dummy/Player/anotherPlayer), it will not work. if one of the two attacks the other can not attack, etc (They can not perform actions that are in the Module)

https://streamable.com/1u3zn7?src=player-page-share

  1. What solutions have you tried so far?
    I tried to search about the problem, but I couldn’t find anything.
    Change the module script, printed self and they was different (dummy/player), so I don’t really know what’s going on.
--ModuleScript 

local LightsaberInstanceCount = 0


local Lightsaber = {}

Lightsaber.__index = Lightsaber

function Lightsaber.New(User, Damage, CDSlash, Anims, AnimFolder, Saber, pathhitbox)
	
	local LSNew = {}
	
	setmetatable(LSNew, Lightsaber)
	
	LSNew.User = User
	LSNew.Damage = Damage
	LSNew.CDSlash = CDSlash
	LSNew.Saber = Saber
	LSNew.PathHitbox = pathhitbox
	LSNew.AnimFolder = AnimFolder
	LSNew.Anims = {}
	for _, v in pairs(AnimFolder:GetChildren()) do
		LSNew.Anims[v.Name] = User.Humanoid.Animator:LoadAnimation(v)
	end
	
	LightsaberInstanceCount = LightsaberInstanceCount + 1
	print("New lightsaber instance created. Total: " .. LightsaberInstanceCount)
	print(LSNew)
	return LSNew 
end

----Script inside of the tool

local function EquipLightsaber()
	local NewLightsaber = TestModule.New(Char, 39, 1.7, nil, AnimsFolder, Tool, Tool.Handle.Wires.blade.Hitbox)
	NewLightsaber:Equipped()

	Tool.Unequipped:Connect(function()
		NewLightsaber:Unequipped()
	end)
	
	Tool.Activated:Connect(function()
		NewLightsaber:Attack()
	end)

	ParryRemote.OnServerEvent:Connect(function()
		NewLightsaber:Parry()
	end)
end

Tool.Equipped:Connect(EquipLightsaber)


Thanks so much for reading!

can you show a snippet of the attack function?

in your ModuleScript, you’re creating a new Lightsaber instance with the Lightsaber.New() function and setting its metatable to Lightsaber This is a common practice in OOP to enable inheritance of methods But if you want each instance to have its own independent properties, you should ensure that these properties are not being shared across instances unintentionally

In the EquipLightsaber function within the tool script, you’re creating a new Lightsaber instance and assigning it to NewLightsaber you then connect several functions to this instance If these functions are intended to be methods of the Lightsaber class they should be defined within the Lightsaber table in your ModuleScript

Hey, I don’t really know what you mean, my English is not very good. Here I show you how is the old script and the new one trying to do what you said(?) --I think you said do something like this

--OldCode

local Lightsaber = {}

Lightsaber.__index = Lightsaber

function Lightsaber.New(User, Damage, CDSlash, Anims, AnimFolder, Saber, pathhitbox)
	
	local LSNew = {}
	
	setmetatable(LSNew, Lightsaber)
	
	LSNew.User = User
	LSNew.Damage = Damage
	LSNew.CDSlash = CDSlash
	LSNew.Saber = Saber
	LSNew.PathHitbox = pathhitbox
	LSNew.Anims = {}
	for _, v in pairs(AnimFolder:GetChildren()) do
		LSNew.Anims[v.Name] = User.Humanoid.Animator:LoadAnimation(v)
	end
	
	return LSNew 
end

function Lightsaber:Equipped()
end

function Lightsaber:Unequipped()
end

function Lightsaber:Attack()
end

function Lightsaber:Parry()
end

return Lightsaber


----NewModule inside of table¿? This works like the previous script, no difference


local LightsaberInstanceCount = 0


local Lightsaber = {}

Lightsaber.__index = Lightsaber

function Lightsaber.New(User, Damage, CDSlash, Anims, AnimFolder, Saber, pathhitbox)
	
	local LSNew = {}
	
	setmetatable(LSNew, Lightsaber)
	
	LSNew.User = User
	LSNew.Damage = Damage
	LSNew.CDSlash = CDSlash
	LSNew.Saber = Saber
	LSNew.PathHitbox = pathhitbox
	LSNew.AnimFolder = AnimFolder
	LSNew.Anims = {}
	for _, v in pairs(AnimFolder:GetChildren()) do
		LSNew.Anims[v.Name] = User.Humanoid.Animator:LoadAnimation(v)
	end
	
	LightsaberInstanceCount = LightsaberInstanceCount + 1
	print("New lightsaber instance created. Total: " .. LightsaberInstanceCount)
	print(LSNew)
	
	--return LSNew 

function Lightsaber:Equipped()
end
	
function Lightsaber:Unequipped()
end

function Lightsaber:Attack()
end
	
function Lightsaber:Parry()
end	

	return LSNew 
end

return Lightsaber

provide more on how the debounce is handled with the given context we can’t really tell whats wrong

Here is more about the script, i did a change i insert the methods inside Lightsaber:Equipped, to see if there was a difference, it remains the same

local LightsaberInstanceCount = 0


local Lightsaber = {}

Lightsaber.__index = Lightsaber

function Lightsaber.New(User, Damage, CDSlash, Anims, AnimFolder, Saber, pathhitbox)
	
	local LSNew = {}
	
	setmetatable(LSNew, Lightsaber)
	
	LSNew.User = User
	LSNew.Damage = Damage
	LSNew.CDSlash = CDSlash
	LSNew.Saber = Saber
	LSNew.PathHitbox = pathhitbox
	LSNew.AnimFolder = AnimFolder
	LSNew.Anims = {}
	for _, v in pairs(AnimFolder:GetChildren()) do
		LSNew.Anims[v.Name] = User.Humanoid.Animator:LoadAnimation(v)
	end
	
	LightsaberInstanceCount = LightsaberInstanceCount + 1
	print("New lightsaber instance created. Total: " .. LightsaberInstanceCount)
	print(LSNew)
	
	--return LSNew 
function Lightsaber:Equipped()

		self.Anims.SableIdle:Play()

		local disHumIsMoving
		local Repeat = true
		local isMoving = false

		local function HumIsMoving()
			if Repeat == false then return end
			if self.User.Humanoid.MoveDirection.Magnitude > 0 then
				isMoving = true
			else
				isMoving = false
			end
			if isMoving then
				self.Anims.SableIdle:Stop()
			else
				if not self.Anims.SableIdle.IsPlaying then
					self.Anims.SableIdle:Play()
				end
			end
		end
		disHumIsMoving = RunService.Heartbeat:Connect(HumIsMoving)

		function Lightsaber:Unequipped()
			self.Anims.SableIdle:Stop()
			disHumIsMoving:Disconnect()
		end

		----------------
		local Count = 0
		local Debounce = false

		function Lightsaber:Attack()

			local CDBetweenCombo = self.CDSlash
			if self.User:GetAttribute("Stunned", true) then return end
			if Debounce == true then return end
			Debounce = true
			------------------------------------
			local function CD()
				task.spawn(function()
					wait(CDBetweenCombo)
					Debounce = false
				end)
			end
			task.spawn(function()
				if Count then
					Count += 1
					CD()
				end
				------------------
				if Count == 4 then
					Count = 1
				end
			end)
			------------------------------------
			local dis = false

			local function Hitbox()

				local function UpdatePositions(Attachment)
				end

				local function RunS(At)
				end

				local function GetAttachments()
				end
				GetAttachments()
			end

			local function Attacking(Animacion)
				Repeat = false
				self.Anims.SableIdle:Stop()
				Hitbox()
				Animacion:Play()
				print(self.User.Name)
				Animacion:GetMarkerReachedSignal("AnimationEnd"):Connect(function()
					Repeat = true
					dis = true
				end)
			end


			if Count == 1 then
				Attacking(self.Anims.M1)
			elseif Count == 2 then
				Attacking(self.Anims.M2)
			elseif Count == 3 then
				Attacking(self.Anims.M3)
			end

		end

		function Lightsaber:Parry()
		end
end
	
	return LSNew 
end

return Lightsaber

your Unequipped and Attack methods look like they’re nested under Equipped that can cause the methods to use the same count and debounce

1 Like

I solved it, thank you all very much!
The problem was in the global variables (debounce, count, etc), what I did was put them in the LSNew table and it worked!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.