[RESOLVED] Loop only happens once and then never after

Sooo (I said this like 10 times already) I’m making a TD game and I was working on a custom tower attack system that works with my enemy system that assigns each enemy a unique ID so they can be tracked considering they only exist as data on the server.

The tower system worked fine until I noticed that when the first enemy dies all Towers will stop attacking and never start again, even if you place a new tower it still won’t attack the enemies…

local towerModule = {}

towerModule.TowerIndex = {} --Index for all towers
local id = 1


function findNearestTarget(d, towerCframe)
	
	local maxDistance = d
	local nearestTarget = nil
	
	for i, target in ipairs(enemymodule.Entities) do
		local distance = (target.Position.Position - towerCframe.Position).Magnitude
		
		if distance < maxDistance then
			nearestTarget = target
			maxDistance = distance
		end
		
		--warn(nearestTarget)
		
	end
	
	return nearestTarget
	
	
end

function towerModule.Attack(towerT)

	local target = findNearestTarget(towerModule.TowerIndex[towerT.ID].Range, towerModule.TowerIndex[towerT.ID].Position)
	
	if target then
		
		animateTowerEvent:FireAllClients(towerModule.TowerIndex[towerT.ID].ID)
		target.Health -= towerModule.TowerIndex[towerT.ID].Damage
		warn(target.Enemy.." has "..target.Health.." health left")
		
	end
	
	task.wait(towerModule.TowerIndex[towerT.ID].Reload)
	
	towerModule.Attack(towerT)
	
end


function towerModule.Create(Player, tower, cframe)
	
	local towerTable = { --// Change so it works for each tower 

		["Tower"] = tower, 
		["ID"] = id,
		["Position"] = cframe,
		["Damage"] = 1,
		["Reload"] = 0.5,
		["Range"] = 25,
	}

	towerModule.TowerIndex[id] = towerTable
	id += 1


	coroutine.wrap(towerModule.Attack)(towerTable)
	
	
end

createTowerEvent.OnServerEvent:Connect(towerModule.Create)

return towerModule

This is the entire tower handling module. It’s pretty self explanatory I think.

Can someone help me?

1 Like

Someone maybe knows why? Thanks

It appears you iterate the Entities table from the enemymodule, is it possible that this module is responsible for removing values in this table? As I cannot see any code in the module provided here that is responsible for that

Yes, the enemy module removes data from the enemy table when its assigned enemy dies or enters the base. But I think I wrote it in the tower module like this that they target other enemies too I think. (Considering that the old enemy they were originally targeting gets set to nil)

If possible, could you provide the code responsible for the removal? Perhaps this may be the source of the issue

The part that adds a table for each enemy that spawns into a storing table (enemyModule.Entities)

local enemyTable = {
				
				["Enemy"] = enemy,
				["ID"] = id,
				["Health"] = list[enemy].Health,
				["Speed"] = list[enemy].Speed,
				["Position"] = CFrame.new(0,0,0),
				["ReferenceObject"] = newFolderForEnemy
			}
			
			
			spawnEnemyModule.Entities[id] = enemyTable
			id += 1

The parr that removes the table for the enemy that died / entered the base. (t being an alpha value to calculate movement)

	if enemyTable.Health <= 0 then

					loop:Disconnect()
					enemyTable.ReferenceObject:Destroy()
					killEnemyEvent:FireAllClients(spawnEnemyModule.Entities[enemyTable.ID].ID)
					spawnEnemyModule.Entities[enemyTable.ID] = nil

				end

				if t >= 1 then -- remove enemyReferenceObject and loop once last waypoint is reached
					enemyTable.ReferenceObject:Destroy()
					--spawnEnemyModule.Entities[id] = nil
					loop:Disconnect()
					workspace:SetAttribute("health", workspace:GetAttribute("health") - enemyTable.Health)
					spawnEnemyModule.Entities[enemyTable.ID] = nil
					updateBaseHealthVisuals:FireAllClients()

					if workspace:GetAttribute("health") <= 0 then
						spawnEnemyModule.clearEnemies()
						gameOverBool.Value = true
					end

				end

A possible reason for the issue might be that the loop that damages and target enemies only runs until the first enemy dies. It literally never runs ever after for some reason