Module script not working as intended

Hi,

I’m trying to use a module script for my fireball ability, it works fine when a single player uses it but when 2 or more players use it then it does not work properly.

As I understand the issue is that when a player is in the charge phase of the ability and someone shoots the ability then for the player in charge phase instead of the shoot part happening for the one who shot, it will instead happen to the them, and breaks for them.

The one on the left is the one shooting and the one on the right is the charging one.

The solution I found was to just duplicate the module script and use one for the player who creates and other to replicate to others but that kind of removes the point of using a module script as I could just do that with local scripts.

So is there a way to make the module script work for everyone, if yes then how would I go about it ?

LocalScript

--SERVICES
local CAS = game:GetService("ContextActionService")
local RepStorage = game:GetService("ReplicatedStorage")

--MODUELS
local Module1 = require(RepStorage.ModuleScripts.AbilityModuleScripts.FireBallModule1)

--REMOTE EVENTS
local RemoteEvent = RepStorage.RemoteEvents.AbilityEvents.FireBall

--INFO
local Player = game.Players.LocalPlayer
local CoolDown = 2.5
local Charging = false
local AbilityStarted = false

--FUNCTIONS
local function GetMouse()
	local Mouse = Player:GetMouse()
	local MouseIgnoreList = game.Workspace.ScriptCreated.AbilityObjects:GetChildren()
	for i, v in pairs(MouseIgnoreList) do
		Mouse.TargetFilter = v
	end
	return Mouse.Hit
end

--ABILITY
local function Ability(ActionName, ActionState)
	
	local Character = Player.Character
	local Humanoid = Character:WaitForChild("Humanoid")
	if Humanoid.Health <= 0 then return end
	
	if ActionState == Enum.UserInputState.Begin then	
		AbilityStarted = true

		local HRP = Character:WaitForChild("HumanoidRootPart")
		HRP.Anchored = true

		local MouseHit = GetMouse()
		RemoteEvent:FireServer("Create", MouseHit)
		Module1.Create(Player, MouseHit)

		Charging = true
		while Charging do
			wait()

			if Charging then
				local MouseHit = GetMouse()
				RemoteEvent:FireServer("Charge", MouseHit)
				Module1.Charge(Player, MouseHit)
			end
		end

	elseif ActionState == Enum.UserInputState.End and AbilityStarted then
		CAS:UnbindAction("Ability")
		Charging = false
		AbilityStarted = false

		local MouseHit = GetMouse()
		RemoteEvent:FireServer("Shoot", MouseHit)
		Module1.Shoot(Player, MouseHit)

		local HRP = Character:WaitForChild("HumanoidRootPart")
		HRP.Anchored = false

		wait(CoolDown)
		CAS:BindAction("Ability", Ability, false, Enum.KeyCode.E)
	end
end

--REPLICATING
RemoteEvent.OnClientEvent:Connect(function(RemotePlayer, State, RemoteMouseHit)
	if RemotePlayer ~= Player then
		if State == "Create" then
			Module1.Create(RemotePlayer, RemoteMouseHit)
		elseif State == "Charge" then
			Module1.Charge(RemotePlayer, RemoteMouseHit)
		elseif State == "Shoot" then
			Module1.Shoot(RemotePlayer, RemoteMouseHit)
		end
	end
end)

--BINDING
CAS:BindAction("Ability", Ability, false, Enum.KeyCode.E)

ModuleScript

local FireBallModule = {}


--SERVICES
local Debris = game:GetService("Debris")
local RepStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")

--MODULES
local CheckHit = require(RepStorage.ModuleScripts.CheckHit)

--BASE STATS
local BaseDamage = 10
local MaxSize = 5
local Speed = 100
local LifeTime = 2
local ScaleTime = 3
local PositionRelativeToPlayer = CFrame.new(0, 0, -5)

--INFO
local Table = {}
local RepFireBall = RepStorage.AbilityObjects.FireBall
local FireBall

local HRPInfo = TweenInfo.new(0.075)
local FireBallRotationInfo1 = TweenInfo.new(5, Enum.EasingStyle.Linear, Enum.EasingDirection.In, -1, false)
local FireBallRotationInfo2 = TweenInfo.new(0.1, Enum.EasingStyle.Linear, Enum.EasingDirection.In, -1, false)
local FireBallInfo = TweenInfo.new(ScaleTime, Enum.EasingStyle.Linear)
local ExplosionInfo = TweenInfo.new(1)

local FireBallRotationGoal1 = {
	Orientation = Vector3.new(0, 360, 0)
}
local FireBallRotationGoal2 = {
	Orientation = Vector3.new(360, 0, 0)
}
local FireBallRotationGoal3 = {
	Orientation = Vector3.new(0, 0, 360)
}

local SizeTween1
local SizeTween2
local SizeTween3
local SizeTween4
local SizeTween5

local RotationTween2
local RotationTween3
local RotationTween4
local RotationTween5

