Resetting module data

Good afternoon, I’m making a module for spawning mobs, and I have a problem: when I spawn the second mob, the information of all previous mobs is reset to the state of mob 2, that’s the problem

Script:

-- Enemy Module
local Enemy = {}
Enemy.__index = Enemy

-- Enemy Container
local Enemies = {}
local IndexMobs = 0

-- Services and Events
local RunService = game:GetService("RunService")
local EventsFolder = game.ReplicatedStorage:WaitForChild("Events")

-- Constants
local UpdateInterval = 1 -- Client updates interval
local Waypoints = workspace:WaitForChild("Waypoints") -- Assuming Waypoints is a folder with part waypoints

-- Enemy Constructor
function Enemy.new(EnemyInfo)
	print(Enemies)
	local self = setmetatable(EnemyInfo, Enemy)
	self.Health = EnemyInfo.Health or 100
	self.Speed = EnemyInfo.Speed or 10
	self.WaypointIndex = 1
	
	self.Position = Waypoints[self.WaypointIndex].Position
	

	self.Alive = true
	
	IndexMobs += 1
	Enemies[IndexMobs] = self

	
	print(Enemies)
	return self
end

-- Move Enemy Function (without Lerp, using constant speed)

function Enemy:Move(deltaTime)

	if not self.Alive then return end

	local nextWaypoint = Waypoints[self.WaypointIndex]
	if nextWaypoint then
		local nextPos = nextWaypoint.Position
		local currentPos = self.Position
		local direction = (nextPos - currentPos).Unit -- Direction from current to next waypoint
		local distance = (nextPos - currentPos).Magnitude
		local moveDistance = self.Speed * deltaTime

		-- Move the enemy towards the next waypoint
		if moveDistance >= distance then
			-- If enemy reaches the waypoint, move to the next one
			self.Position = nextPos
			self.WaypointIndex += 1
			if self.WaypointIndex > #Waypoints:GetChildren() then
				self:Destroy() -- Reached the end of the path
			end
		else
			-- Move the enemy along the direction vector
			self.Position = currentPos + direction * moveDistance
		end
	end
end


-- Enemy Destroy Method
function Enemy:Destroy()
	self.Alive = false
	Enemies[IndexMobs] = nil -- Remove enemy from the list
end

-- Enemy Damage Method
function Enemy:TakeDamage(amount)
	self.Health -= amount
	if self.Health <= 0 then
		self:Destroy()
	end
end

-- Global Update Function
local count = 0
RunService.Heartbeat:Connect(function(deltaTime)
	count += deltaTime

	for i, enemy in pairs(Enemies) do
		if enemy.Alive then
			enemy:Move(deltaTime)
		end
	end

	-- Update clients only at intervals
	if count >= UpdateInterval then
		count = 0
		EventsFolder.Replication:FireAllClients(Enemies)
	end
end)

return Enemy

Maybe I’m saving new mobs wrong?
I also noticed that it changes the data of all mobs in the table to the data of the new mob

Hi, i think this is to do with you passing the EnemyInfo table as a parameter to set the metatable. If this is not a new table created each time it will simply create a new reference to the original, so as you change the values they will all change.

The simplest/safest way is to define self as a new table inside the constructor. Then set the metatable.

local self = {}
setmetatable(self, Enemy)
--rest of code etc

How do you execute the constructor? I think the problem is not currently in the module but rather how you utilize the module outside.

thank you very much, I didn’t notice

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