> For the complete documentation index, see [llms.txt](https://izzyshop-1.gitbook.io/izzyshop-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://izzyshop-1.gitbook.io/izzyshop-docs/izzyshop-resources/izzy-strafe/configuration.md).

# Configuration

### Player Usage

| Action               | Default                            |
| -------------------- | ---------------------------------- |
| Open ranked UI       | `/strafe` or **F10**               |
| Accept party invite  | **F5**                             |
| Decline party invite | **F6**                             |
| Lobby entry          | World ped/blip + **E** (or target) |

### Match Flow

1. Open UI → select mode (1v1 … 10v10) → join queue or create a custom room.
2. When enough players are found → accept/reject screen (timeout auto-rejects).
3. Weapon vote → locked weapon displayed → match starts.
4. **Warmup** (optional) → **freeze countdown** (3-2-1) → round begins.
5. Hold **SHIFT** (or aim) and complete **WASD / WDSA** strafe patterns to score.
6. Leaving the arena radius teleports you to `center` and **resets your score**.
7. Match ends → results screen → rewards → return to pre-match position.

### Configuration

{% hint style="info" %}
All main settings live in `shared/config.lua`.
{% endhint %}

| Option                     | Description                                                           |
| -------------------------- | --------------------------------------------------------------------- |
| `Config.Core`              | `'auto'` \| `'esx'` \| `'qb'` \| `'oldqb'` \| `'qbox'`                |
| `Config.SQL`               | `'auto'` \| `'oxmysql'` \| `'ghmattimysql'` \| `'mysql-async'`        |
| `Config.Language`          | UI locale: `en`, `tr`, `es`, `fr`, `de`, `pt`, `pl`, `nl`, `it`, `ru` |
| `Config.UseCharacterNames` | `true` = IC name in UI/leaderboard; `false` = Steam/FiveM name        |
| `Config.Notify`            | Notify resource (`'auto'` or specific name — see config comments)     |

### Open Command

```lua
OpenCommand = {
    command = 'strafe',
    enabled = true,
    key = 'F10',   -- empty string = no keybind
},
```

### Matchmaking

```lua
Matchmaking = {
    minTeamSize = 1,
    maxTeamSize = 10,
    bestOf = 1,          -- 1 | 3 | 5
    randomArena = true,  -- pick random enabled arena per match
},
```

{% hint style="info" %}
Matches start only when `(teamSize × 2)` real players are in queue — no bots, no fill timers.
{% endhint %}

### Match Duration & Flow

| Option                  | Description                                                   |
| ----------------------- | ------------------------------------------------------------- |
| `MatchDuration`         | Round length in **seconds** (`0` = no timer)                  |
| `Match.warmup`          | Free movement before round lock                               |
| `Match.freezeCountdown` | 3-2-1 freeze at round start                                   |
| `Match.returnAfter`     | Teleport back after match (saved position or fallback coords) |
| `RoutingBucket`         | Isolate matches in routing buckets                            |

### Ready Timeout

When a match is found, players must accept in time:

* `ReadyTimeout.warningAfter` — seconds before warning
* `ReadyTimeout.cancelAfter` — seconds before auto-reject

### Arena block

Each arena in `Config.Arenas` needs:

```lua
{
    id = 'default',
    label = 'Strafe Arena #1',
    enabled = true,

    -- Zone: leaving maxDistance teleports to center and resets score
    center = vector3(x, y, z),
    maxDistance = 10.0,   -- radius in meters

    teamA = { ['1'] = vector4(...), ... },
    teamB = { ['1'] = vector4(...), ... },
},
```

* Slot keys `"1"` … `"N"` must match `Matchmaking.maxTeamSize`.
* Zone is always active when `center` is set.
* Score reset on exit is always enabled (not configurable).
* No ground marker is drawn.

### Lobby entries

`Config.LobbyEntries` defines world access points (ped, blip, interaction):

* `interaction`: `'float'` | `'drawtext'` | `'target'`
* `interactionKey`: default `38` (E)

### Weapons

{% hint style="info" %}
Weapon pool for ranked vote UI is in `Config.Weapons`. Place PNG icons in `html/weapons/`.
{% endhint %}

### Strafe Scoring

```lua
StrafeScore = {
    enabled = true,
    requireShift = true,
    patternPoints = 25,
    minUniqueKeys = 2,
    comboWindowMs = 2000,
    comboMultiplierStep = 0.1,
    maxComboMultiplier = 2.0,
    saveToDatabase = true,
},
```

**How it works**

* Player must hold **SHIFT** or **aim** while pressing movement keys.
* Valid patterns: **WASD** or **WDSA** (full 4-key sequence).
* Single-key spam (e.g. DDDD) does not count.
* Combo multiplier increases with consecutive successful patterns (capped at `maxComboMultiplier`).
* Client syncs score to server; `StrafeAntiCheat` validates rates server-side.

### Sounds

{% hint style="info" %}
NUI sound effects are configured in `Config.Sounds`:
{% endhint %}

```lua
Sounds = {
    enabled = true,
    masterVolume = 1.0,

    combo =       { enabled = true, volume = 0.55 },
    win =         { enabled = true, volume = 0.65 },
    lose =        { enabled = true, volume = 0.65 },
    matchFound =  { enabled = true, volume = 0.70 },
    click =       { enabled = true, volume = 0.35 },
},
```

* `enabled = false` on the root disables all sounds.
* Per-sound `enabled` and `volume` (0.0–1.0) are multiplied by `masterVolume`.
* Audio files: `web/src/assets/sounds/` (bundled into `html/` on build).

### Rewards

```lua
Rewards = {
    enabled = true,
    type = 'money',      -- 'money' | 'item' | 'both'
    inventory = 'auto',  -- item delivery: ox, qb, esx, qbox, default

    money = {
        account = 'cash',
        winAmount = 500,
        lossAmount = 0,
    },

    item = {
        win = { { name = 'water', count = 1 } },
        loss = {},
    },
},
```

### Admin Commands

Queue ban (always active)

| Command        | Usage                     |
| -------------- | ------------------------- |
| `/strafeban`   | `[id] [minutes] [reason]` |
| `/strafeunban` | `[id]`                    |

Command names are configurable via `Config.QueueBanCommands`.

#### `/strafeadmin` (framework group or license allowlist)

| Subcommand                              | Description                                                                       |
| --------------------------------------- | --------------------------------------------------------------------------------- |
| `resetstats [id]`                       | Reset one player's stats                                                          |
| `setstats [id] [wins] [losses] [score]` | Set player stats manually                                                         |
| `resetall`                              | Wipe **all** stats + match logs (requires `Config.Admin.resetAll.enabled = true`) |

Admin groups: ESX (`admin`, `superadmin`) and QB (`mod`, `admin`, `god`) — see `Config.Admin`.

### Auto queue ban

{% hint style="info" %}
`Config.QueueBan` bans players who spam queue leaves or ready rejects (configurable windows and thresholds).
{% endhint %}

### Discord Webhooks

Configure in `server/webhook.lua`:

* `matchmaking` — queue joins, match found
* `matchResult` — match outcomes
* `leaderboard` / `daily` / `weekly` — scheduled leaderboard posts
* `admin` — admin actions
* `upset` / `milestone` — optional highlight events

Leave a URL as `''` to disable that channel. Set `WebhookConfig.enabled = false` to disable all webhooks.

### Database

| Table                    | Purpose                                   |
| ------------------------ | ----------------------------------------- |
| `izzy_strafe_stats`      | Player wins, losses, score, names         |
| `izzy_strafe_match_log`  | Per-match score log (period leaderboards) |
| `izzy_strafe_queue_bans` | Temporary queue bans                      |

### Leaderboard periods

UI supports: **ALL TIME**, **DAILY**, **WEEKLY**, **MONTHLY** (via match log timestamps).

### Supported Frameworks

| System  | Auto-detect                        | Manual                 |
| ------- | ---------------------------------- | ---------------------- |
| ESX     | `es_extended`                      | `Config.Core = 'esx'`  |
| QB-Core | `qb-core`                          | `Config.Core = 'qb'`   |
| QBox    | `qbx_core` / `qb-core`             | `Config.Core = 'qbox'` |
| SQL     | oxmysql, ghmattimysql, mysql-async | `Config.SQL`           |

{% hint style="info" %}
Notify auto-detection supports izzy-hud, okokNotify, mythic\_notify, ox\_lib, ESX/QB defaults, and more — see `Config.Notify` comments in `shared/config.lua`.
{% endhint %}

### Features Summary

* Ranked matchmaking 1v1–10v10
* Party system (2v2+) with invite toast
* Custom rooms (host-filled teams, join by code)
* Weapon vote with synced timer
* Best-of series (1 / 3 / 5)
* Live strafe HUD (keys, score, combo)
* Server-side anti-cheat for score inflation
* Multi-language UI (10 locales)
* World lobby peds + blips
* Post-match rewards (money/items)
* Discord webhook integration
* Admin stats management & queue bans

### Support Notes

* If `maxTeamSize` changes, update every arena's `teamA` / `teamB` slot keys accordingly.
* For production, set `MatchDuration` to a realistic value (e.g. `300` for 5 minutes); default `20` is suitable for testing.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://izzyshop-1.gitbook.io/izzyshop-docs/izzyshop-resources/izzy-strafe/configuration.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
