§ How to · with Picoo

How to make an ability system with cooldowns in Roblox

By Sametcan Tasgiran, Founder & Developer·Published ·Updated

Abilities are easy to fake and hard to trust: the hotbar is the visible part, but the cooldown is the part players will try to break.

If the cooldown lives on the client, it is a suggestion. Every cooldown, cost and damage number here is enforced on the server.

Hotbar with keybinds

Per-ability key (Q/E/R/F by default), icon, name, and a cooldown veil that sweeps as it recharges.

Six ability kinds

Projectile, dash, AoE slam and beam by default; ask for five or six abilities to add a buff and a heal. Each kind plays differently, so the kit is not four flavours of the same nuke.

One balance table

Cooldown, cost, damage, range, power and duration all live in a single registry ModuleScript.

Mana with regen

A 100-point mana bar that refills 6 per second. A cast you cannot afford is refused and the bar flashes red.

Mobile

Every slot is a button, so phone players tap what desktop players press.

Themes

fire (the default), water, ice, lightning, shadow, wind or nature: each sets the colour, ability names and icons.

Files Picoo ships for this prompt

5 files · 419 lines · one recipe call

ReplicatedStorage.AbilityConfig (ModuleScript)

THE registry. Copy a row and it binds its key and casts with no new code; a matching Slot in the hotbar makes it clickable.

52 lines

ServerScriptService.AbilityServer

Cooldowns, mana, hit detection and damage. The authority.

254 lines

StarterGui.AbilityHUD (ScreenGui)

48 instances in Edit mode with the default four abilities. Restyle the hotbar without pressing Play.

instance

StarterGui.AbilityHUD.AbilityClient

Keybinds, taps, the cooldown sweep, and the dash impulse after approval.

113 lines

ReplicatedStorage.AbilityRemotes

CastAbility and AbilityState RemoteEvents.

instance

Sample output: ReplicatedStorage.AbilityConfig

--!strict
-- Generated by Picoo recipe: ability_system (fire)
--
-- THIS IS THE REGISTRY. Everything reads from it: the hotbar builds its slots
-- from these rows, the client binds these keys, the server enforces these
-- cooldowns and costs. To re-balance, edit a number here — nothing else.
-- To ADD an ability, copy a row, give it a unique id and a free key, and set
-- kind to one of: "projectile" | "dash" | "aoe" | "beam" | "buff" | "heal".
-- (A new row needs a matching Slot in StarterGui.AbilityHUD.Hotbar to be
-- clickable, but it will bind its KEY and cast with no further code.)

export type Ability = {
	id: string,
	name: string,
	icon: string,
	key: string,
	kind: string,
	cooldown: number,   -- seconds
	cost: number,       -- Mana
	damage: number,     -- per hit, server-applied
	range: number,      -- studs (projectile travel / beam length / aoe radius)
	power: number,      -- dash velocity, buff bonus, or heal amount
	duration: number,   -- seconds, buffs only
}

local abilities: { Ability } = {
	{ id = "fire_projectile", name = "Fireball", icon = "🔥", key = "Q", kind = "projectile", cooldown = 1.5, cost = 12, damage = 18, range = 180, power = 95, duration = 0 },
	{ id = "fire_dash", name = "Flame Rush", icon = "💨", key = "E", kind = "dash", cooldown = 4, cost = 15, damage = 0, range = 0, power = 78, duration = 0 },
	{ id = "fire_aoe", name = "Meteor Slam", icon = "☄️", key = "R", kind = "aoe", cooldown = 9, cost = 35, damage = 40, range = 22, power = 0, duration = 0 },
	{ id = "fire_beam", name = "Flamethrower", icon = "🌋", key = "F", kind = "beam", cooldown = 6, cost = 28, damage = 32, range = 120, power = 0, duration = 0 },
}

Building an ability system with cooldowns in Roblox

An ability system is two problems wearing one costume. The visible one is the hotbar: icons, keybinds, a cooldown that sweeps. The real one is trust — whether the numbers can be edited by the person they are meant to constrain.

Picoo splits it accordingly. ReplicatedStorage.AbilityConfig is the single balance table: id, key, kind, cooldown, cost, damage, range, power, duration. The hotbar's slots are generated from it, the client binds its keys from it, and the server enforces it. Re-balancing is editing a number in one file; adding an ability is copying a row, plus a hotbar Slot if it should be clickable.

ServerScriptService.AbilityServer is the authority. It keeps per-player cooldown timestamps and mana, and a cast that arrives early or unaffordable is rejected — the client's sweeping veil is presentation, not permission. There is a flood guard too: no legitimate client casts twice inside 100ms.

Hits use GetPartBoundsInRadius and Raycast rather than .Touched. Touched fires once per touching part, which means a single contact can raise it 5-30 times — with .Touched damage, whether your fireball does 18 or 180 depends on how the character's limbs happened to overlap.

Dash is the one effect applied on the client, after the server approves it, because character physics is client-owned and a server-side velocity write on someone else's character rubber-bands. The pattern generalises: validate where the truth is, act where the ownership is.

Six kinds are available: projectile, dash, AoE slam, beam, buff and heal, handed out in that order, so the default four are projectile, dash, AoE slam and beam. Themes cover fire, water, ice, lightning, shadow, wind and nature. Two to six abilities, keys of your choosing.

See more on the Luau generator, the AI Luau script writer, the 3D model generator and the game builder, read how Picoo compares with ChatGPT, or browse the full blog.

Frequently asked

Where do I change damage or cooldown?+

One file: ReplicatedStorage.AbilityConfig. The server enforces those numbers, and the client binds its keys and times its cooldown sweep from the same table, so editing a number there is the whole change. Copy a row to add an ability: it binds its key and casts with no new code, and a matching Slot in StarterGui.AbilityHUD.Hotbar makes it clickable.

Can a player fake a shorter cooldown?+

No. The client's cooldown veil is display only; the server keeps its own per-player timestamp and silently rejects an early cast. Same for mana — the balance lives server-side and a spammed remote just gets refused.

Why is the dash applied on the client?+

Character physics is client-owned. A server-side velocity write on a player's own character fights their simulation and rubber-bands. The server validates the cast and approves it; the client applies the impulse. Every damaging effect stays server-side.

Does this work on mobile?+

Yes. Each hotbar slot is a button, so a tap casts exactly like the keyboard shortcut. No separate mobile control set to maintain.

How does it detect hits?+

GetPartBoundsInRadius for projectiles and AoE, Raycast for beams — never .Touched. Touched fires once per touching part, so a single contact can raise it 5-30 times and multiply your damage by luck.

Related Picoo prompts