Volleyball Script Configuration

5 min read

View Volleyball Script in the WXMAPS store

Configuration

config.lua is deliberately lean: only the knobs a server owner would realistically change. Ball physics feel, how a dead ball bounces, hit tuning, the shot bands, netcode timings, the animation clip map and the contact measurements are named constants inside the module that owns each of them, not config entries. That is on purpose; they are balance, not settings.

Who gets the tools

Config.Admin = {
    aces        = { 'vsvb.admin' },          -- ACE permissions
    groups      = { 'admin', 'superadmin' }, -- ESX / QBCore groups, if you run one
    identifiers = {},                        -- a hard list
    resolve     = nil,                       -- or your own function(src)
}

Per player, enforced on the server: the client gate only decides whether a menu opens, and every write (a saved court, a placed prop, an erased map object) is re-checked over the wire. There is no server-wide dev switch, and nothing has to be turned off for production. See Admin & commands.

Config.Debug = false   -- console diagnostics only. It gates no tool and no overlay

Match rules

Config.Rules = {
    pointsToWin  = 15,
    winBy        = 2,
    cap          = 21,          -- 0 = no cap
    sets         = 1,           -- best-of = sets * 2 - 1
    maxTouches   = 3,           -- 0 = unlimited / arcade
    teamSizes    = { 1, 2, 3 }, -- which formats are offered
    serveSeconds = 15,

    fillWithAI        = true,   -- fill empty seats with AI
    stamina           = true,
    serveStamina      = true,   -- price the serve type against the bar
    teammateAimAssist = true,   -- looking at a team-mate locks the pass onto them
    netAssist         = false,

    rematchSeconds    = 20,     -- the result screen's ceiling. 0 takes it out
}

Explained in full on Rules, stamina & AI.

fillWithAI = false is strict PvP, and it is the setting that most looks like a bug when it is not. A 3v3 court then needs six real players before anything starts, so "Join a match" appears to do nothing while you wait.

How players start a match

Config.RequireReferee = true

true means matches start only through a placed referee desk. false also allows /vb near a court.

true with no desk placed means nobody can start a match at all. Place one, or set this false while you are authoring a new location.

Training

Config.Training = {
    enabled     = true,
    matchPoints = 5,   -- the short bout at the end of a lesson
    matchWinBy  = 1,
    matchCap    = 0,
}

Courts, net and ball

Config.Net = {
    model         = 'wx_volleyball_net',
    poles         = 'wx_volleyball_poles',
    headingOffset = 90.0,   -- align the assembly to the court
    zOffset       = 1.732,
    polesZOffset  = 1.732,
}

Config.Courts = { floorHeadingOffset = 90.0, floorZOffset = 0.0, floors = { ... } }

Config.Ball = { model = 'prop_beach_volball02', radius = 0.11 }

The net and poles spawn together at every court and are switched off together by the creator's B. Which floor a court uses is stored per court. Config.Courts.floors holds one measured row per floor model, produced by /vb_mark. See Courts & the builder.

The ball model is cosmetic; no physics reads it. Its radius is the one non-cosmetic field; it is how far the ball rests above the sand and how far off the net it stops.

The rest, in one table

KeyWhat it controls
Config.DrinksThe three cans: which item names map to which effect, what each one does and for how long, and the cool box's prices. See Beach circle & drinks
Config.FreeplayThe beach circle: spacing between neighbours, maxPlayers, invite radius and timeout, the ball prop, whether sprinting costs stamina
Config.BallCarryThe ball carts: where they stand, the cart and ball models, the load in take order, refillSeconds, the item name, maxCarry
Config.Teamsenabled, maxMembers, invite timeout, autoSide, partyEnabled, and imageHosts: empty means any https host may supply a banner
Config.SpectateBounds on who sees a live match, a radius and a runaway guard, not a switch
Config.SfxThe audio bank, the mix, distances and which clip plays for what
Config.BuilderThe placement catalogue and objectLimit (150 per court)
Config.AidsOptional on-screen helpers. The incoming-ball arc is the one that is on as shipped; the reach rings and the diagnostics are off
Config.CourtLines · Config.HideMinimapDraw the court lines · hide the minimap during a match
Config.ThemeNUI colours: the scoreboard, panels and meters all read them

Sound

The resource ships its own audio bank (21 waves with a dat54), so hits, grunts, the net, the ball on sand and the crowd all go through the game's own mix with real 3D position and distance. The clips rows in Config.Sfx name waves inside that pack, not files on disk.

A name that is not in the pack is simply silent, with no error to catch it. /vb_sound (admin) plays every configured sound by name, printing each before it plays; that is how you check one. Adding a new sound means rebuilding the pack, not copying a file in.

Sound levels are baked into the pack. Config.Sfx.volume and Config.Sfx.mix record the balance the pack was built with; editing them does not change playback. Player volume is the SFX slider in GTA's own audio settings, which this script sits under like any other game sound.

What you can edit

The resource ships under Cfx asset escrow, and the files a buyer has to read or edit are left unencrypted on purpose:

config.luaevery setting on this page
locales/*.jsontranslations
inventory/ox_inventory_items.luathe item rows you copy into ox_inventory
install.sqlthe schema, for a backup or a manual install
README.mdthe resource's own documentation

Gameplay tuning that the client and the server both have to agree on, such as the physics, the shot bands and the contact timing, is deliberately not exposed: the two sides disagreeing about it is how a match desyncs.

Localisation

locales/en.json, read through the ox_lib locale system. Every player-facing string is in there: shot prompts, serve types, the referee menu, training, teams, the result screen. Copy the file to your language code rather than editing Lua.