Configuration
All configuration for legends_cases lives in two places:
config.lua— spin timings, cooldown, locale, integrations, and case definitionsshared/rarities.lua— rarity tier names, colors, and labels
This page documents every setting in config.lua. For step-by-step recipes (adding a new case, balancing weights, custom rarities) see Adding a Case.
Spin & Reveal Timings
Config.SpinDuration
Config.SpinDuration = 6500Description: How long the roulette reel spins before stopping on the winning slot, in milliseconds.
Type: number
Default: 6500
Config.RevealDelay
Config.RevealDelay = 600Description: Delay between the reel landing on the winning slot and the reward reveal modal appearing, in milliseconds. Tunes the dramatic pause.
Type: number
Default: 600
Config.WinModalTime
Config.WinModalTime = 4000Description: How long the win modal stays on screen before auto-closing, in milliseconds.
Type: number
Default: 4000
Config.ReelLength
Config.ReelLength = 60Description: Number of items rendered on the roulette reel. Larger values produce a longer-feeling spin without changing the spin duration.
Type: number
Default: 60
Config.ReelWinIndex
Config.ReelWinIndex = 55Description: Which slot index (1-indexed) on the reel contains the winning item. The reel is built so the player visually lands here. Adjust if you change ReelLength.
Type: number
Default: 55
ReelWinIndex must be less than or equal to ReelLength. Changing reel length without updating the win index will cause the reveal to land on the wrong slot.
Rate Limiting
Config.OpenCooldown
Config.OpenCooldown = 1500Description: Minimum milliseconds between case opens by the same player. Anti-spam protection. Combined with the per-player pending-state lock, blocks both flood opens and timing-based double-redemption exploits.
Type: number
Default: 1500
Localization
Config.Locale
Config.Locale = 'en'Description: Active language. Keys into locales/<lang>.lua. Ships with English; add new languages by creating locales/de.lua, locales/fr.lua, etc.
Type: string
Default: 'en'
Locale strings (en.lua):
| Key | Default text | When shown |
|---|---|---|
not_configured | This case is not configured. | Player uses an item that isn't in Config.Cases |
cooldown | Slow down. | Player tries to open within OpenCooldown |
pending_open | Finish your previous case first. | Player tries to open while another spin is pending |
case_not_found | Case not found. | Server can't resolve the case key |
consume_failed | Failed to consume case. | Inventory removal failed |
inventory_full_drop | Inventory full, reward dropped. | Reward dropped to the ground |
use_blocked_busy | Already opening a case. | Client blocked a use call while UI is open |
Integrations
Config.Integrations
Config.Integrations = {
Framework = 'auto',
Inventory = 'auto',
Notify = 'auto',
}Description: Each entry is either 'auto' (the bridge picks based on GetResourceState) or a literal resource name to pin explicitly.
| Property | Type | Accepted values |
|---|---|---|
Framework | string | 'auto', 'qbx_core', 'qb-core', 'es_extended', 'standalone' |
Inventory | string | 'auto', 'ox_inventory', 'qs-inventory', 'codem-inventory', 'origen_inventory', 'tgiann-inventory', 'ps-inventory', 'qb-inventory', 'esx' |
Notify | string | 'auto', 'ox_lib', 'okokNotify', 'qbx_core', 'qb-core', 'es_extended', 'native' |
QBox is expected to use ox_inventory. Other inventories work on QBox only if their exports don't depend on a qb-core player object. qb-inventory does not work on QBox.
Case Definitions
Config.Cases
Config.Cases = {
['starter_case'] = {
label = 'Starter Case',
items = {
{ item = 'bandage', count = 5, chance = 35.0, rarity = 'milspec' },
{ item = 'lockpick', count = 2, chance = 25.0, rarity = 'milspec' },
{ item = 'radio', count = 1, chance = 18.0, rarity = 'restricted' },
{ item = 'phone', count = 1, chance = 6.0, rarity = 'classified' },
{ item = 'WEAPON_STUNGUN', count = 1, chance = 3.0, rarity = 'covert' },
{ item = 'WEAPON_PISTOL', count = 1, chance = 0.9, rarity = 'gold' },
},
},
}Description: A table of every case definition keyed by the inventory item name. Each case has a label (shown in the UI) and an items array of possible rewards.
Per-item entry:
| Property | Type | Description |
|---|---|---|
item | string | Inventory item name to award (any item your inventory recognizes — consumables, weapons, cash, custom) |
count | number | Quantity to award when this slot wins |
chance | number | Weight — see note below. NOT a percentage |
rarity | string | One of the keys in shared/rarities.lua (default: milspec, restricted, classified, covert, gold) |
Chance is a weight, not a percentage. Values do NOT need to sum to 100. A slot with chance = 50.0 is twice as likely as one with chance = 25.0, regardless of the total. This makes balancing easy — tweak any single item without recalculating every other entry.
Rarity Tiers
Rarity tiers are defined in shared/rarities.lua. The default set follows the CS-style palette:
| Key | Display | Color treatment |
|---|---|---|
milspec | Mil-Spec | Blue (common) |
restricted | Restricted | Purple (uncommon) |
classified | Classified | Pink (rare) |
covert | Covert | Red (very rare) |
gold | Gold | Yellow / gold (extremely rare) |
| (custom) | — | Reserved slot for server-specific styling |
Edit shared/rarities.lua to rename tiers, add new ones, or swap colors. The roulette reel and reveal modal pick up the changes automatically — there is no hardcoded tier name in the React source.
Performance Notes
- No server tick. The server only does work when a player opens a case (build reel → roll → award).
- No client tick when the UI is closed. The client only listens for inventory
useevents. - Idle resmon: ~0.00ms on both client and server.