Troop System with Groups, Optimization

  1. What do you want to achieve? Keep it simple and clear!
    I am making a troop system with formations. For that I created a group handler to group troops and save information in module scripts. To do this I have a preset for all groups and duplicate it for every group created.

  2. What is the issue? Include screenshots / videos if possible!
    When no troop is in the group, the module script should delete itself but it doesn’t work. I heared that this is due to security to stop exploiters that don’t know what they are doing.
    I am wondering if there is a more efficient way doing this as I don’t want the server to store hundreds of group infos for groups without troops in them (as there are new ones with the troops from existing groups which get moved).

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    Maybe I could make only one module script and save the data in new global tables, but I don’t know how it would be done.

thanks in advance!

Groups Handler Module

local groupHandler = {}

local lastGroupId = 10
local preset = script.preset


function groupHandler.newGroup(troops)
	lastGroupId += 1
	local thisGroupInfo = preset:Clone()
	thisGroupInfo.Name = lastGroupId
	thisGroupInfo.Parent = script
	local thisGroupInfoM = require(thisGroupInfo)

	for index, troop in troops do
		thisGroupInfoM.addTroop(troop)
	end
	
	print("Group made with Id ".. thisGroupInfo.Name)
	
	return thisGroupInfo.Name
end

function groupHandler.removeTroopFromAnyGroup(troop)
	if tonumber(troop:GetAttribute("GroupId")) > 5 then
		require(script[troop:GetAttribute("GroupId")]).removeTroop(troop)
	end
end

function groupHandler.removeTroopFromAnyGroupTable(troops)
	for index, troop in troops do
		if tonumber(troop:GetAttribute("GroupId")) > 5 then
			require(script[troop:GetAttribute("GroupId")]).removeTroop(troop)
		end
	end
end

function groupHandler.getGroupFromId(groupId)
	if not script[groupId] then warn(`Group with {groupId} was not Found.`) return end
	return script[groupId]
end

return groupHandler

Group Preset Module:

local formationInfo = {
	pointsToWalkTo = {},
	groupTroops = {}
}

local troopWalkHandler = require(script.Parent.Parent:WaitForChild("TroopSystemScript"):WaitForChild("TroopWalkHandler"))

function formationInfo.addTroop(troop)
	table.insert(formationInfo.groupTroops, troop)
	troop:SetAttribute("GroupId", script.Name)
end

function formationInfo.removeTroop(troop)
	
	if troop:GetAttribute("GroupId") ~= script.Name then
		warn(`{troop.Name} not in this group`)
		return
	end
	
	for index, groupTroop in formationInfo.groupTroops do
		if groupTroop == troop then
			table.remove(formationInfo.groupTroops, index)
			troop:SetAttribute("GroupId", 0)
			return
		end
	end
	
	if #formationInfo.groupTroops <= 1 then
		formationInfo.removeTroop(formationInfo.groupTroops[1])
	end
end

function formationInfo.troopsAreWalking()
	for index, troop in formationInfo.groupTroops do
		if troop:GetAttribute("isWalking") == true then
			return true
		end
	end
	return false
end

function formationInfo.onTroopFinishedWalking()
	if not formationInfo.troopsAreWalking() and formationInfo.pointsToWalkTo[1] then
		print(formationInfo.pointsToWalkTo)
		-- All troops are finished walking
		troopWalkHandler.moveTroops(formationInfo.groupTroops, formationInfo.pointsToWalkTo[1], false)
		table.remove(formationInfo.pointsToWalkTo, 1)
	end
end

return formationInfo

why dont you check if the troop count is bigger than 0?

I do this at the end of function removeTroop, at the beginning I had there script:Destroy() which doesn’t work because it’s a module script

Yeah there isnt a true way to delete module scripts without deleting the parent.