Scripts 2026-04-09

Agency-ProgressBar: The UI Detail That Quietly Elevates Every Script

TDYSKY

TDYSKY

Founder & Lead Developer at Agency Scripts

A Tiny Script, An Outsized Effect

Progress bars show up everywhere in FiveM — lockpicking, repairing, washing money, mining, medical aid. Default implementations are functional but flat. Agency-ProgressBar is our take on what this utility should feel like when someone cares about the details.

The Anatomy of a Good Progress Bar

A good progress bar communicates four things simultaneously: what action is happening, how far along you are, how much time remains, and whether you can cancel. Most implementations only handle the first two. Agency-ProgressBar shows all four, with subtle animations that make progress feel smooth rather than chunky.

Cancellation That Works

Player-initiated cancellation triggers a brief fade-out animation that returns the bar's opacity to zero in 300ms. No jarring disappearance. Developers can register a cancel callback so scripts clean up properly when players walk away from an action mid-progress.

Contextual Positioning

The bar appears near the relevant on-screen element — above your head for self-targeted actions, above the target NPC for interactive actions. No more reading action status from the bottom of the screen while something happens at the top. This contextual positioning is a subtle UX upgrade that players feel without being able to name.

The Export Pattern

Like all our utility scripts, Agency-ProgressBar exposes a simple exports API: exports['agency-progressbar']:Play({label, duration, canCancel, onCancel, onDone}). Drop it into any script in minutes. It composes with Agency-Notify, Agency-Hud, and the rest of our ecosystem without any special configuration.

Installation & Setup

Agency-ProgressBar is a drop-in utility with zero database dependency. Download from Tebex, drop the folder into your resources directory, add ensure agency-progressbar to server.cfg. That's it. The resource starts working immediately and any script can call the exports API on the next restart.

If you're replacing an existing progress bar (ox_lib's progressBar, qb-progressbar, etc.), a find-and-replace on the export call name handles most migrations in minutes. The parameter structure is intentionally close to common community patterns.

Configuration Options

Open config.lua to adjust defaults:

  • Default position — above player head (default) or fixed bottom-center.
  • Color scheme — the fill color gradient. Supports single color, two-stop gradient, or severity-mapped (green for normal, orange for slow, red for critical).
  • Cancel key — which key cancels a cancellable progress bar. Default: backspace.
  • Cancel animation — fade-out (default), slide-out, or instant disappear.
  • Time display — show remaining seconds (default), percentage, or neither.
  • Minimum duration — actions shorter than this threshold skip the bar entirely. Default: 500ms.

Framework Compatibility

Agency-ProgressBar is fully standalone with no framework dependencies. It functions identically on QBCore, ESX, and custom server setups. The exports API is the only integration surface — no shared globals, no framework events, no permission checks. Install it and call it from any script regardless of origin.

Why This Matters for Roleplay

Progress bars are a UX primitive that appears in dozens of gameplay moments — lockpicking, handcuffing, crafting, healing, evidence collecting, hacking. When those bars look mismatched or behave inconsistently across different scripts, it creates subtle visual noise that undermines server coherence.

When every progress bar on your server uses Agency-ProgressBar, the visual language is unified. Players develop intuition for what the bar means and how it behaves. The cancellation behavior is consistent. The typography matches the rest of your UI. Small things, but they compound into a noticeably more polished player experience.

The contextual positioning matters more than it sounds. A progress bar anchored to your character's head during a lockpick keeps your focus on the action, not on a corner of the screen. During tense moments — being chased while picking a lock, for example — this keeps players spatially aware while the bar is visible.

Frequently Asked Questions

Can I run multiple progress bars simultaneously?

Yes. Each Play() call returns an ID and manages its own state. Multiple bars stack vertically above the player with sensible spacing. This is useful for multi-step actions where progress on parallel tasks needs to be visible simultaneously, though most RP scenarios use one bar at a time.

How do I attach a progress bar to a prop or NPC instead of the player?

Pass a target = {type = 'entity', id = entityNetId} field in the options table. The bar hovers above the specified entity rather than the player. Use this for repair actions, medical actions on downed players, or any case where the action's focus is external.

Can the bar be forced non-cancellable from the server side?

Yes. Set canCancel = false when calling Play(). The cancel key has no effect and no cancel animation plays. This is appropriate for server-enforced actions (arrest animations, scripted cutscenes) where player interruption would break the flow.

Does this work with ox_lib animations?

Yes. Agency-ProgressBar is animation-agnostic — you handle animations in your own script alongside the progress bar call. The bar is purely a UI element. Pair it with any animation library or raw FiveM animation calls independently.

Requirements

  • FiveM server (any framework or standalone)
  • cfx.re account with valid Agency-ProgressBar license
  • No database dependency
  • No external resource dependencies

Practical Integration Examples

Here are common patterns for integrating Agency-ProgressBar with existing scripts:

Lockpicking: Call Play({label = 'Picking lock...', duration = 8000, canCancel = true, onCancel = cleanupFunction}) at the start of a lockpick attempt. Pair with the lockpick mini-game running in parallel. If the mini-game fails, call Dismiss() with the returned ID. If it succeeds, let the bar complete naturally.

Medical treatment: Use target = {type = 'entity', id = patientNetId} to anchor the bar above the patient rather than the medic. Players watching the scene see progress happening at the point of treatment, not floating over the medic's head.

Evidence collection: Set canCancel = false for scripted evidence collection that shouldn't be interruptable (to prevent players from cancelling to avoid leaving fingerprints at the scene). The non-cancellable bar communicates to the player that this action is mandatory, not optional.

Server-side actions: Fire a progress bar on the client while a server-side action runs asynchronously. When the server callback returns, either let the bar complete or dismiss it early depending on the server-side result. The visual duration should approximately match the expected server processing time.

Share this article

Ready to upgrade your server?

Check out our premium FiveM scripts in the Agency Scripts store or join our Discord community for support and updates.