Compare commits
2 commits
aabe57b767
...
8558120ef8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8558120ef8 | ||
|
|
3514d04518 |
2 changed files with 1408 additions and 10 deletions
|
|
@ -18,7 +18,91 @@ verified empirically on the `left4.me` Trixie test server (kernel
|
||||||
| `sv_lan` | `0` (internet server) |
|
| `sv_lan` | `0` (internet server) |
|
||||||
| `sv_voiceenable` | `1` |
|
| `sv_voiceenable` | `1` |
|
||||||
| `nb_update_frequency` | `0.033` (safe, no plugin), `0.014` with the SM fix plugin. **Cheat-protected — must be set via `sm_cvar`.** |
|
| `nb_update_frequency` | `0.033` (safe, no plugin), `0.014` with the SM fix plugin. **Cheat-protected — must be set via `sm_cvar`.** |
|
||||||
|
| `nb_update_framelimit` | `30` (was 15). Raises the per-frame bot-AI cap so commons don't lag at high counts. **Cheat-protected.** |
|
||||||
| `fps_max` | `64` for 30-tick, `0` (uncapped) for higher ticks |
|
| `fps_max` | `64` for 30-tick, `0` (uncapped) for higher ticks |
|
||||||
|
| `net_maxcleartime` | `0.0001` — drop choked packets fast instead of stalling. **Cheat-protected.** |
|
||||||
|
| `sv_tags` | `"coop,custom"` (etc.) — Steam server browser hint |
|
||||||
|
| `sv_region` | `3` (EU) / `1` (US East) / `255` (any) |
|
||||||
|
|
||||||
|
## Copy-paste best practice config
|
||||||
|
|
||||||
|
A complete starting config that pairs with the project's existing
|
||||||
|
`examples/script-overlays/tickrate.sh` overlay (which installs the
|
||||||
|
Tickrate Enabler plugin) and a SourceMod install. Two files: the
|
||||||
|
plain `server.cfg` and a SourceMod-only `cfg/sourcemod/sourcemod.cfg`.
|
||||||
|
|
||||||
|
For background and per-cvar rationale, see the topic sections below.
|
||||||
|
|
||||||
|
### `server.cfg` (vanilla, non-cheat cvars only)
|
||||||
|
|
||||||
|
```
|
||||||
|
// --- Identity & discoverability ---
|
||||||
|
hostname "your server name here"
|
||||||
|
sv_tags "coop,custom"
|
||||||
|
sv_region 3 // 3=EU, 1=US East, 255=any
|
||||||
|
sv_lan 0
|
||||||
|
sv_steamgroup "0" // your Steam group ID for reserved slots
|
||||||
|
sv_search_key "0" // groups your servers in the lobby browser
|
||||||
|
|
||||||
|
// --- Security ---
|
||||||
|
sv_cheats 0
|
||||||
|
sv_pure 0 // 0/1 for modded servers; 2 = strict
|
||||||
|
sv_consistency 0 // 0 if hosting custom campaigns; 1 = strict
|
||||||
|
sv_password ""
|
||||||
|
sv_allow_lobby_connect_only 0 // let players connect via IP, not just lobby
|
||||||
|
|
||||||
|
// --- Voice / chat ---
|
||||||
|
sv_voiceenable 1
|
||||||
|
sv_alltalk 0
|
||||||
|
|
||||||
|
// --- Player limits (coop) ---
|
||||||
|
sv_maxplayers 4
|
||||||
|
sv_visiblemaxplayers 4
|
||||||
|
// (For versus: 8/8)
|
||||||
|
|
||||||
|
// --- Network rates (100-tick; requires Tickrate Enabler) ---
|
||||||
|
sv_minrate 100000
|
||||||
|
sv_maxrate 100000
|
||||||
|
sv_mincmdrate 100
|
||||||
|
sv_maxcmdrate 100
|
||||||
|
sv_minupdaterate 100
|
||||||
|
sv_maxupdaterate 100
|
||||||
|
sv_client_min_interp_ratio -1
|
||||||
|
sv_client_max_interp_ratio 2
|
||||||
|
net_splitpacket_maxrate 50000
|
||||||
|
net_splitrate 2
|
||||||
|
fps_max 0
|
||||||
|
sv_forcepreload 1
|
||||||
|
|
||||||
|
// --- Logging (used by left4me's log-streaming feature) ---
|
||||||
|
sv_logfile 1
|
||||||
|
sv_logflush 0
|
||||||
|
sv_logecho 1
|
||||||
|
sv_logbans 1
|
||||||
|
```
|
||||||
|
|
||||||
|
### `cfg/sourcemod/sourcemod.cfg` (cheat-flagged cvars, set via `sm_cvar`)
|
||||||
|
|
||||||
|
```
|
||||||
|
// --- Network tweaks (cheat-flagged or SM-managed) ---
|
||||||
|
sm_cvar net_maxcleartime 0.0001
|
||||||
|
|
||||||
|
// --- Simulation cadence (more frequent AI ticks; no behaviour change) ---
|
||||||
|
sm_cvar nb_update_frequency 0.033 // 0.014 if you have the AM fix plugin
|
||||||
|
sm_cvar nb_update_framelimit 30 // default 15 — raise per-frame bot AI cap
|
||||||
|
|
||||||
|
// --- Diagnostics ---
|
||||||
|
sm_cvar nb_stuck_dump_threshold 5 // log stuck bots ≥5s
|
||||||
|
```
|
||||||
|
|
||||||
|
> **If you're not running SourceMod**, the entire `sm_cvar` block
|
||||||
|
> above is dead — those cvars are cheat-protected and silently
|
||||||
|
> ignored from plain `server.cfg`. The vanilla block still applies
|
||||||
|
> and delivers the bulk of the network-feel improvements. See
|
||||||
|
> [Cheat-protected cvars and `sm_cvar`](#cheat-protected-cvars-and-sm_cvar).
|
||||||
|
|
||||||
|
For tickrates other than 100, see the
|
||||||
|
[Network rates](#network-rates) section below.
|
||||||
|
|
||||||
## Network rates
|
## Network rates
|
||||||
|
|
||||||
|
|
@ -105,9 +189,11 @@ within the same server session.
|
||||||
|
|
||||||
## `nb_update_frequency`
|
## `nb_update_frequency`
|
||||||
|
|
||||||
Controls how often common infected and witches recalculate their
|
Like raising server tickrate, this controls *how often* common
|
||||||
pathfinding and state. Default `0.1` (10 Hz), independent of
|
infected and witches get an AI tick — it doesn't change what they
|
||||||
server tickrate.
|
decide, only how quickly the engine asks them. Pure cadence cvar.
|
||||||
|
|
||||||
|
Default `0.1` (10 Hz), independent of server tickrate.
|
||||||
|
|
||||||
| Value | Effect |
|
| Value | Effect |
|
||||||
|---|---|
|
|---|---|
|
||||||
|
|
@ -120,25 +206,161 @@ Set via `sm_cvar nb_update_frequency 0.033` in
|
||||||
`cfg/sourcemod/sourcemod.cfg` (or any sm-auto-execed cfg). Without
|
`cfg/sourcemod/sourcemod.cfg` (or any sm-auto-execed cfg). Without
|
||||||
SourceMod, you cannot reliably set this on a VAC-protected server.
|
SourceMod, you cannot reliably set this on a VAC-protected server.
|
||||||
|
|
||||||
If commons still look choppy after lowering `nb_update_frequency`,
|
## NextBot scheduler & diagnostics
|
||||||
try `sm_cvar z_resolve_zombie_collision_multiplier 0.6` (default
|
|
||||||
`0.25`) — helps commons unstick from each other. Cheat-protected,
|
`nb_update_frequency` (covered above) is *how often* the scheduler
|
||||||
same `sm_cvar` mechanism.
|
asks bots to think. Two related cvars are also pure
|
||||||
|
cadence/throughput — no behaviour change — and one is a passive
|
||||||
|
diagnostic.
|
||||||
|
|
||||||
|
### `nb_update_framelimit`
|
||||||
|
|
||||||
|
Default `15`. **Maximum number of NextBots that get an AI tick per
|
||||||
|
server frame.** Above this cap the engine round-robins bots across
|
||||||
|
frames, so at 30 commons on a 30-tick server each common gets a
|
||||||
|
fresh think roughly every other frame — visible as "zombies
|
||||||
|
hesitate before chasing." Raising this to `30`–`60` lets every bot
|
||||||
|
think every frame at the cost of linear extra CPU. Does not alter
|
||||||
|
how bots decide what to do; only how often they get to decide.
|
||||||
|
|
||||||
|
This is the most under-documented L4D2 cvar and the one most often
|
||||||
|
blamed on tickrate or `nb_update_frequency` when it's neither.
|
||||||
|
|
||||||
|
Cheat-protected — use `sm_cvar`.
|
||||||
|
|
||||||
|
### `nb_stuck_dump_threshold`
|
||||||
|
|
||||||
|
Default `-1` (disabled). Set to `5` to log any bot stuck for ≥5
|
||||||
|
seconds to the server console. Costs nothing at runtime and is the
|
||||||
|
single best diagnostic for "why do zombies keep clipping into
|
||||||
|
geometry on this custom campaign?" tickets. Pure logging — does
|
||||||
|
not affect bot behaviour. Cheat-protected.
|
||||||
|
|
||||||
|
## Lag compensation
|
||||||
|
|
||||||
|
Most lag-compensation cvars are present but not in the truncated
|
||||||
|
`cvar_list` dump. Verify on your own server with `sm_cvar <name>`
|
||||||
|
(no value) before relying on them.
|
||||||
|
|
||||||
|
| Cvar | Default | Notes |
|
||||||
|
|---|---|---|
|
||||||
|
| `sv_unlag` | `1` | Enable lag compensation. Keep on. |
|
||||||
|
| `sv_maxunlag` | `0.5`–`1.0` | Max ms of lag-comp rewind. Confogl uses `1`. Higher = better for higher-ping shots. |
|
||||||
|
| `sv_unlag_fixstuck` | `1` | Used by upstream Competitive-Rework. |
|
||||||
|
| `sv_forcepreload` | `0` | Set to `1` to preload server-side assets at boot. Smoother first map. Confirmed in `cvar_list`. |
|
||||||
|
|
||||||
|
## Packet compression & high-entity-count tuning
|
||||||
|
|
||||||
|
Relevant when running custom servers with raised `z_common_limit`,
|
||||||
|
big mob spawns, or many addon entities. At high entity counts,
|
||||||
|
snapshots routinely exceed the UDP MTU and get split into multiple
|
||||||
|
packets. Clients perceive this as "lag" — but it's really
|
||||||
|
*snapshot drops*, visible in `net_graph` as updates/sec dipping
|
||||||
|
well below `sv_maxupdaterate`. The fix is on the wire, not in the
|
||||||
|
simulation.
|
||||||
|
|
||||||
|
Source: [Lux's L4D2 high-zombie-count discussion (Steam)](https://steamcommunity.com/app/550/discussions/0/2568690416482192538/).
|
||||||
|
|
||||||
|
| Cvar | Default | Recommended | Notes |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `net_compresspackets` | varies | `1` | Enable LZ-style packet compression. Cheap CPU win for high-entity servers. Verify with `sm_cvar`. |
|
||||||
|
| `net_compresspackets_minsize` | varies | `2324` | Compress packets ≥ this size — roughly the wire MTU. |
|
||||||
|
| `net_splitrate` | `1` | `2` | Allow 2 split-packet pieces per net frame; drains queue faster. Confirmed in `cvar_list`. |
|
||||||
|
| `net_splitpacket_maxrate` | `15000` | `50000`+ | Throughput cap when sending split packets. |
|
||||||
|
| `net_maxcleartime` | `4.0` | `0.0001` | Don't stall on choke — drop choked packets fast. Confirmed real (RCON-verified 2026-05-20: `sm_cvar net_maxcleartime` returns the set value). |
|
||||||
|
| `sv_extra_client_connect_time` | varies | `0.0001` | Tiny handshake speedup from the Lux thread. Verify with `sm_cvar`. |
|
||||||
|
|
||||||
|
Several of these are missing from the local `cvar_list` dump but
|
||||||
|
that file is **not exhaustive** — see
|
||||||
|
[Verifying a cvar actually exists](#verifying-a-cvar-actually-exists)
|
||||||
|
below. Several of these lines exist verbatim in upstream
|
||||||
|
Competitive-Rework's `cfg/server.cfg`, which has been running on
|
||||||
|
public servers for years.
|
||||||
|
|
||||||
|
## Server discoverability
|
||||||
|
|
||||||
|
Cosmetic but real UX wins for public servers.
|
||||||
|
|
||||||
|
| Cvar | Recommended | What it does |
|
||||||
|
|---|---|---|
|
||||||
|
| `sv_tags` | `"coop,custom,modded"` (your choice) | Comma-separated tags shown in the Steam server browser. Players filter on these. |
|
||||||
|
| `sv_region` | `3` (EU), `1` (US East), `255` (any) | Region reported to the master server. Set this and your server appears in the right regional browser. |
|
||||||
|
| `sv_search_key` | `"left4me"` (or your own string) | When players search from the in-game lobby, only servers with a matching key appear. Useful for grouping a fleet. |
|
||||||
|
| `sv_steamgroup` | your group's ID | Steam group members get reserved-slot priority (with the appropriate plugin). |
|
||||||
|
| `sv_lan` | `0` | Set `1` only for local-only play; skips Steam auth (players can't friend-join). |
|
||||||
|
|
||||||
|
## Logging hygiene
|
||||||
|
|
||||||
|
Relevant because the project's log-streaming feature (the work in
|
||||||
|
`l4d2web/static/js/files-overlay/editor.js` and adjacent) tails
|
||||||
|
the server log file. These cvars control what actually gets
|
||||||
|
written.
|
||||||
|
|
||||||
|
| Cvar | Recommended | Notes |
|
||||||
|
|---|---|---|
|
||||||
|
| `sv_logfile` | `1` | Server log to disk. Required for log-streaming. |
|
||||||
|
| `sv_logflush` | `0` | Don't flush after every line — slow. Keep at `0` unless you're debugging crashes. |
|
||||||
|
| `sv_logecho` | `1` | Mirror log to stdout — needed for any process that tails srcds's console. |
|
||||||
|
| `sv_logbans` | `1` | Log every `kickid` / `banid` to the same log file. Cheap audit trail. |
|
||||||
|
| `sv_log_onefile` | `0` | Default — one log per day. `1` rolls everything into a single file (gets large quickly). |
|
||||||
|
| `sv_logsdir` | `"logs"` | Default. Path is relative to the game directory. |
|
||||||
|
|
||||||
|
## Verifying a cvar actually exists
|
||||||
|
|
||||||
|
The local `/Users/mwiegand/Projekte/left4me/cvar_list` dump (~2199
|
||||||
|
entries) is **incomplete** — it's missing several real L4D2 cvars
|
||||||
|
that upstream Competitive-Rework uses and that have been verified
|
||||||
|
in-engine via RCON. Likely it was generated via the in-engine
|
||||||
|
`cvarlist` command, which truncates and filters.
|
||||||
|
|
||||||
|
Authoritative existence check via SourceMod console (RCON):
|
||||||
|
|
||||||
|
```
|
||||||
|
sm_cvar <name> # no value → "Value of cvar X: Y" if real,
|
||||||
|
# "unknown" otherwise
|
||||||
|
```
|
||||||
|
|
||||||
|
The screenshot evidence for `net_maxcleartime` (2026-05-20):
|
||||||
|
|
||||||
|
```
|
||||||
|
> sm_cvar net_maxcleartime
|
||||||
|
[SM] Value of cvar "net_maxcleartime": "0.0001"
|
||||||
|
```
|
||||||
|
|
||||||
|
Rule of thumb when copying configs from elsewhere:
|
||||||
|
|
||||||
|
1. If the cvar is in `cvar_list` → it's definitely real.
|
||||||
|
2. If it's *not* in `cvar_list` but is in upstream Competitive-
|
||||||
|
Rework's `server.cfg` → probably real, but verify via `sm_cvar`
|
||||||
|
before relying on it.
|
||||||
|
3. If it's in neither and only mentioned in a random forum post →
|
||||||
|
high probability it's a CSGO/CS:S or HL2 cvar that someone
|
||||||
|
assumed exists in L4D2.
|
||||||
|
|
||||||
## Cvars that DO NOT exist in L4D2 (despite some guides claiming otherwise)
|
## Cvars that DO NOT exist in L4D2 (despite some guides claiming otherwise)
|
||||||
|
|
||||||
These come up in older guides or are inherited from other Source
|
These come up in older guides or are inherited from other Source
|
||||||
games but don't actually exist in L4D2's command set. Verified by
|
games but don't actually exist in L4D2's command set. Verified by
|
||||||
RCON `<cmd>` returning "unknown command":
|
RCON `sm_cvar <name>` returning "unknown":
|
||||||
|
|
||||||
- `net_maxcleartime` — CSGO/CS:S only.
|
|
||||||
- `z_resolve_zombie_collision_multiplier` — confirmed unknown in
|
- `z_resolve_zombie_collision_multiplier` — confirmed unknown in
|
||||||
current L4D2 builds (verified via RCON 2026-05-14). Some
|
current L4D2 builds (verified via RCON 2026-05-14). Some
|
||||||
community guides list it; it's not in the binary.
|
community guides list it; it's not in the binary.
|
||||||
|
- `z_update_rate` — referenced in older tuning guides but not a
|
||||||
|
real L4D2 cvar. The actual zombie-AI cadence knob is
|
||||||
|
`nb_update_frequency`.
|
||||||
|
|
||||||
If a guide tells you to set one of these in L4D2, the guide is
|
If a guide tells you to set one of these in L4D2, the guide is
|
||||||
wrong or out of date.
|
wrong or out of date.
|
||||||
|
|
||||||
|
**Earlier revisions of this doc also listed `net_maxcleartime`
|
||||||
|
here. That was wrong** — it's a real L4D2 cvar (RCON-verified
|
||||||
|
2026-05-20 returning `0.0001` on `left4.me`). It just happens to
|
||||||
|
be missing from the `cvar_list` dump. The lesson: the cvar_list
|
||||||
|
file is useful as a positive check but unreliable as a negative
|
||||||
|
check (see
|
||||||
|
[Verifying a cvar actually exists](#verifying-a-cvar-actually-exists)).
|
||||||
|
|
||||||
## Security and integrity
|
## Security and integrity
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
@ -229,6 +451,28 @@ filesystem's native uid" (on disk) and `<outer>` means "the uid
|
||||||
exposed outward through the mount." Empirically verified; do not
|
exposed outward through the mount." Empirically verified; do not
|
||||||
trust the man page's word choice.
|
trust the man page's word choice.
|
||||||
|
|
||||||
|
## Project integration (left4me overlays)
|
||||||
|
|
||||||
|
The project already ships overlays in `examples/script-overlays/`
|
||||||
|
that map cleanly onto the recommendations above:
|
||||||
|
|
||||||
|
| Overlay | Use it for |
|
||||||
|
|---|---|
|
||||||
|
| [`tickrate.sh`](../examples/script-overlays/tickrate.sh) | Drop-in 100-tick foundation: installs the Tickrate Enabler plugin (`tickrate_enabler.dll/.so/.vdf`) and writes the core rate cvars (`sv_minrate/maxrate 100000`, `nb_update_frequency 0.014`, `net_splitpacket_maxrate 50000`, `net_maxcleartime 0.0001`, `fps_max 0`). Required base layer for any of the higher-tick recommendations in this doc. |
|
||||||
|
| [`competitive_rework.sh`](../examples/script-overlays/competitive_rework.sh) | Pulls the entire SirPlease/L4D2-Competitive-Rework master branch into the overlay. Full confogl bundle — plugins, configs, cfgogl per-mode tuning. Opinionated for tournament versus. Use this *or* `tickrate.sh`, not both. |
|
||||||
|
| [`cedapug_maps.sh`](../examples/script-overlays/cedapug_maps.sh), [`l4d2center_maps.sh`](../examples/script-overlays/l4d2center_maps.sh) | Competitive map pools (orthogonal to cvars). |
|
||||||
|
|
||||||
|
The cvars in the "Copy-paste best practice config" section above
|
||||||
|
are intended to be applied **on top of `tickrate.sh`** — either by
|
||||||
|
adding them to an instance's `spec.config` YAML list, or by
|
||||||
|
creating a new overlay (e.g. `examples/script-overlays/ux_polish.sh`)
|
||||||
|
that writes them to `$OVERLAY/left4dead2/cfg/server.cfg`.
|
||||||
|
|
||||||
|
How `spec.config` becomes `server.cfg` (for reference):
|
||||||
|
`l4d2host/l4d2host/instances.py:52-54` joins the YAML list with
|
||||||
|
newlines into `{LEFT4ME_ROOT}/instances/{name}/server.cfg`, then
|
||||||
|
that file is staged into the runtime upper layer at instance start.
|
||||||
|
|
||||||
## Launch parameters (reference)
|
## Launch parameters (reference)
|
||||||
|
|
||||||
Typical srcds invocation:
|
Typical srcds invocation:
|
||||||
|
|
@ -248,7 +492,9 @@ Typical srcds invocation:
|
||||||
|
|
||||||
Primary references used for the recommendations above:
|
Primary references used for the recommendations above:
|
||||||
|
|
||||||
- [L4D2-Competitive-Rework server.cfg](https://github.com/SirPlease/L4D2-Competitive-Rework/blob/master/cfg/server.cfg)
|
- [L4D2-Competitive-Rework server.cfg](https://github.com/SirPlease/L4D2-Competitive-Rework/blob/master/cfg/server.cfg) — the canonical confogl/competitive cvar block. Many cheat-flagged cvars in this doc are sourced from here.
|
||||||
|
- [L4D2-Competitive-Rework cvar_tracking.cfg](https://github.com/SirPlease/L4D2-Competitive-Rework/blob/master/cfg/cvar_tracking.cfg) — client-cvar enforcement list (anti-cheat tracking; not directly used here but useful context).
|
||||||
|
- [Lux's L4D2 high-zombie-count packet compression analysis (Steam Discussions, app/550)](https://steamcommunity.com/app/550/discussions/0/2568690416482192538/) — origin of the `net_compresspackets` / `net_splitrate` / `net_maxcleartime` recommendations.
|
||||||
- [L4D2 Dedicated Server Guide (Steam Community)](https://steamcommunity.com/sharedfiles/filedetails/?id=276173458)
|
- [L4D2 Dedicated Server Guide (Steam Community)](https://steamcommunity.com/sharedfiles/filedetails/?id=276173458)
|
||||||
- [L4D2 Dedicated Server Network Tweaks (Steam Discussions)](https://steamcommunity.com/app/550/discussions/1/1839063537784156851/)
|
- [L4D2 Dedicated Server Network Tweaks (Steam Discussions)](https://steamcommunity.com/app/550/discussions/1/1839063537784156851/)
|
||||||
- [SirPlease/Server4Dead-Project — Tickrate Enabler](https://github.com/SirPlease/Server4Dead-Project/tree/master/Tickrate%20Enabler)
|
- [SirPlease/Server4Dead-Project — Tickrate Enabler](https://github.com/SirPlease/Server4Dead-Project/tree/master/Tickrate%20Enabler)
|
||||||
|
|
@ -257,3 +503,5 @@ Primary references used for the recommendations above:
|
||||||
- [Source Multiplayer Networking — Valve Developer Community](https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking)
|
- [Source Multiplayer Networking — Valve Developer Community](https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking)
|
||||||
- [Required Versions (SourceMod wiki)](https://wiki.alliedmods.net/Required_Versions_(SourceMod))
|
- [Required Versions (SourceMod wiki)](https://wiki.alliedmods.net/Required_Versions_(SourceMod))
|
||||||
- [MetaMod:Source news](https://www.sourcemm.net/)
|
- [MetaMod:Source news](https://www.sourcemm.net/)
|
||||||
|
- Local: `/Users/mwiegand/Projekte/left4me/cvar_list` — 2199-line dump of L4D2 cvars (positive existence reference; *not* exhaustive — see [Verifying a cvar actually exists](#verifying-a-cvar-actually-exists)).
|
||||||
|
- Local: `examples/script-overlays/tickrate.sh`, `examples/script-overlays/competitive_rework.sh` — overlay scripts that apply these settings to a left4me instance.
|
||||||
|
|
|
||||||
1150
docs/superpowers/plans/2026-05-17-server-detail-page-redesign.md
Normal file
1150
docs/superpowers/plans/2026-05-17-server-detail-page-redesign.md
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue