Damage Module - Feedback

i made a module that handles damage and states

i wanted to see what you think about it and whether or not there are any flaws with my code
i dont usually post my scripts into the internet but since i havent made a system like this in ages i just wanted some feedback on what i should improve

anyways heres my code

-- Variables

local PathHandler = require(game:GetService("ReplicatedStorage").Modules.Qol.PathHandler)
local GlobalServicesPathHandler = require(game:GetService("ReplicatedStorage").Modules.Qol.GlobalServicesPathHandler)


local RS = GlobalServicesPathHandler.ReplicatedStorage
local CS = GlobalServicesPathHandler.CollectionService
local Players = GlobalServicesPathHandler.Players
local Lighting = GlobalServicesPathHandler.Lighting

local TweenModule = require(RS.Modules.TweenModule)
local HighlighterModule = require(RS.Modules.HighlighterModule)

local States = {}

local Types = {
	Normal = {
		Name = "Normal",
		Color = Color3.fromRGB(255, 25, 25),
	},
	Critical = {
		Name = "Critical",
		Color = Color3.fromRGB(255, 100, 0),
	},
	Stun = {
		Name = "Stun",
		Color = Color3.fromRGB(25, 25, 25),
	},
	Blocked = {
		Name = "Blocked",
		Color = Color3.fromRGB(50, 50, 255),
	},
	Negated = {
		Name = "Negated",
		Color = Color3.fromRGB(250, 250, 250),
	},
}

local DamageModule = {}

-- Functions

function DamageModule:Initialize()
	
	for i, v in pairs(Players:GetPlayers()) do
		
		States[v.Name] = {
			State = Types.Normal,
			Id = v.UserId,
		}
	end
	
	Players.PlayerAdded:Connect(function(Player: Player)
		
		States[Player.Name] = {
			State = Types.Normal,
			Id = Player.UserId,
		}
	end)
end

function DamageModule.New(Character: Model, Damage: number, Damager: Player, Indicator: boolean, Time: number)
	assert(Character, "Invalid Character")
	Damage = Damage or 10
	assert(Damager, "Invalid Damager")
	local Type
	Indicator = Indicator or true
	Time = Time or 2
	
	local RootPart: BasePart = Character:FindFirstChild("HumanoidRootPart")
	local Humanoid: Humanoid = Character:FindFirstChildOfClass("Humanoid")
	local Player: Player = Players:GetPlayerFromCharacter(Character)
	Type = States[Player.Name].State
	
	local _Indicator: BillboardGui = script.Indicator:Clone()
	_Indicator:AddTag("Indicator")
	local Text: TextLabel = _Indicator.Damage
	Text.TextColor = Types[Type].Color
	Text.Text = Damage
	Text.TextTransparency = 1
	
	_Indicator.Adornee = RootPart
	Humanoid:TakeDamage(Damage)
	HighlighterModule:SuddenHighlight(Character, Types[Type].Color, "Inside", 0, 1)
	TweenModule:SimpleTween(Text, 0.1, {TextTransparency = 0})
	TweenModule:SimpleTween(_Indicator, 1, {StudsOffset = Vector3.new(math.random(-2, 2), 0, math.random(-2, 2))})
	
	task.wait(Time)
	
	TweenModule:SimpleTween(Text, 0.1, {TextTransparency = 1})
	task.wait(0.1)
	_Indicator:Destroy()
end

function DamageModule.Tick(Character: Model, Damage: number, Damager: Player, Time: number, Indicator: boolean, _Time: number)
	assert(Character, "Invalid Character")
	Damage = Damage or 1
	assert(Damager, "Invalid Damager")
	Time = Time or 5
	Indicator = Indicator or true
	_Time = _Time or 2
	
	repeat
		DamageModule.New(Character, Damage, Damager, Indicator, _Time)
		task.wait(1)
		Time -= 1
	until Time == 0
end

function DamageModule:SetState(User: Model | Player, Type: string)
	assert(User, "Invalid User")
	Type = Type or Types.Normal
	if Type ~= (Types.Normal.Name or Types.Critical.Name or Types.Stun.Name or Types.Blocked.Name or Types.Negated.Name) then
		error("Invalid Type")
		return
	end
	
	local Player: Player
	if User:IsA("Player") then
		Player = User
	else
		User = Players:GetPlayerFromCharacter(User)
	end
	local State
	State = States[Player.Name].State
	HighlighterModule:SuddenHighlight(User, Types[Type].Color, "Inside", 0, 1)
	
	State = Type
end

function DamageModule:GetState(User: Model | Player)
	assert(User, "Invalid User")
	
	local Player: Player 
	if User:IsA("Player") then
		Player = User
	else
		Player = Players:GetPlayerFromCharacter(User)
	end
	
	local State = States[Player.Name].State
	
	if State == nil then
		warn("Invalid State, Did you initialize the module ? Starting the initialization process automatically...")
		DamageModule:Initialize()
	end
	
	return State
end

function DamageModule:GetStateFromId(Id: number)
	assert(Id, "Invalid Id")
	
	local Player: Player = Players:GetPlayerByUserId(Id)
	local State = States[Player.Name].State
		
	if State == nil then
		warn("Invalid State, Did you initialize the module ? Starting the initialization process automatically...")
		DamageModule:Initialize()
	end
	
	return State
end

function DamageModule:GetIndicators(Character: Model)
	assert(Character, "Invalid Character")
	
	local Indicators = {}
	
	for i, v in pairs(CS:GetTagged("Indicator")) do
		if v:IsDescendantOf(Character) then
			Indicators[v] = v
		end
	end
	
	return Indicators
end

function DamageModule._RemoveIndicators()
	
	for i, v in pairs(CS:GetTagged("Indicator")) do
		v:Destroy()
	end
end

return DamageModule

please feel free to tell me what could be improved and what is redundant, as i am mostly self taught, so i feel like there are some things that arent optimized with my code

2 Likes