Streetball Basketball
Real streetball for your city — procedural dribbling, a skill-based shot meter, and a ball that actually bounces off the rim. Place hoops anywhere, run pickup games to 21, and climb the city leaderboard.
Streetball for FiveM — real dribbling, a skill-based shot meter, and a ball that actually bounces off the rim.
Built for Qbox (works on QBCore, and standalone if you turn stats off).
What it does
Dribbling. The ball isn't glued to your hand. It's simulated: it meets the floor in front of you, leads you when you run, comes back to your hand on a real bounce arc, and switches hands when you crossover. The bounce cadence tightens as you speed up. Everyone on the server sees the same thing — held balls cost zero bandwidth because every client derives the position from the holder's ped.
Shooting. Hold LMB and a meter fills. Somewhere on that meter is a green window, and its position is the correct power for your current distance. Release inside it and the ball goes in. Release early and it's short; release late and it's long — by an amount proportional to how far off you were. The window shrinks with distance, shrinks more if you're running or sprinting, and shrinks again if someone is guarding you. It grows back as your career makes pile up.
The ball. Shots aren't a dice roll. The release solves an exact ballistic arc to a target point, then the ball is simulated against the rim (as a torus), the backboard (as a rectangle), the floor and the world. A shot that lands 4 cm off centre rattles the rim and decides for itself. Bank shots work because the backboard is really there.
Also: passes with receiver leading, dunks off a sprint, layups, 2s and 3s (or streetball 1s and 2s), make streaks with heating up / on fire, pickup games to 21, persistent stats and a city leaderboard.
Install
- Drop the folder in
resources/[custom]/—ensure [custom]picks it up. - Start the server once. Both MySQL tables are created automatically
(
sql/install.sqlis there if you'd rather do it by hand). - Place your hoops with
/bballplacer(see below). **Nothing works until at least one hoop exists** — there are no hardcoded coordinates.
Requires ox_lib and oxmysql.
Placing hoops
/bballplacer
Admin only (ACE command.bballplacer, or a group from Config.AdminGroups).
Pick Place a new hoop, then aim at the rim. The ring, net, backboard and facing arrow preview live, with a basketball sitting in the hoop so you can see exactly where the centre is.
| Input | Does |
|---|---|
| Aim | Rim follows your crosshair |
| Scroll | Rotate (which way the hoop faces) |
| Shift + Scroll | Raise / lower |
| Arrow keys | Nudge on the flat |
| Hold Ctrl | Fine steps (1 cm / 0.5°) |
| F | Re-attach to the crosshair |
| G | Snap to regulation height (3.05 m above the floor) |
| H | Face the hoop toward where you're standing |
| RMB | Save (asks for a court name) |
| LMB | Cancel |
The facing direction matters — it's the side the backboard isn't on. Get it backwards and bank shots come off the wrong face. H is the quick fix: stand on the court, look at the hoop, press H.
Hoops that share a court name form one court: one blip, one ball rack, one pickup game. Two hoops named Chumash Beach House = a full court.
The menu also lists nearby hoops so you can move, teleport to, or delete them, and toggles a debug overlay that draws the rim, backboard and ball volumes.
Playing
| Key | Action |
|---|---|
| E | Take a ball from the rack, or pick up a loose one |
| LMB (hold) | Charge the shot meter, release to shoot |
| RMB | Pass to whoever you're facing |
| SPACE | Dunk (sprinting, inside 3.6 m) — otherwise a normal jump |
| X | Crossover |
| G | Drop the ball |
/bball grab a ball
/bball game start a pickup game at this court
/bball join join the game here
/bball leave leave
/bballstats career stats + leaderboard
Tuning
Everything lives in config.lua. The knobs worth knowing:
| Setting | Effect |
|---|---|
Shot.chargeMs | How fast the meter fills. Lower = twitchier |
Shot.greenBase / greenFalloff / greenMin | How forgiving the perfect window is, and how fast it shrinks with distance |
Shot.errorScale | Metres of long/short per unit of meter error. Raise it to punish misses harder |
Shot.arcBase / arcPerMetre | Rainbow shots vs line drives |
Dribble.period* | Bounce cadence per movement speed |
Physics.rest* | Bounciness of floor / rim / board / world |
Score.streetball | 1s and 2s instead of 2s and 3s |
Game.target / winBy / payout | Pickup game rules |
Anims | Fallback chains — see below |
If shooting feels too easy or too hard
The single most useful dial is Shot.greenBase. 0.070 is generous. Drop it to 0.045 and deep shots start needing real timing. Shot.greenFalloff controls how much harder it gets as you back up.
Notes on the implementation
Why the ball isn't a physics prop. GTA props barely bounce, their collision against a thin rim is unreliable, and the engine gives you no hook for "did it go through the hoop". The ball here is a kinematic prop positioned every frame by our own integrator, substepped finely enough that it can't tunnel through the rim.
Animations. GTA has no basketball animations, but it does have anim@sports@ballgame@handball@ (ball_idle / ball_walk / ball_run / ball_sprint), which is what the carry uses, played upper-body-only so your legs still move normally. The shot uses the projectile throw set. Every entry in Config.Anims is a chain: if a clip doesn't actually play, the resource notices, prints a line to console and falls back to the next candidate.
Sound. GTA ships no ball-bounce sound, so the bounce / rim / board / swish / catch pack in html/sfx is synthesised and played through NUI with distance-based volume. Crowd stingers use vanilla sound sets. Turn it all off with Config.Audio.enabled = false.
Anti-cheat. The server owns who is holding the ball and validates every bucket: you must be the ball's authority, near the hoop, past a rate limit, and report a sane point value. It does not re-simulate the shot — a determined cheater could report a make they didn't earn. That's a deliberate trade for responsiveness; if that matters on your server, lower Score.minShotDistance and watch the stats table.
Files
config.lua all tuning
client/util.lua helpers + the self-healing anim resolver
client/physics.lua arc solver + ball simulation and collision
client/ball.lua ball entities, procedural dribble, replication
client/sync.lua hoops, blips, ball racks
client/main.lua controls, shot meter, feedback
client/game.lua pickup games
client/placer.lua /bballplacer
server/main.lua hoops, ball authority, scoring, stats, games
html/ HUD + stats page + synthesised SFX
