expert
60 min

Advanced Combat Systems

Build a complete combat system with hitboxes, combos, and abilities.

Hitbox DetectionCombo SystemsCooldownsDamage Calculation

1
Hitbox Detection

Create precise hitbox detection for combat.

Region3 Hitbox Detection

local function getPlayersInHitbox(position, size)
  local region = Region3.new(position - size/2, position + size/2)
  region = region:ExpandToGrid(4)
  
  local partsInRegion = workspace:FindPartsInRegion3(region, nil, 100)
  local hitPlayers = {}
  
  for _, part in ipairs(partsInRegion) do
    local humanoid = part.Parent:FindFirstChild("Humanoid")
    if humanoid then
      local player = game.Players:GetPlayerFromCharacter(part.Parent)
      if player and not hitPlayers[player] then
        hitPlayers[player] = true
        table.insert(hitPlayers, player)
      end
    end
  end
  
  return hitPlayers
end

Region3 creates a 3D box to detect players in an area.

Raycast Hitbox

local function performRaycastAttack(origin, direction, distance)
  local raycastParams = RaycastParams.new()
  raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
  raycastParams.FilterDescendantsInstances = {character}
  
  local result = workspace:Raycast(origin, direction * distance, raycastParams)
  
  if result then
    local hitPart = result.Instance
    local humanoid = hitPart.Parent:FindFirstChild("Humanoid")
    
    if humanoid then
      -- Deal damage
      humanoid:TakeDamage(25)
      print("Hit at position: " .. tostring(result.Position))
      return true
    end
  end
  
  return false
end

Raycasts are perfect for sword slashes and projectile weapons.

💡 Tips:

  • • Use Region3 for area attacks (explosions, ground slams)
  • • Use Raycasts for linear attacks (swords, bullets)
  • • Always check if humanoid exists before dealing damage

2
Combo System

Track and execute combo attacks.

Combo Tracker

local ComboSystem = {}
ComboSystem.__index = ComboSystem

function ComboSystem.new()
  local self = setmetatable({}, ComboSystem)
  self.combo = 0
  self.maxCombo = 5
  self.lastHitTime = 0
  self.comboWindow = 2  -- Seconds to continue combo
  return self
end

function ComboSystem:hit()
  local currentTime = tick()
  
  -- Check if combo expired
  if currentTime - self.lastHitTime > self.comboWindow then
    self.combo = 0
  end
  
  self.combo = math.min(self.combo + 1, self.maxCombo)
  self.lastHitTime = currentTime
  
  return self.combo
end

function ComboSystem:getDamageMultiplier()
  return 1 + (self.combo * 0.1)  -- +10% per combo
end

function ComboSystem:reset()
  self.combo = 0
end

Track combo count and apply damage multipliers.

3
Cooldown System

Manage ability cooldowns.

Ability Cooldown Manager

local CooldownManager = {}
CooldownManager.__index = CooldownManager

function CooldownManager.new()
  local self = setmetatable({}, CooldownManager)
  self.cooldowns = {}
  return self
end

function CooldownManager:isOnCooldown(abilityName)
  local cooldown = self.cooldowns[abilityName]
  if not cooldown then return false end
  
  return tick() < cooldown
end

function CooldownManager:startCooldown(abilityName, duration)
  self.cooldowns[abilityName] = tick() + duration
end

function CooldownManager:getRemainingTime(abilityName)
  local cooldown = self.cooldowns[abilityName]
  if not cooldown then return 0 end
  
  local remaining = cooldown - tick()
  return math.max(0, remaining)
end

-- Usage
local cooldowns = CooldownManager.new()

if not cooldowns:isOnCooldown("Fireball") then
  -- Cast fireball
  print("Fireball cast!")
  cooldowns:startCooldown("Fireball", 5)
else
  local remaining = cooldowns:getRemainingTime("Fireball")
  print("Cooldown: " .. math.ceil(remaining) .. "s")
end

Track multiple ability cooldowns with timestamps.

💡 Tips:

  • • Use tick() for accurate timing
  • • Store cooldowns per player
  • • Display cooldown UI for better feedback

Practice Exercises

Exercise 1: Basic Combat System

Create a function that deals damage with a combo multiplier.

Starter Code:

local combo = 3

local function dealDamage(baseDamage, combo)
  -- Calculate damage with combo multiplier
  
end

print(dealDamage(50, combo))
Show Solution
local combo = 3

local function dealDamage(baseDamage, combo)
  local multiplier = 1 + (combo * 0.1)
  return baseDamage * multiplier
end

print(dealDamage(50, combo))  -- 65 damage

Ready for more?

Continue your learning journey

Executors.Online - Your Roblox Developer Hub