--CREATE
function FireBallModule.Create(RemotePlayer, MouseHit)
	Table = {}
	
	local Character = RemotePlayer.Character
	local HRP = Character:WaitForChild("HumanoidRootPart")
	HRP.CFrame = CFrame.new(HRP.CFrame.Position, MouseHit.Position)
	
	FireBall = RepFireBall:Clone()
	local FireBallParts = FireBall:GetChildren()
	for i, v in pairs(FireBallParts) do
		v.Position = (HRP.CFrame * PositionRelativeToPlayer).Position
		
		if v == FireBall.P1 then
			local Goals = {
				Size = Vector3.new(MaxSize, MaxSize, MaxSize)
			}
			SizeTween1 = TweenService:Create(v, FireBallInfo, Goals)
			SizeTween1:Play()
			
		elseif v == FireBall.P2 then
			local Goals = {
				Size = Vector3.new(MaxSize + 0.1, MaxSize + 0.1, MaxSize + 0.1)
			}
			SizeTween2 = TweenService:Create(v, FireBallInfo, Goals)
			SizeTween2:Play()
			RotationTween2 = TweenService:Create(v, FireBallRotationInfo1, FireBallRotationGoal1)
			RotationTween2:Play()
			
		elseif v == FireBall.P3 then
			local Goals = {
				Size = Vector3.new(MaxSize + 0.2, MaxSize + 0.2, MaxSize + 0.2)
			}
			SizeTween3 = TweenService:Create(v, FireBallInfo, Goals)
			SizeTween3:Play()
			RotationTween3 = TweenService:Create(v, FireBallRotationInfo1, FireBallRotationGoal1)
			RotationTween3:Play()

		elseif v == FireBall.P4 then
			local Goals = {
				Size = Vector3.new(MaxSize + 0.3, MaxSize + 0.3, MaxSize + 0.3)
			}
			SizeTween4 = TweenService:Create(v, FireBallInfo, Goals)
			SizeTween4:Play()
			RotationTween4 = TweenService:Create(v, FireBallRotationInfo1, FireBallRotationGoal1)
			RotationTween4:Play()

		elseif v == FireBall.P5 then
			local Goals = {
				Size = Vector3.new(MaxSize + 0.4, MaxSize + 0.4, MaxSize + 0.4)
			}
			SizeTween5 = TweenService:Create(v, FireBallInfo, Goals)
			SizeTween5:Play()
			RotationTween5 = TweenService:Create(v, FireBallRotationInfo1, FireBallRotationGoal1)
			RotationTween5:Play()

		end
	end
	FireBall.Parent = game.Workspace.ScriptCreated.AbilityObjects
end

--CHARGE
function FireBallModule.Charge(RemotePlayer, MouseHit)
	
	local Character = RemotePlayer.Character
	local HRP = Character:WaitForChild("HumanoidRootPart")

	local HRPGoals = {
		CFrame = CFrame.new(HRP.CFrame.Position, MouseHit.Position)
	}
	local HRPTween = TweenService:Create(HRP, HRPInfo, HRPGoals)
	HRPTween:Play()

	local FireBallParts = FireBall:GetChildren()
	for i, v in pairs(FireBallParts) do
		local FireBallGoals = {
			Position = (HRP.CFrame * PositionRelativeToPlayer).Position
		}
		local FireBallTween = TweenService:Create(v, HRPInfo, FireBallGoals)
		FireBallTween:Play()
	end
end

