-- Settings local DAMAGE_COLOR = Color3.fromRGB(255, 75, 75) local DEATH_COLOR = Color3.fromRGB(255, 0, 0) local HEAVY_HIT_THRESHOLD = 50 local STACK_RESET_TIME = 5.0 -- Damage memory lasts 5s local DISPLAY_TIME = 1.3 -- Animation lasts 1.3s local BASE_SHAKE = 0.12 local BASE_SIZE = 2.2 local DamagePools = {} -- Persistent damage totals local ActiveVisuals = {} -- Current active Billboard per humanoid local function formatDamage(amount) local absAmount = math.abs(amount) return (absAmount % 1 == 0) and tostring(math.floor(absAmount)) or string.format("%.1f", absAmount) end local function createIndicator(humanoid, amount, isDeath) local root = humanoid.Parent:FindFirstChild("HumanoidRootPart") or humanoid.Parent:FindFirstChild("Head") if not root then return end -- 1. Handle the Persistent Damage Pool (5s Memory) if not DamagePools[humanoid] then DamagePools[humanoid] = {Total = 0, LastHit = 0} end local pool = DamagePools[humanoid] -- If it's been more than 5s, start the stack over if tick() - pool.LastHit > STACK_RESET_TIME then pool.Total = math.abs(amount) else pool.Total = pool.Total + math.abs(amount) end pool.LastHit = tick() local displayAmount = pool.Total -- 2. Handle the Instant Visual Update -- If a number is already floating, destroy it so we can "restart" the animation if ActiveVisuals[humanoid] then ActiveVisuals[humanoid]:Destroy() ActiveVisuals[humanoid] = nil end -- Create Billboard local billboard = Instance.new("BillboardGui") billboard.Size = UDim2.new(BASE_SIZE, 0, BASE_SIZE, 0) billboard.Adornee = root billboard.AlwaysOnTop = true ActiveVisuals[humanoid] = billboard local label = Instance.new("TextLabel") label.Size = UDim2.new(1, 0, 1, 0) label.BackgroundTransparency = 1 label.TextScaled = true label.Font = Enum.Font.Cartoon label.TextStrokeTransparency = 0 label.Rotation = math.random(-15, 15) local isHeavy = displayAmount >= HEAVY_HIT_THRESHOLD if isDeath then label.Text = "DEATH" label.TextColor3 = DEATH_COLOR else label.Text = formatDamage(displayAmount) label.TextColor3 = isHeavy and Color3.new(1, 1, 1) or DAMAGE_COLOR end label.Parent = billboard billboard.Parent = game.CoreGui -- 3. Visual Animation Logic (Exactly 1.3s) task.spawn(function() local startTime = tick() while (tick() - startTime < DISPLAY_TIME) and (ActiveVisuals[humanoid] == billboard) do local elapsed = tick() - startTime local progress = elapsed / DISPLAY_TIME -- Strobe if isHeavy and not isDeath then label.TextColor3 = (math.sin(tick() * 25) > 0) and Color3.new(1, 1, 1) or Color3.new(1, 0, 0) end -- Shake & Float local currentShake = isDeath and (BASE_SHAKE * 3) or (isHeavy and BASE_SHAKE * 2 or BASE_SHAKE) local yOffset = 3 + (progress * 3.5) -- Size Pop local sizeMult = 1.0 if progress < 0.25 then sizeMult = isDeath and 2.0 or (isHeavy and 1.7 or 1.4) sizeMult = sizeMult - (progress * 1.5) end billboard.Size = UDim2.new(BASE_SIZE * sizeMult, 0, BASE_SIZE * sizeMult, 0) local shakeX = (math.random() - 0.5) * currentShake local shakeY = (math.random() - 0.5) * currentShake billboard.ExtentsOffset = Vector3.new(shakeX, yOffset + shakeY, 0) -- Fade label.TextTransparency = progress label.TextStrokeTransparency = progress task.wait() end -- Only destroy and clean up if this specific billboard is still the active one if ActiveVisuals[humanoid] == billboard then billboard:Destroy() ActiveVisuals[humanoid] = nil end end) end -- Humanoid Watcher local function watch(hum) local lastH = hum.Health hum.HealthChanged:Connect(function(newH) local d = newH - lastH if d <= -0.1 then createIndicator(hum, d, (newH <= 0 and lastH > 0)) end lastH = newH end) end for _, v in pairs(workspace:GetDescendants()) do if v:IsA("Humanoid") then watch(v) end end workspace.DescendantAdded:Connect(function(v) if v:IsA("Humanoid") then watch(v) end end)