Usage
Controls
| Input | Action |
|---|---|
W / A / S / D | Move around the ring |
Left Shift | Sprint (costs stamina) |
LMB | Left hook (body) |
RMB | Right hook (body) |
Q + LMB | Left jab (body) |
Q + RMB | Right jab (body) |
E + LMB | Left uppercut (body) |
E + RMB | Right uppercut (body) |
Caps Lock + LMB/RMB/Q+LMB/... | Target the head instead of body |
Space | Block |
E | Get up after being knocked down |
Power Punches
Hold the modifier key longer before releasing to throw a power punch (e.g. Q held → LMB = power jab). Power punches deal more damage and drain more of the opponent's stamina on block.
Starting a Match
- Approach a boxing ring - an interaction prompt will appear.
- Choose Invite player to match and select a nearby player.
- Configure the match settings:
- Rounds - 1 to 12 (default:
3) - Round Time - 30 to 300 seconds (default:
180) - Rest Time - 0 to 300 seconds between rounds (default:
30) - Match Type - Ranked or Sparring
- Rounds - 1 to 12 (default:
- The invited player receives a notification and must approach the same ring to accept.
- Both players pick an intro animation, then the match begins.
Sparring
Sparring matches are informal - they do not count towards the win/loss record and are not saved to the database.
Tutorial
Select Start Tutorial at any ring to begin a 2-step NPC tutorial:
- Step 1 - Movement (WASD, sprint) and basic punches (hooks, jabs, uppercuts)
- Step 2 - Blocking, head shots (Caps Lock), and getting up after a knockdown
Rings
Config-defined rings
Rings can be hardcoded in config/sh_config.lua. They will always be present and cannot be removed by admins in-game.
Config.BoxingRings = {
["main_gym"] = {
position = vector4(x, y, z, heading),
rotation = vector3(rx, ry, rz),
},
}Admin-spawned rings
Admins can place rings at runtime using the in-game gizmo. These are saved to config/adminRings.json and persist across restarts.
| Command | Permission | Description |
|---|---|---|
/boxingspawnring [name] | group.admin | Spawn a ring at your current position (opens gizmo) |
/boxingremovering [name] | group.admin | Remove a named ring |
/boxinglistrings | group.admin | Open the admin panel listing all active rings |
The gizmo controls during placement:
| Key | Action |
|---|---|
W | Position mode |
R | Rotation mode |
X | Toggle snap-to-ground |
Enter | Confirm and spawn |
Esc | Cancel |
Custom ring model
To replace the default ring prop, set this before sh_config.lua is loaded (e.g. at the top of your own config):
Config.OverrideRingModel = `your_model_hash`General Settings (sh_config.lua)
| Option | Default | Description |
|---|---|---|
Config.DefaultRoundCount | 3 | Pre-filled round count when setting up a match |
Config.DefaultRoundTime | 180 | Pre-filled round duration (seconds) |
Config.DefaultRestTime | 30 | Pre-filled rest time between rounds (seconds) |
Config.InviteDuration | 60000 | How long an invitation stays open (ms) |
Config.RingSpawnDistance | 200.0 | Max distance at which a ring prop is streamed in |
Config.Debug | true | Enable debug logging (override with boxing_debug convar) |
Config.HitSoundVolume | 0.2 | Volume for hit sounds |
Config.WhooshSoundVolume | 0.05 | Volume for miss sounds |
Config.BellVolume | 0.2 | Volume for round bell |
Balance Settings (balance_config.lua)
| Option | Default | Description |
|---|---|---|
Config.DefenseStaminaDrain | 5 | % stamina drained per second while holding block |
Config.StaminaRegen | 25 | % stamina regained per second |
Config.StaminaRegenDelay | 750 | ms after last action before stamina starts regenerating |
Config.SprintSpeedMultiplier | 2.0 | Speed multiplier when sprinting |
Config.SprintStaminaCost | 50 | Stamina cost per second of sprinting |
Config.KOThreshold | 30 | KO meter value required to knock an opponent down |
Config.RemoveMaxStaminaPercentage | 3 | % of max stamina permanently removed per round based on total stamina used |
Per-move stamina costs, damage values, defense stamina costs and KO contributions are all defined in Config.AttackStaminaCost, Config.AttackDamage, Config.DefenseStaminaCost and Config.KOAttacks respectively.