§ How to · with Forge AI

How to make a Roblox combat system (with AI)

A Roblox combat system needs four wired-up parts: server-authoritative damage, a RemoteEvent contract, health bar UI, and respawn logic. Forge AI generates all four from one prompt — no client-trusted damage, no broken RemoteEvents, no missing services.

5 files · 140 lines · 42 seconds · 1 credit. Drop into your place and press Play.

Server-authoritative damage

Damage is calculated on the server with range, cooldown, and target validation. The client never gets to write a damage number.

RemoteEvent guards

Cooldown table, range check (8 studs default), valid-target check, input sanitization. Exploiters can spam the remote — server still rejects them.

Health bar UI

Pooled BillboardGui health bars on every Humanoid. Smooth tween on damage, color shifts red below 30%.

Damage numbers

Pooled TextLabel pop-ups that float up and fade. Spawn-on-server-event so all players see hits, not just the attacker.

Respawn flow

On death: drop weapons, wait 5s, respawn at SpawnLocation, re-equip starter sword. Configurable in one constant.

Anti-exploit by default

All damage server-side, all guards cooldown-based, RemoteEvent rate-limited per UserId. Forge audit flags any client-trusted damage in your existing code.

Files Forge AI ships for this prompt

5 files · 140 lines · 42 seconds · 1 credit

ServerScriptService/CombatServer.lua

RemoteEvent listener with range/cooldown guards and damage calc

84 lines

StarterPlayerScripts/CombatClient.lua

Input handler that fires the RemoteEvent — no damage logic

32 lines

ReplicatedStorage/Remotes/CombatRemote

RemoteEvent instance

instance

StarterGui/HealthBarUI.lua

BillboardGui health bar with damage tween

18 lines

StarterGui/DamageNumbers.lua

Pooled damage number spawner

6 lines

Sample output: ServerScriptService/CombatServer.lua

--!strict
-- ServerScriptService/CombatServer.lua  (Forge AI · 84 lines)
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local CombatRemote = ReplicatedStorage:WaitForChild("Remotes"):WaitForChild("CombatRemote")

local cooldowns: { [number]: number } = {}
local DAMAGE = 18
local COOLDOWN = 0.45
local RANGE = 8

CombatRemote.OnServerEvent:Connect(function(player: Player, targetUserId: number)
    local now = tick()
    if cooldowns[player.UserId] and now - cooldowns[player.UserId] < COOLDOWN then return end
    local attacker = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
    local target = Players:GetPlayerByUserId(targetUserId)
    local victim = target and target.Character and target.Character:FindFirstChild("HumanoidRootPart")
    if not attacker or not victim then return end
    if (attacker.Position - victim.Position).Magnitude > RANGE then return end
    cooldowns[player.UserId] = now
    local humanoid = victim.Parent:FindFirstChildOfClass("Humanoid")
    if humanoid then humanoid:TakeDamage(DAMAGE) end
end)

Building a Roblox combat system

A combat system is the heart of most Roblox PvP and PvE games — and it is the easiest place to ship exploit-friendly code by accident. The single most common mistake is letting the client send a damage number. Once a client can write damage, an exploiter writes 9999 and one-shots the lobby. Forge AI is built around server authority so this class of bug never reaches your place.

The Forge AI prompt "build me a combat system with a sword, health bar, damage numbers, respawn" produces a 5-file system in 42 seconds. The server script holds the cooldown table and the damage calculation. The client script fires a RemoteEvent with the target UserId — that is all the client gets to do. The server then checks distance, cooldown, target validity, and applies damage via Humanoid:TakeDamage. No client-trusted state, no possible exploit path.

The damage number system uses a pooled TextLabel BillboardGui per Humanoid — it spawns on a server event, replicates to all clients, and tweens upward then fades. Pooling matters: spawning a fresh GUI on every hit causes frame drops in any 10+ player server. Forge pools by default. The health bar follows the same pattern — one BillboardGui per Humanoid, smooth tween on damage, red below 30%, pooled across respawns.

If you already have a combat system and want Forge to upgrade it, the audit prompt finds client-trusted damage in seconds. Common upgrades: replacing FireServer-with-amount calls, adding range checks to existing remotes, pooling damage number GUIs that currently Instance.new on every hit.

See more on the Luau generator, the game builder, or browse the full blog.

Frequently asked

Is the combat system anti-exploit by default?+

Yes. Damage is calculated server-side, every RemoteEvent fire goes through range check, cooldown, valid-target check, and rate limit. The client only fires the intent — it never gets to send a damage number.

Can I customize damage, cooldown, range?+

Yes. The top of CombatServer.lua exposes DAMAGE, COOLDOWN, RANGE as named constants. Change them in code or extend the module to read from a Config table.

Does it work with non-sword weapons?+

The same RemoteEvent contract works for ranged and magic. The server validates by attacker→target line of sight; the client controls when to fire (hit detection, projectile cast, mouse cast). Forge can extend with a separate prompt.

What about NPC enemies?+

Use the boss fight or NPC system prompt. Combat system focuses on PvP — NPCs need pathfinding, AI states, and aggro tables which Forge generates separately.

How long does generation take?+

42 seconds for a fresh combat system. Forge writes 5 files (140 lines), inserts each into the right service, wires the RemoteEvent, and builds the UI. You press Play immediately.

Related Forge AI prompts