Replicating Enemies on all clients

I am creating a wave system for my tower defense game but im running into a problem of replicating the positions on every client

Problems

  • Different Positions
  • Not The Same amount spawning

could i use replica for this? just wondering as i’ve only used it for replicating player data.

local function SpawnMobs(amount : number, data : any, delayTime : number)
	local Speed = data.Speed
	for i = 1, amount, 1 do
		if workspace:GetAttribute("BaseHealth") <= 0 then
			break
		end
		task.spawn(function()
			local Time_Left = GetPosition(data) -- time to complete the path
			
			task.wait(Time_Left)
			workspace:SetAttribute("BaseHealth", workspace:GetAttribute("BaseHealth") - data.Health / 4)
		end)
		data.StartTime = os.clock()
		ReplicatedStorage.Events.SpawnEnemy:FireAllClients(data)

		task.wait(delayTime)
	end
end

task.wait(5)
-- Function, Amount, Data, Delay
task.spawn(SpawnMobs, 10, EnemyData["Mob_test"], .5)

here is the client side

local function OnSpawn(mob: Model, mob_data, elapsed)
	if not mob.PrimaryPart then return end
	
	-- Animate
	local Animations = mob:WaitForChild("Animations")
	local AnimationController = mob:WaitForChild("AnimationController")
	local Animator = AnimationController:WaitForChild("Animator") :: Animator
	local Run = Animations:WaitForChild("Run") :: Animation
	local track = Animator:LoadAnimation(Run)
	track:Play()
	
	local passed = 0
	local Speed = mob_data.Speed :: number
	-- Tween To Waypoints
	for i = 2, MAX_WAYPOINTS do
		if not mob then return end
		if not mob.PrimaryPart then return end
		
		local current_waypoint = Waypoints[tostring(i)] :: Part
		local previous = Waypoints[tostring(i - 1)] :: Part
		
		local distance = (previous.Position - current_waypoint.Position).Magnitude
		local duration = distance / Speed
		
		if elapsed > passed + duration then
			passed += duration
			continue
		elseif elapsed > passed then
			-- start in the middle of this tween
			local partial = elapsed - passed
			local alpha = partial / duration
			local targetPos = previous.Position:Lerp(current_waypoint.Position, alpha)
			mob:PivotTo(CFrame.new(targetPos))
			duration -= partial
		end
		
		local info = TweenInfo.new(duration, Enum.EasingStyle.Linear)
		
		local tween = TweenService:Create(mob.PrimaryPart, info, {CFrame = current_waypoint.CFrame})
		tween:Play()
		tween.Completed:Wait()
		passed += duration
	end
	mob:Destroy()
end

ReplicatedStorage.Events.SpawnEnemy.OnClientEvent:Connect(function(mob_data)
	if mob_data == false then
		for _, v in Mobs:GetChildren() do
			v:Destroy()
		end
		return
	end
	local mob = ReplicatedStorage.Mobs:FindFirstChild(mob_data.Name):Clone() :: Model
	mob.Parent = workspace.Mobs
	mob:SetAttribute("Health", mob_data.Health)
	mob:SetAttribute("MAXHEALTH", mob_data.Health)
	local StartTime = mob_data.StartTime :: number
	local elapsed = math.max(0, os.clock() - StartTime)
	mob:PivotTo(START_POSITION.CFrame)

	task.spawn(OnSpawn, mob, mob_data, elapsed)
	mob:GetAttributeChangedSignal("Health"):Connect(function()
		if mob:GetAttribute("Health") <= 0 then
			mob:Destroy()
		end
	end)
end)

Show us the data it sends, also you should probably make a single message about how many mobs spawned and when, along with the data and send it once when you attempt spawning them

it clearly shows what data it sends in the post