--SHOOT
function FireBallModule.Shoot(RemotePlayer, MouseHit)
	
	local Attachment1 = FireBall.P1.A1
	local Attachment2 = FireBall.P1.A2
	local Size = FireBall.P1.Size - Vector3.new(1, 1, 1)
	FireBall.P1.Trail.Enabled = true
	
	local A1X = Attachment1.Position.X ~= 0 and (Attachment1.Position.X > 0 
		and Attachment1.Position.X + Size.X/2 or Attachment1.Position.X - Size.X/2)
		or 0
	local A1Y = Attachment1.Position.Y ~= 0 and (Attachment1.Position.Y > 0 
		and Attachment1.Position.Y + Size.Y/2 or Attachment1.Position.Y - Size.Y/2)
		or 0
	local A1Z = Attachment1.Position.Z ~= 0 and (Attachment1.Position.Z > 0 
		and Attachment1.Position.Z + Size.Z/2 or Attachment1.Position.Z - Size.Z/2)
		or 0
	
	local A2X = Attachment2.Position.X ~= 0 and (Attachment2.Position.X > 0 
		and Attachment2.Position.X + Size.X/2 or Attachment2.Position.X - Size.X/2)
		or 0
	local A2Y = Attachment2.Position.Y ~= 0 and (Attachment2.Position.Y > 0 
		and Attachment2.Position.Y + Size.Y/2 or Attachment2.Position.Y - Size.Y/2)
		or 0
	local A2Z = Attachment2.Position.Z ~= 0 and (Attachment2.Position.Z > 0 
		and Attachment2.Position.Z + Size.Z/2 or Attachment2.Position.Z - Size.Z/2)
		or 0

	Attachment1.Position = Vector3.new(A1X, A1Y, A1Z)
	Attachment2.Position = Vector3.new(A2X, A2Y, A2Z)
	
	local Character = RemotePlayer.Character
	local HRP = Character:WaitForChild("HumanoidRootPart")
	HRP.CFrame = CFrame.new(HRP.CFrame.Position, MouseHit.Position)
	
	SizeTween1:Pause()
	SizeTween2:Pause()
	SizeTween3:Pause()
	SizeTween4:Pause()
	SizeTween5:Pause()
	
	local TempTable = {}
	local FireBallParts = FireBall:GetChildren()
	for i, v in pairs(FireBallParts) do

		local BV = Instance.new("BodyVelocity")
		BV.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
		BV.P = 100
		BV.Velocity = HRP.CFrame.LookVector * Speed
		
		v.Position = (HRP.CFrame * PositionRelativeToPlayer).Position
		v.Anchored = false
		BV.Parent = v
		table.insert(TempTable, BV)
	end
	
	Debris:AddItem(FireBall, LifeTime)
	
	local Explosion = false

	FireBall.P1.Touched:Connect(function(Hit)
		if Hit ~= FireBall.P2 and Hit ~= FireBall.P3 and Hit ~= FireBall.P4 and Hit ~= FireBall.P5 then
		
			local Multiplier = FireBall.P1.Size.X
			local Damage = math.floor(BaseDamage * Multiplier)
			CheckHit.Check(Hit, RemotePlayer, Table, Damage)
			
			if Explosion == false then
				Explosion = true
				
				RotationTween3:Pause()
				RotationTween4:Pause()
				RotationTween5:Pause()
				
				local RotationTween3 = TweenService:Create(FireBall.P3, FireBallRotationInfo2, FireBallRotationGoal1)
				RotationTween3:Play()
				local RotationTween4 = TweenService:Create(FireBall.P4, FireBallRotationInfo2, FireBallRotationGoal2)
				RotationTween4:Play()
				local RotationTween5 = TweenService:Create(FireBall.P5, FireBallRotationInfo2, FireBallRotationGoal3)
				RotationTween5:Play()
				
				local Particles = coroutine.create(function()
					local Emitter = FireBall.P1.ParticleEmitter
					
					local NumberSequenceKeypoints = {
						NumberSequenceKeypoint.new(0, 0.25 * Multiplier) ;
						NumberSequenceKeypoint.new(1, 1 * Multiplier)
					}
					Emitter.Size = NumberSequence.new(NumberSequenceKeypoints)
					Emitter.Speed = NumberRange.new(10 * Multiplier, 10 * Multiplier)
					
					Emitter.Enabled = true
					wait(0.1)
					Emitter.Enabled = false
				end)
				coroutine.resume(Particles)
				
				for i, v in pairs(TempTable) do
					v:Destroy()
				end
				
				for i, v in pairs(FireBallParts) do
					v.Anchored = true
					local ExplosionGoal = {
						Size = v.Size * 10 ;
						Transparency = 1
					}
					local ExplosionTween = TweenService:Create(v, ExplosionInfo, ExplosionGoal)
					ExplosionTween:Play()
				end
			end
		end
	end)
end


return FireBallModule

If I interpreted the op correctly, so theres a ModuleScript on the server that acts as the controller, and the LocalScripts are distributed to the client respectively? (1 ModuleScript and LocalScript is given to each player a single LocalScript)

EDIT: After looking at the video, do you mean that visual bug where the fireball retains? If yes did you destroy it after being used? Are visual effects handled on the client or serverside?

The module script is in replicated storage and local is in starterplayerscripts, LocalScript is used to call the ModuleScript and almost everything besides damage is done on that same ModuleScript.

Visuals are handled on the client and the wrong one got destroyed, the script breaks due to getting an error which is caused by destroying the wrong one

Does this ModuleScript run on the server aswell to replicate visuals across clients?

no, the local script activates a remote event connected to other local scripts to replicate visuals, only damage is done on the server

Is the bug on the visual or the damage? I’ve mentioned this question but you did not awnser me

The issue is that when one of the players is in the middle of using their ability and someone else uses their ability the functions in the module do not affect the correct person’s ability

So the problem is for example:

Player A uses charge
In the middle of Player A charging, Player B uses attack
Player A then instead of charging uses attack instead

If yes then can you give me the code of the remote handling for the fireballs?

Pretty much yes, if you mean the code for remote event handling then here:

--SERVICES
local RepStorage = game:GetService("ReplicatedStorage")

--REMOTE EVENTS
local FireBallEvent = RepStorage.RemoteEvents.AbilityEvents.FireBall

--FIREBALL
FireBallEvent.OnServerEvent:Connect(function(RemotePlayer, State, RemoteMouseHit)
	if State == "Create" then
		FireBallEvent:FireAllClients(RemotePlayer, State, RemoteMouseHit)
	elseif State == "Charge" then
		FireBallEvent:FireAllClients(RemotePlayer, State, RemoteMouseHit)
	elseif State == "Shoot" then
		FireBallEvent:FireAllClients(RemotePlayer, State, RemoteMouseHit)	
	end
end)