Unknown ❤ RESPAWN.ZAFEST.RO | VIP FREE | FREE FOR ALL ❤ 0/32
Romania XPlayZM.CSBlackDevil.COM # Zombie Plague UltimateX [ Respawn + FDL + VIP 22-12PM + POINTS] ® 18/32
Promote server

Add 6 tutorials (6 files)

Browse Source
Daemon666 committed parent e791f7700a commit 14deb04591d878e32ce0c12e70318c205280f8fa
6 changed files with 328 additions and 0 deletions
+48 -0 amx-gag-mute-players/en.md A
@@ -0,0 +1,48 @@
1 +---
2 +title: "Gagging and Muting Players (amx_gag)"
3 +excerpt: "How amx_gag blocks a player's chat and voice, why it is a plugin command rather than a stock one, its flag syntax, and how to lift a gag."
4 +category: "administration"
5 +tags: "moderation, chat"
6 +image: ""
7 +read_time: "7 min read"
8 +---
9 +<p>When one player is spamming chat, blaring their mic or pasting slurs on repeat, you want to silence <em>that player</em> without kicking them and without punishing everyone. That is what a gag does: it blocks a specific client's chat and/or voice while leaving them in the game. The command most admins reach for is <code>amx_gag</code> — but there is an important detail people miss, which is that it is not part of stock AMX Mod X.</p>
10 +
11 +<h2>1. amx_gag comes from a plugin</h2>
12 +<p>A default AMX Mod X install does not ship an <code>amx_gag</code> command. It is provided by a separate gag/mute plugin that you install into <code>addons/amxmodx/plugins/</code> and add to <a href="/tutorials/plugins-ini-load-order">plugins.ini</a>. There are several popular implementations, and their exact flag letters differ, so the syntax below is the common shape — always confirm against the header of the specific <code>.sma</code> you deploy. Our maintained implementation is <a href="/plugins/csb-gag">CSB Gag</a>, which documents its own flags.</p>
13 +
14 +<h2>2. The command syntax</h2>
15 +<p>Most gag plugins follow this form:</p>
16 +<pre>amx_gag &lt;target&gt; &lt;flags&gt; [time in minutes]</pre>
17 +<p>The target is a name fragment or <code>#userid</code>. The flags select <em>what</em> to block, typically:</p>
18 +<ul>
19 +<li><code>a</code> — block public chat (<code>say</code>).</li>
20 +<li><code>b</code> — block team chat (<code>say_team</code>).</li>
21 +<li><code>c</code> — block voice communication.</li>
22 +</ul>
23 +<p>An optional time argument sets an automatic expiry in minutes; omit it (or pass <code>0</code>) for a gag that lasts until the map changes or you lift it. For example, silencing a spammer's public and team chat for ten minutes:</p>
24 +<pre>amx_gag Spammer ab 10</pre>
25 +<p>To also cut their microphone, add the voice flag:</p>
26 +<pre>amx_gag Spammer abc 10</pre>
27 +
28 +<h2>3. How voice muting actually works</h2>
29 +<p>Text chat is easy to block — the plugin intercepts the <code>say</code>/<code>say_team</code> command and drops it before it reaches anyone. Voice is different: the engine relays voice packets between clients, so a server-side voice gag works by blocking the voice message going out from the gagged player to everyone else. This is why the voice flag depends on the plugin actually implementing that message hook; a chat-only gag plugin cannot mute a mic no matter what flag you pass. If your gag silences text but not voice, the plugin simply does not support voice muting, and the only alternative is for each player to mute the offender client-side through the scoreboard — which does not scale when it is the whole server being blasted.</p>
30 +
31 +<h2>4. Lifting a gag</h2>
32 +<p>Gag plugins pair the gag command with an ungag:</p>
33 +<pre>amx_ungag &lt;target&gt;</pre>
34 +<p>A timed gag lifts itself when the timer expires; an untimed gag persists until you ungag the player or the map changes (most implementations clear gags on map change since the player list resets). If you need a gag to survive reconnects and map changes, you need a plugin that stores gags against SteamID rather than the temporary player slot — check whether yours does.</p>
35 +
36 +<h2>5. Gag versus kick versus ban</h2>
37 +<p>Gag is the proportionate tool for a chat/voice problem. Reserve harder measures for behaviour that gagging cannot fix: use <a href="/tutorials/amx-slap-slay-kick">kick</a> for someone who needs to cool off and reconnect, and <a href="/tutorials/amx-ban-commands">ban</a> for someone who should not come back. A recurring spammer who evades timed gags is a ban candidate. For automated defence against chat flooding rather than targeted muting, layer an <a href="/plugins/csb-anti-flood">anti-flood plugin</a> underneath so you are not gagging by hand all night.</p>
38 +
39 +<h2>Common errors</h2>
40 +<ul>
41 +<li><strong><code>Unknown command: amx_gag</code></strong> — the gag plugin is not installed or not loaded. Add it to <code>plugins.ini</code>, change the map, and confirm with <code>amxx plugins</code>.</li>
42 +<li><strong>Text is blocked but the mic still works</strong> — your gag plugin does not implement voice muting, or you did not pass the voice flag. Check the plugin's supported flags.</li>
43 +<li><strong>Gag disappears when the player reconnects</strong> — the plugin tracks gags by slot, not SteamID. Use a persistent gag plugin for evaders.</li>
44 +<li><strong>Access denied</strong> — gagging usually requires a chat/slay access flag; the acting admin lacks it. Grant the flag the plugin requires in <a href="/tutorials/users-ini-explained">users.ini</a>.</li>
45 +</ul>
46 +
47 +<h2>Verification</h2>
48 +<p>Gag a test client and confirm the effect matches the flags: with <code>ab</code> their <code>say</code> and <code>say_team</code> messages should no longer appear to anyone; with <code>c</code> their voice should be silent to other players. Run <code>amx_ungag</code> and verify chat returns. If the gag plugin exposes a list command, use it to see who is currently gagged and for how long, so a timed gag does not quietly outlive the situation that caused it.</p>
+54 -0 block-bad-nicknames/en.md A
@@ -0,0 +1,54 @@
1 +---
2 +title: "Blocking Bad Nicknames and Ads in Player Names"
3 +excerpt: "Stop clan-tag ads, empty names and slurs in player nicks: how CS 1.6 handles name changes, what the engine can filter, and an AMXX name-filter approach that renames offenders."
4 +category: "administration"
5 +tags: "names, moderation"
6 +image: ""
7 +read_time: "8 min read"
8 +---
9 +<p>Player names are the one piece of text every visitor controls, and on a public server a fraction of them will abuse it: a website advert as a clan tag, a slur, a name that impersonates an admin, or an empty/blank nick that breaks kill feeds. The engine gives you almost nothing here, so name moderation is an AMX Mod X job. This covers what the engine does at connect, what a name filter can enforce, and how to apply it without breaking legitimate name changes.</p>
10 +
11 +<h2>1. Understand when a name is set</h2>
12 +<p>A client's name is the <code>name</code> setinfo value. It is sent at connect and can be changed at any time in-game via the console (<code>name "whatever"</code>) or the options menu. That means a filter cannot be a one-time check at join &mdash; a player can connect with a clean name and switch to <code>www.rival-server.com</code> ten seconds later. Any real solution has to react to name <em>changes</em>, not just connects.</p>
13 +
14 +<h2>2. What the engine and mp_ cvars can do (not much)</h2>
15 +<p>Stock CS has no name blacklist. The engine will reject a name that is entirely empty by substituting a default, and it collapses some characters, but there is no cvar to ban a word or a URL from a nick. Do not go looking for an <code>mp_</code> cvar for this &mdash; it does not exist. This is squarely a plugin problem, which is why every serious public server runs a name filter.</p>
16 +
17 +<h2>3. How an AMXX name filter works</h2>
18 +<p>A name-filter plugin hooks the moment a name is set and validates it, using the <code>client_infochanged</code> forward (fired whenever any setinfo, including <code>name</code>, changes) and the <code>namecheck</code>/<code>SetClientKeyValue</code> mechanics to inspect and, if needed, overwrite the new name. The logic is:</p>
19 +<ol>
20 +<li>Read the proposed new name from the client's info buffer.</li>
21 +<li>Compare it against a blacklist (substrings, or a regex for URLs) and against structural rules (min length, no all-whitespace, character set).</li>
22 +<li>If it violates a rule, reject it &mdash; either revert to the previous name or force a neutral placeholder like <code>Player</code>, and optionally warn the client.</li>
23 +</ol>
24 +<p>Blocking a URL pattern such as <code>.com</code>, <code>.net</code>, <code>www.</code> and <code>http</code> catches the overwhelming majority of name adverts. A short slur list handles the rest. Our <a href="/plugins/csb-name-filter">CSB Name Filter</a> implements exactly this &mdash; a configurable blacklist plus URL and empty-name rules that rename offenders on the spot.</p>
25 +
26 +<h2>4. Set sensible rules</h2>
27 +<p>Filters that are too aggressive punish normal players. Reasonable defaults:</p>
28 +<ul>
29 +<li><strong>Block URLs</strong> &mdash; <code>www.</code>, <code>http</code>, and common TLDs in a name are almost always ads. This is the single highest-value rule.</li>
30 +<li><strong>Reject empty / whitespace-only names</strong> &mdash; force a placeholder. Blank names break the kill feed and votes.</li>
31 +<li><strong>Minimum length</strong> &mdash; one or two characters is usually a troll or an evasion; require at least three.</li>
32 +<li><strong>Impersonation</strong> &mdash; block names containing <code>ADMIN</code>, your server name, or an owner's handle, so nobody masquerades as staff.</li>
33 +<li><strong>Slur list</strong> &mdash; keep it short and specific; long word lists cause false positives on innocent substrings (the classic \"Scunthorpe\" problem).</li>
34 +</ul>
35 +<p>Log every rename so you can tune the list and catch a rule that fires too often.</p>
36 +
37 +<h2>5. Handle the rename gracefully</h2>
38 +<p>When you reject a name, tell the player why and give them a clean fallback rather than silently reverting in a loop &mdash; a client whose name is rejected can get stuck re-sending it. Print a one-line chat message (\"Names with website addresses are not allowed\") and set them to a neutral placeholder. Pair the filter with an <a href="/plugins/csb-adverts">adverts plugin</a> that states the naming rule occasionally, so it feels like a policy rather than a random kick.</p>
39 +
40 +<h2>Common errors</h2>
41 +<ul>
42 +<li><strong>Filter only checks at connect, ads slip in later</strong> &mdash; it hooks connect instead of <code>client_infochanged</code>. A name changed in-game must be re-validated.</li>
43 +<li><strong>Legitimate names get rejected</strong> &mdash; an over-broad blacklist (a TLD substring matching inside a normal word, or a slur substring inside an innocent one). Match on word boundaries or full tokens, not bare substrings.</li>
44 +<li><strong>Name-change loop</strong> &mdash; the plugin reverts to the same rejected value the client keeps resending. Force a fixed placeholder instead of bouncing between two names.</li>
45 +<li><strong>Unicode/colored names bypass the filter</strong> &mdash; the offender uses lookalike characters. Normalize the string before matching, or block non-ASCII if your community does not need it.</li>
46 +<li><strong>Admins caught by the impersonation rule</strong> &mdash; exempt authenticated admins from the <code>ADMIN</code> block by checking their flags before filtering.</li>
47 +</ul>
48 +
49 +<h2>Verification</h2>
50 +<p>Test each rule from a client console. Try to set a forbidden name and confirm the plugin corrects it:</p>
51 +<pre>name "www.some-ad.com" // should be rejected / renamed
52 +name "" // should become a placeholder
53 +name "x" // should fail the minimum-length rule</pre>
54 +<p>Watch the server console or AMXX log for the rename entries. Then set a perfectly normal name and confirm it is accepted unchanged &mdash; a filter that blocks ads but also blocks <code>Steve</code> is worse than no filter. Once it behaves, add the naming rule to your <a href="/tutorials/motd-txt-html-guide">MOTD</a> so players know before they are corrected.</p>
+57 -0 cs16-connect-via-console/en.md A
@@ -0,0 +1,57 @@
1 +---
2 +title: "Connecting to a CS 1.6 Server via Console (connect IP:PORT)"
3 +excerpt: "Join any CS 1.6 server directly from the console with the connect command, pass a password, set your name, and reconnect after a drop — no server browser needed."
4 +category: "client"
5 +tags: "console, connect"
6 +image: ""
7 +read_time: "7 min read"
8 +---
9 +<p>The server browser is slow, sometimes hides servers behind filters, and will not show a box that is not heartbeating the master list. The console <code>connect</code> command bypasses all of that: give it an address and port and you are in. This is the fastest way to reach a specific server, rejoin one that dropped you, or connect to a community box that does not appear in the internet list. Here is the full command set.</p>
10 +
11 +<h2>1. Open the console</h2>
12 +<p>You need the developer console bound to a key or set to open with the tilde. If it does not open, follow <a href="/tutorials/cs16-enable-console">enable the developer console</a> first, then press the key (usually <code>~</code>) to bring it up.</p>
13 +
14 +<h2>2. Connect with an address and port</h2>
15 +<p>The command is <code>connect</code> followed by the IP and port, colon-separated:</p>
16 +<pre>connect 203.0.113.10:27015</pre>
17 +<p>The default CS 1.6 port is <strong>27015</strong>. If the server runs on a non-default port you must include it — many providers put several servers on one IP separated only by port, so <code>27016</code>, <code>27017</code> and so on are common. Leaving the port off assumes 27015, which connects you to the wrong server or to nothing.</p>
18 +
19 +<h2>3. Join a password-protected server</h2>
20 +<p>Set the join password <em>before</em> you connect, then connect:</p>
21 +<pre>password "theserverpassword"
22 +connect 203.0.113.10:27015</pre>
23 +<p>The <code>password</code> cvar holds your join password; the server compares it against its own <code>sv_password</code>. If you connect first and get rejected, set the password and use <code>retry</code> (below) rather than retyping the whole address. Clear it afterward with <code>password ""</code> so it does not linger for the next server.</p>
24 +
25 +<h2>4. Set your name and rejoin cleanly</h2>
26 +<p>Your in-game name lives in the <code>name</code> setinfo. Set it from console any time:</p>
27 +<pre>name "YourNick"
28 +setinfo "_vgui_menus" "0"</pre>
29 +<p>Two commands make reconnecting painless:</p>
30 +<pre>retry // reconnect to the last server you tried
31 +disconnect // drop to the main menu</pre>
32 +<p><code>retry</code> is the one to remember — after a map change kicks everyone, or when a server is briefly full, <code>retry</code> hammers the same address without you re-typing the IP.</p>
33 +
34 +<h2>5. Check where you are with status</h2>
35 +<p>Once connected, the <code>status</code> command dumps the server's address, the map, your slot, and every player's userid and SteamID:</p>
36 +<pre>status</pre>
37 +<p>This is how you copy the exact address of a server you joined through the browser so you can turn it into a direct-connect alias, and it is the same command admins use to read player IDs for bans. If a friend asks "what server are you on?", <code>status</code> gives you the line to paste. It also confirms the real port when a shared-IP host put you somewhere other than 27015.</p>
38 +
39 +<h2>6. Save a favourite as an alias</h2>
40 +<p>If you join the same server daily, make a one-word command for it in your <a href="/tutorials/cs16-competitive-video-config">autoexec.cfg</a>:</p>
41 +<pre>alias "home" "connect 203.0.113.10:27015"
42 +alias "scrim" "password topsecret; connect 203.0.113.11:27016"</pre>
43 +<p>Now typing <code>home</code> in console joins instantly. This is far quicker than scrolling the browser, and it works for servers that never show up there at all.</p>
44 +
45 +<h2>Common errors</h2>
46 +<ul>
47 +<li><strong><code>Connection failed after 4 retries</code></strong> — the address or port is wrong, the server is down, or UDP is blocked between you and it. Double-check the port and see <a href="/tutorials/cs16-connection-failed-retries-client">the client-side fix for this exact error</a>.</li>
48 +<li><strong>Joins the wrong server on a shared IP</strong> — you omitted the port and defaulted to 27015. Add the real port.</li>
49 +<li><strong><code>Bad password</code> or immediate kick</strong> — the <code>password</code> cvar was empty or wrong. Set it before connecting, then <code>retry</code>.</li>
50 +<li><strong><code>Server is full</code></strong> — no reserved slot for you. Use <code>retry</code> to catch an opening, or join a server with reserved-slot handling.</li>
51 +<li><strong><code>connect</code> does nothing</strong> — you typed it in in-game chat, not the console. The console is a separate window; open it with your bound key.</li>
52 +</ul>
53 +
54 +<h2>Verification</h2>
55 +<p>Point <code>connect</code> at a known-good server and confirm it loads straight into the map. To prove your favourite alias works, reload the game and type your one-word command:</p>
56 +<pre>home</pre>
57 +<p>It should resolve to the full <code>connect</code> and join. If a specific server refuses every time while others connect fine, the problem is that address, port, or password — not your client. If <em>every</em> server fails with the retries error, the trouble is on your side, and the <a href="/tutorials/cs16-connection-failed-retries-client">connection-failed guide</a> walks through it.</p>
+71 -0 parse-cs16-server-logs/en.md A
@@ -0,0 +1,71 @@
1 +---
2 +title: "Parsing CS 1.6 Server Logs (logs/L*.log)"
3 +excerpt: "Turn logging on, understand the Half-Life log line format, and grep and awk the L*.log files to answer who connected, who said what, and who killed whom."
4 +category: "administration"
5 +tags: "logs, admin"
6 +image: ""
7 +read_time: "8 min read"
8 +---
9 +<p>Every CS 1.6 server can write a detailed, machine-readable log of connects, chat, kills and admin actions to <code>cstrike/logs/</code>. Most admins never turn it on until they need to answer "who did that?" a week too late. This shows how to enable logging, read the standard Half-Life log format, and extract answers with nothing more than <code>grep</code> and <code>awk</code>.</p>
10 +
11 +<h2>1. Turn logging on</h2>
12 +<p>Put these in <a href="/tutorials/setup-server-cfg-cs16">server.cfg</a>:</p>
13 +<pre>log on // enable logging to cstrike/logs/
14 +mp_logmessages 1 // include chat in the log
15 +mp_logdetail 3 // log attacks and kills (bit 1 + bit 2)
16 +sv_log_onefile 0 // 0 = one file per map/session, 1 = single file</pre>
17 +<p>Files land in <code>cstrike/logs/</code> named by date, like <code>L0715001.log</code> (month, day, sequence). New files roll over on map change and at midnight, so a busy server produces many small logs — which is exactly what you want when grepping a single incident.</p>
18 +
19 +<h2>2. Read the log line format</h2>
20 +<p>Every line follows the Half-Life standard: a timestamp, then a quoted actor, a verb, and details. A kill looks like:</p>
21 +<pre>L 07/15/2026 - 20:14:33: "Neo&lt;3&gt;&lt;STEAM_0:1:12345&gt;&lt;CT&gt;" killed "Smith&lt;5&gt;&lt;STEAM_0:0:98765&gt;&lt;TERRORIST&gt;" with "ak47"</pre>
22 +<p>The actor is <code>Name&lt;userid&gt;&lt;authid&gt;&lt;team&gt;</code>. Other common verbs:</p>
23 +<ul>
24 +<li><code>connected, address "1.2.3.4:27005"</code> — a client joined.</li>
25 +<li><code>entered the game</code> — finished connecting.</li>
26 +<li><code>disconnected</code> — left.</li>
27 +<li><code>say "..."</code> and <code>say_team "..."</code> — chat.</li>
28 +<li><code>triggered "..."</code> — bomb planted/defused, round events.</li>
29 +</ul>
30 +<p>Because the format is stable, tools like HLstatsX parse it directly; you can too.</p>
31 +
32 +<h2>3. Grep for the common questions</h2>
33 +<p>Who connected, and from what IP:</p>
34 +<pre>grep 'connected, address' cstrike/logs/L0715*.log</pre>
35 +<p>Everything a specific player did, by SteamID (survives name changes):</p>
36 +<pre>grep 'STEAM_0:1:12345' cstrike/logs/L0715*.log</pre>
37 +<p>All chat, to review an argument or a slur report:</p>
38 +<pre>grep -E '" (say|say_team) "' cstrike/logs/*.log</pre>
39 +<p>Grepping by SteamID rather than name is the key habit — names are trivially changed, the authid is not, which is also why <a href="/tutorials/ip-bans-vs-steamid-bans">SteamID bans</a> are the precise ones.</p>
40 +
41 +<h2>4. awk for counts and leaderboards</h2>
42 +<p>A quick kill leaderboard for one log — pull the killer name from each <code>killed</code> line and tally:</p>
43 +<pre>grep '" killed "' cstrike/logs/L0715001.log \
44 + | awk -F'"' '{print $2}' \
45 + | sed 's/&lt;.*//' \
46 + | sort | uniq -c | sort -rn | head</pre>
47 +<p>The <code>-F'"'</code> splits on quotes so field 2 is the killer's <code>Name&lt;id&gt;&lt;auth&gt;&lt;team&gt;</code> block; stripping from the first <code>&lt;</code> leaves the name. Count word frequency in chat, count disconnects per hour, or filter to a time window with a timestamp <code>grep</code> — the same shape of pipeline answers most questions.</p>
48 +
49 +<h2>5. Find admin actions and abuse</h2>
50 +<p>AMX Mod X writes admin commands to the same logs (and to its own under <code>addons/amxmodx/logs/</code>). To audit who is banning and kicking:</p>
51 +<pre>grep -iE 'amx_(ban|kick|slay|slap|map)' cstrike/logs/*.log</pre>
52 +<p>This is the backbone of <a href="/tutorials/prevent-admin-abuse">preventing admin abuse</a> — the log is the record you check when a player claims an admin acted unfairly.</p>
53 +
54 +<h2>6. Correlate an incident end to end</h2>
55 +<p>When you need the full story of one player, chain the pipelines: pull their SteamID from the connect line, then grep every log that mentions it to reconstruct the session — when they joined, from which IP, what they said, who they killed, and whether an admin acted on them. Because the timestamp prefix is fixed-width, you can also narrow to a window with a plain string match:</p>
56 +<pre>grep 'STEAM_0:1:12345' cstrike/logs/*.log | grep '20:1' // 20:10-20:19</pre>
57 +<p>That two-step — identity first, then time window — answers almost every "what happened at round 12" question without any external tooling. Archive the logs off the server periodically so a busy box does not rotate the evidence away before you look.</p>
58 +
59 +<h2>Troubleshooting</h2>
60 +<ul>
61 +<li><strong>No log files at all</strong> — <code>log on</code> was never set, or the <code>cstrike/logs/</code> directory is not writable by the server's user. Check permissions and the console for a log-open error.</li>
62 +<li><strong>Chat missing from the log</strong> — <code>mp_logmessages 0</code>. Set it to 1.</li>
63 +<li><strong>No kill/attack lines</strong> — <code>mp_logdetail 0</code>. Use <code>3</code> for attacks and kills.</li>
64 +<li><strong>One giant file instead of many</strong> — <code>sv_log_onefile 1</code>. That is fine, but grep by date range instead of by filename.</li>
65 +<li><strong>Wrong timezone in timestamps</strong> — the log uses the server host's local time; set the box's timezone if it matters for correlating reports.</li>
66 +</ul>
67 +
68 +<h2>Verification</h2>
69 +<p>Trigger something and confirm it lands. Join the server, type a test line in chat, then:</p>
70 +<pre>tail -f cstrike/logs/L0715001.log</pre>
71 +<p>You should see your <code>say</code> line appear live with your name, userid and SteamID. Kill a bot and confirm a <code>killed ... with</code> line shows up. Once you trust the logs are complete, keep them — disk is cheap and the one time you need to prove what happened, only the log can.</p>
+20 -0 timelimit-maxrounds-flow/en.md A
@@ -0,0 +1,20 @@
1 +---
2 +title: "mp_timelimit, mp_maxrounds and Map Flow Tuning"
3 +excerpt: "How the four end-of-map limits interact, which need ReGameDLL, why whichever fires first wins, and how to design a map flow that ends cleanly and advances the rotation."
4 +category: "administration"
5 +tags: "cvars, gameplay"
6 +image: ""
7 +read_time: "8 min read"
8 +---
9 +<p>What ends a map on CS 1.6 is not <a href="/tutorials/mapcycle-txt-setup">mapcycle.txt</a> &mdash; the rotation only advances once a map ends, and <em>ending</em> is decided by four cvars that race each other. Set them carelessly and the map either never ends or ends in a way that surprises players mid-round. This explains the four limits, which ones require ReGameDLL, and how to pick a flow that feels intentional.</p><h2>1. The four ways a map ends</h2><table><thead><tr><th>Cvar</th><th>Unit</th><th>Requires</th><th>Ends the map when...</th></tr></thead><tbody><tr><td><code>mp_timelimit</code></td><td>minutes</td><td>stock</td><td>the clock runs out.</td></tr><tr><td><code>mp_maxrounds</code></td><td>rounds</td><td>ReGameDLL</td><td>N rounds have been played.</td></tr><tr><td><code>mp_winlimit</code></td><td>wins</td><td>ReGameDLL</td><td>one team reaches N round wins.</td></tr><tr><td><code>mp_fraglimit</code></td><td>frags</td><td>stock</td><td>any player reaches N kills.</td></tr></tbody></table><p>Only <code>mp_timelimit</code> and <code>mp_fraglimit</code> exist on stock Valve CS. <code>mp_maxrounds</code> and <code>mp_winlimit</code> are added by <a href="/tutorials/install-regamedll-cs16">ReGameDLL_CS</a>; on stock CS, setting them is a silent no-op &mdash; the value goes nowhere and the map never ends by round count.</p><h2>2. Whichever fires first wins</h2><p>These limits are not prioritized; they run in parallel and the <strong>first</strong> one satisfied ends the map. If you set <code>mp_timelimit 30</code> and <code>mp_maxrounds 30</code>, a fast-paced map may hit 30 rounds in 22 minutes and end early, while a slow one hits 30 minutes first. That is not a bug &mdash; it is the design. The mistake is setting several limits without deciding which you actually want to govern the map, then being confused when the map ends at an unpredictable moment.</p><h2>3. Pick one primary limit</h2><p>Decide what your server is for and let one cvar lead:</p><ul><li><strong>Casual public</strong> &mdash; time-based. Set <code>mp_timelimit</code> (20&ndash;30 is common) and leave the others at <code>0</code>. Everyone knows roughly how long a map lasts.</li><li><strong>Competitive / MR-style</strong> &mdash; round-based. Set <code>mp_maxrounds</code> (e.g. 30 for an MR15) and set <code>mp_timelimit 0</code> so the map ends on rounds, not the clock.</li><li><strong>Race to a score</strong> &mdash; <code>mp_winlimit</code>. The map ends the instant a team clinches, good for short rotations.</li><li><strong>Deathmatch-style</strong> &mdash; <code>mp_fraglimit</code>, ending on individual kills.</li></ul><pre>// casual public example
10 +mp_timelimit 25
11 +mp_maxrounds 0
12 +mp_winlimit 0
13 +mp_fraglimit 0</pre><h2>4. Set the limit to 0 to disable it</h2><p>Every one of these is disabled by <code>0</code>. The dangerous combination is <strong>all four at 0</strong>: nothing ends the map, the rotation freezes, and it looks like your <a href="/tutorials/mapcycle-txt-setup">mapcycle</a> is broken when in fact nothing is telling the map to end. If a server loops one map forever, check these four cvars before touching the cycle file.</p><h2>5. Leave room for the end-of-map vote</h2><p>If you run an end-of-map vote or Rock The Vote, it is scheduled off <code>mp_timelimit</code> &mdash; the vote pops in the closing minutes of the time limit. A purely round-based flow (<code>mp_timelimit 0</code>, <code>mp_maxrounds 30</code>) gives the vote nothing to hook onto, so the vote never appears. If you want both a round limit and a vote, keep a generous <code>mp_timelimit</code> as a backstop so the vote still fires. See <a href="/tutorials/rtv-nextmap-setup">the RTV and nextmap guide</a> for how the vote timing works, and the full <a href="/tutorials/mp-cvars-reference">mp_ cvars reference</a> for the round-timing cvars that shape play between these limits.</p><h2>6. A worked example</h2><p>Say you run a competitive 5v5 and want a clean MR15 &mdash; first team to 16 wins, or 30 rounds played, whichever settles it &mdash; with a two-minute buffer at the end for the scoreboard. The flow is round-governed, so the round cvars lead and time is only a safety net:</p><pre>mp_maxrounds 30 // 30 rounds = MR15
14 +mp_winlimit 16 // a team clinching 16 ends it immediately
15 +mp_timelimit 0 // no clock; rounds decide the map
16 +mp_fraglimit 0 // not a deathmatch
17 +mp_chattime 10 // end-of-map scoreboard window</pre><p>Here <code>mp_winlimit 16</code> and <code>mp_maxrounds 30</code> describe the <em>same</em> ending from two angles &mdash; a 16&ndash;14 result trips the win limit at round 30, a 16&ndash;6 result trips it early at round 22 &mdash; and either way the map ends and the <a href="/tutorials/mapcycle-txt-setup">cycle</a> advances. Now contrast a casual public box: there you want <code>mp_timelimit 25</code> leading with every round cvar at <code>0</code>, so maps last a predictable wall-clock length regardless of score. The two configurations are opposites, and the point is to choose one philosophy &mdash; clock or rounds &mdash; rather than half-setting both and getting a map that ends at a moment nobody predicted.</p><h2>Common errors</h2><ul><li><strong>Map never changes</strong> &mdash; all four limits are <code>0</code>. Set at least one.</li><li><strong><code>mp_maxrounds</code> does nothing</strong> &mdash; you are on stock CS. It needs <a href="/tutorials/install-regamedll-cs16">ReGameDLL_CS</a>.</li><li><strong>Map ends earlier than expected</strong> &mdash; a second limit fired first. Set the ones you do not want to <code>0</code>.</li><li><strong>End-of-map vote never shows</strong> &mdash; <code>mp_timelimit 0</code>. The vote is scheduled off the time limit; keep a non-zero backstop.</li><li><strong>Limits keep reverting</strong> &mdash; ReGameDLL's <code>game.cfg</code> or an AMXX config re-sets them after <code>server.cfg</code>. Trace the execution order.</li></ul><h2>Verification</h2><p>Read the four cvars back in the console:</p><pre>mp_timelimit
18 +mp_maxrounds
19 +mp_winlimit
20 +mp_fraglimit</pre><p>Confirm only the one you want to govern the map is non-zero. Then lower your primary limit to something small &mdash; <code>mp_timelimit 2</code> or <code>mp_maxrounds 2</code> &mdash; on a test server and confirm the map ends and advances to the next <a href="/tutorials/mapcycle-txt-setup">cycle entry</a> exactly when that limit is hit. Restore your real values once the flow behaves.</p>
+78 -0 zhlt-vhlt-compile-parameters/en.md A
@@ -0,0 +1,78 @@
1 +---
2 +title: "VHLT / ZHLT Compile Parameters: Fast Draft vs Final Quality"
3 +excerpt: "What each of the four GoldSrc compile stages does and the real flags that matter — a fast draft pass for iteration and a full-quality pass for release, with no invented switches."
4 +category: "mapping"
5 +tags: "vhlt, compiling"
6 +image: ""
7 +read_time: "8 min read"
8 +---
9 +<p>A CS 1.6 map is built by four separate command-line programs run in order: <code>hlcsg</code>, <code>hlbsp</code>, <code>hlvis</code> and <code>hlrad</code>. Each takes its own flags, and the difference between a 20-second iteration compile and a 40-minute release compile is entirely in those flags. There is no single <code>-final</code> switch that does everything; "final quality" is a specific combination of full visibility and high-quality lighting. This explains the flags that actually exist in Vluzacn's VHLT (the maintained ZHLT fork) and how to build a fast pass and a release pass.</p>
10 +
11 +<h2>1. The four stages</h2>
12 +<table>
13 +<thead><tr><th>Tool</th><th>Job</th><th>Skippable for a draft?</th></tr></thead>
14 +<tbody>
15 +<tr><td><code>hlcsg</code></td><td>Turns brushes into raw geometry, bakes WAD textures.</td><td>No — always runs.</td></tr>
16 +<tr><td><code>hlbsp</code></td><td>Builds the BSP tree, detects <a href="/tutorials/fix-leak-in-hull-pointfile">leaks</a>.</td><td>No — always runs.</td></tr>
17 +<tr><td><code>hlvis</code></td><td>Computes what is visible from where (PVS).</td><td>Yes, but the map renders everything at once.</td></tr>
18 +<tr><td><code>hlrad</code></td><td>Calculates lighting and shadows.</td><td>Yes, but the map is fullbright.</td></tr>
19 +</tbody>
20 +</table>
21 +
22 +<h2>2. hlvis flags: the visibility trade-off</h2>
23 +<p><code>hlvis</code> is the slow stage on large maps. It has two real quality levels:</p>
24 +<pre>hlvis -fast mymap // rough PVS, quick, over-draws — fine for testing
25 +hlvis -full mymap // full PVS, slow, tight — use for release</pre>
26 +<p>Run with no flag for the default (mid) quality. Never ship a <code>-fast</code> vis compile: it over-renders and hurts client FPS in busy areas.</p>
27 +
28 +<h2>3. hlrad flags: the lighting quality</h2>
29 +<p><code>hlrad</code> is where a map goes from flat to good-looking, and where release compiles spend most of their time. The flags that matter:</p>
30 +<pre>hlrad -extra mymap // supersampled lighting, much smoother shadows
31 +hlrad -bounce 8 mymap // number of radiosity bounces (default is low)
32 +hlrad -chop 64 mymap // luxel patch size; smaller = finer, slower
33 +hlrad -smooth 50 mymap // angle below which faces are smooth-shaded
34 +hlrad -sparse mymap // lower memory, slightly slower vis matrix
35 +hlrad -fast mymap // quick, blocky lighting for a draft</pre>
36 +<p>For release, <code>-extra</code> plus a few extra bounces is the classic quality combination. For iteration, <code>-fast</code> (or skipping RAD entirely) keeps the loop tight.</p>
37 +
38 +<h2>4. hlcsg and hlbsp flags worth knowing</h2>
39 +<pre>hlcsg -wadautodetect mymap // only include WADs actually used
40 +hlcsg -nowadtextures mymap // embed textures in the BSP (no external WAD)
41 +hlcsg -onlyents mymap // re-export entities only, no geometry rebuild
42 +hlbsp -leakonly mymap // stop at the first leak, skip the rest
43 +hlbsp -nofill mymap // do not auto-fill; useful when hunting leaks
44 +hlbsp -subdivide 512 mymap // face subdivision size</pre>
45 +<p><code>-onlyents</code> is a huge time-saver: if you only changed entity keyvalues (a light color, a spawn angle) you can re-export entities in seconds without recompiling geometry, VIS or RAD.</p>
46 +
47 +<h2>5. Shared diagnostic flags</h2>
48 +<p>Most stages accept these, and they are worth adding to every compile:</p>
49 +<pre>-chart // print a resource usage chart (planes, clipnodes, textures)
50 +-estimate // show a running time/percentage estimate
51 +-verbose // detailed output for debugging a stuck stage
52 +-low // run at low CPU priority so the machine stays usable
53 +-texdata 16000 // raise texture memory limit for texture-heavy maps</pre>
54 +<p>The <code>-chart</code> output is your early warning for hitting engine limits — clipnodes and planes have hard ceilings, and a map that is near them will fail to run on a server even if it compiles.</p>
55 +
56 +<h2>6. A draft pass and a release pass</h2>
57 +<p>Use two saved presets in <a href="/tutorials/jack-editor-setup-cs16">J.A.C.K.</a>. A fast iteration pass:</p>
58 +<pre>hlcsg -wadautodetect mymap
59 +hlbsp mymap
60 +hlvis -fast mymap
61 +hlrad -fast mymap</pre>
62 +<p>A release pass:</p>
63 +<pre>hlcsg -wadautodetect -chart mymap
64 +hlbsp -chart mymap
65 +hlvis -full mymap
66 +hlrad -extra -bounce 8 -chart mymap</pre>
67 +
68 +<h2>Troubleshooting</h2>
69 +<ul>
70 +<li><strong>Compile takes forever on VIS</strong> — you ran <code>-full</code> on a leaking or over-sized map. Fix the <a href="/tutorials/fix-leak-in-hull-pointfile">leak</a> first; VIS should never run on a leaked map.</li>
71 +<li><strong>Lighting is blocky/pixelated</strong> — you compiled RAD with <code>-fast</code>. Re-run with <code>-extra</code> for release.</li>
72 +<li><strong>"Exceeded MAX_MAP_CLIPNODES" or similar</strong> — you hit an engine limit; the <code>-chart</code> output shows which. Simplify geometry or tie decorative brushes to <code>func_detail</code> so they leave the BSP hulls.</li>
73 +<li><strong>Textures missing after compile</strong> — <code>-nowadtextures</code> was off and the WAD is not on the server, or a WAD went missing. Either ship the WAD or embed with <code>-nowadtextures</code>.</li>
74 +<li><strong>Entity change not showing</strong> — you used <code>-onlyents</code> but also moved brushes; that flag ignores geometry. Do a full compile after any brush edit.</li>
75 +</ul>
76 +
77 +<h2>Verification</h2>
78 +<p>Run the release preset and read the tail of the console: <code>hlvis</code> and <code>hlrad</code> should both complete with a <code>-chart</code> summary and no leak warning. Load the map and confirm the lighting is smooth (no jagged shadow edges) and that distant rooms are culled when you cannot see them. Keep the draft preset for day-to-day edits and only pay for the full pass at release. If VIS or RAD refuse to run at all, the map is almost always leaking — go back to the <a href="/tutorials/fix-leak-in-hull-pointfile">pointfile guide</a>.</p>
0 79