Add 6 tutorials (6 files)
Browse Source
6 changed files
with 304 additions and 0 deletions
A
amx-map-extendmap/en.md
+49 -0
A
competitive-5v5-config/en.md
+76 -0
A
cs16-connection-failed-retries-client/en.md
+45 -0
A
hlds-vs-rehlds-explained/en.md
+52 -0
A
per-map-config-files/en.md
+69 -0
A
unban-a-player/en.md
+13 -0
amx-map-extendmap/en.md
A
| @@ -0,0 +1,49 @@ | ||
| 1 | +--- | |
| 2 | +title: "amx_map, amx_extendmap and Changelevel Commands" | |
| 3 | +excerpt: "The difference between amx_map, the engine changelevel command and amx_votemap, how extending a map really works, and how to avoid a failed changelevel." | |
| 4 | +category: "administration" | |
| 5 | +tags: "maps, admin" | |
| 6 | +image: "" | |
| 7 | +read_time: "8 min read" | |
| 8 | +--- | |
| 9 | +<p>There are three different ways to change or prolong the current map on a CS 1.6 server, and admins routinely confuse them: the AMX Mod X <code>amx_map</code> command, the raw engine <code>changelevel</code>, and map <em>extension</em>. They behave differently — one validates the map for you and one will happily try to load a map that does not exist — so it is worth knowing exactly which does what.</p> | |
| 10 | + | |
| 11 | +<h2>1. amx_map: the safe admin command</h2> | |
| 12 | +<p><code>amx_map</code> is provided by the AMXX admin-commands plugin. It changes the level, but first it validates that the map exists on disk and gives players a short heads-up before the switch:</p> | |
| 13 | +<pre>amx_map de_inferno</pre> | |
| 14 | +<p>Because it checks the map before committing, a typo gets rejected with a message rather than dropping everyone into a broken load. It requires the map-change access flag (see the <a href="/tutorials/amxx-admin-flags-reference">flags reference</a>). This is the command you should use day to day.</p> | |
| 15 | + | |
| 16 | +<h2>2. changelevel: the raw engine command</h2> | |
| 17 | +<p><code>changelevel</code> is a built-in engine command, not an AMXX one. It changes the map immediately with no validation and no warning:</p> | |
| 18 | +<pre>changelevel de_nuke</pre> | |
| 19 | +<p>It is fine from RCON or the server console when you know the map is installed, but it has two sharp edges. First, it does no existence check — point it at a missing map and the server fails the transition. Second, because it bypasses the <a href="/tutorials/mapcycle-txt-setup">mapcycle</a> position logic, jumping to a map that is not in your cycle resets the rotation to the top afterwards. Prefer <code>amx_map</code> unless you have a specific reason to use the engine command directly.</p> | |
| 20 | + | |
| 21 | +<h2>3. amx_votemap: let players decide</h2> | |
| 22 | +<p>When you would rather put the change to a vote than force it, use <code>amx_votemap</code>:</p> | |
| 23 | +<pre>amx_votemap de_dust2 de_train cs_office</pre> | |
| 24 | +<p>This opens a short vote between the listed maps and changes to the winner. For a permanent player-driven system rather than a one-off admin vote, install <a href="/tutorials/rtv-nextmap-setup">Rock The Vote and nextmap</a> instead — that is the maintained way to hand map choice to players.</p> | |
| 25 | + | |
| 26 | +<h2>4. Extending the current map</h2> | |
| 27 | +<p>Extending means keeping the <em>current</em> map running longer by pushing back <code>mp_timelimit</code>, rather than changing to a new one. The extend feature is part of the end-of-map vote system (<code>mapchooser</code>) and is governed by two cvars:</p> | |
| 28 | +<pre>amx_extendmap_max 90 // ceiling: a map may be extended to at most this many minutes total | |
| 29 | +amx_extendmap_step 15 // how many minutes each successful "Extend" adds</pre> | |
| 30 | +<p>When "Extend" wins the end-map vote, the plugin raises <code>mp_timelimit</code> by the step, up to the max. There is no universal stock <code>amx_extendmap</code> command in a default install — an explicit "extend now" admin command comes from an add-on plugin such as <a href="/plugins/csb-admin-extend-map">CSB Admin Extend Map</a>. If you want admins to extend on demand rather than only through a vote, install that plugin; the cvars above still cap how far it can go.</p> | |
| 31 | + | |
| 32 | +<h2>5. Manual extend without a plugin</h2> | |
| 33 | +<p>You can always extend by hand from RCON by raising the time limit on the fly:</p> | |
| 34 | +<pre>mp_timelimit 45</pre> | |
| 35 | +<p>That adds time to the running map immediately. It is blunt but reliable, and it is exactly what the extend feature automates. Just remember the value is in minutes and it applies to the current map only — the next map starts fresh from whatever your config sets. For the full list of round and map timing cvars, see the <a href="/tutorials/mp-cvars-reference">mp_ cvars reference</a>.</p> | |
| 36 | + | |
| 37 | +<h2>Common errors</h2> | |
| 38 | +<ul> | |
| 39 | +<li><strong><code>changelevel failed</code> or the server hangs on switch</strong> — the target map is not in <code>cstrike/maps/</code>. Use <code>amx_map</code>, which validates first, or confirm the <code>.bsp</code> is installed.</li> | |
| 40 | +<li><strong>Rotation jumps to the first map after a manual change</strong> — you used <code>changelevel</code> (or <code>amx_map</code>) to a map not in the cycle. That is expected; add the map to <code>mapcycle.txt</code> if you want it in rotation.</li> | |
| 41 | +<li><strong>Extend does nothing</strong> — <code>mp_timelimit</code> is 0, so there is no time limit to extend. Set a real limit first.</li> | |
| 42 | +<li><strong>Map extends forever</strong> — <code>amx_extendmap_max</code> is too high or unset, so a popular map never ends. Cap it to a sane ceiling.</li> | |
| 43 | +<li><strong><code>Unknown command: amx_extendmap</code></strong> — there is no such stock command; the on-demand extend comes from an add-on plugin. Install one or raise <code>mp_timelimit</code> manually.</li> | |
| 44 | +</ul> | |
| 45 | + | |
| 46 | +<h2>Verification</h2> | |
| 47 | +<p>Run <code>amx_map</code> with a valid map and confirm the warning appears and the switch completes. Try it with a deliberately misspelled name and confirm it is rejected rather than crashing the server. To test extend, set <code>mp_timelimit 2</code>, let the end-map vote appear, choose Extend, and read the limit back:</p> | |
| 48 | +<pre>mp_timelimit</pre> | |
| 49 | +<p>It should now show the original value plus <code>amx_extendmap_step</code>, capped at the max. Once the map controls behave, tie them into your rotation with the <a href="/tutorials/mapcycle-txt-setup">mapcycle.txt guide</a>.</p> |
competitive-5v5-config/en.md
A
| @@ -0,0 +1,76 @@ | ||
| 1 | +--- | |
| 2 | +title: "Competitive 5v5 Config (ESL Style) for CS 1.6" | |
| 3 | +excerpt: "A clean 5v5 match config for CS 1.6: the mp_ cvars ESL-style play expects, why a match plugin handles the score and knife round, and how to keep the pug config separate from your public one." | |
| 4 | +category: "administration" | |
| 5 | +tags: "competitive, config" | |
| 6 | +image: "" | |
| 7 | +read_time: "9 min read" | |
| 8 | +--- | |
| 9 | +<p>A competitive 5v5 config is not just \"public server with friendly fire on.\" It is a specific, deliberately austere ruleset — fixed economy timings, no auto-balancing, restricted spectating, friendly fire enabled with team-kill punishment removed — loaded on demand for a match and unloaded afterward. This walks through the cvars that matter, what belongs in the config versus a match plugin, and how to keep it from bleeding into your public settings.</p> | |
| 10 | + | |
| 11 | +<h2>1. Keep the match config separate</h2> | |
| 12 | +<p>Do not put competitive values in <code>server.cfg</code>. Create a dedicated file, <code>cstrike/match.cfg</code>, that you <code>exec</code> when a match starts and that a public config overwrites when it ends. That way your <a href="/tutorials/setup-server-cfg-cs16">public server.cfg</a> is the resting state and the match settings are a temporary overlay:</p> | |
| 13 | +<pre>// in-game / rcon | |
| 14 | +exec match.cfg // switch to competitive rules | |
| 15 | +// ... play the match ... | |
| 16 | +exec public.cfg // restore public rules</pre> | |
| 17 | + | |
| 18 | +<h2>2. The core round and economy cvars</h2> | |
| 19 | +<p>These are the values ESL-style 5on5 has used for years. Units matter — roundtime and buytime are in <em>minutes</em> (see the <a href="/tutorials/mp-cvars-reference">mp_ cvars reference</a>):</p> | |
| 20 | +<pre>// match.cfg -- round & economy | |
| 21 | +mp_freezetime 6 | |
| 22 | +mp_roundtime 1.75 // 1:45, standard for de_ maps | |
| 23 | +mp_startmoney 800 | |
| 24 | +mp_buytime 0.25 // 15 seconds | |
| 25 | +mp_c4timer 35 // classic competitive fuse | |
| 26 | +mp_maxrounds 0 // the match plugin controls score, not this | |
| 27 | +mp_timelimit 0 // no time-based map change during a match</pre> | |
| 28 | + | |
| 29 | +<h2>3. Fair-play and team cvars</h2> | |
| 30 | +<p>Competitive turns off the conveniences a public server wants. Friendly fire is on, but automatic team-kill punishment is off because the referee/admin handles it; teams are never auto-shuffled:</p> | |
| 31 | +<pre>// match.cfg -- fair play | |
| 32 | +mp_friendlyfire 1 | |
| 33 | +mp_tkpunish 0 // FF on, but no auto-punish -- admins decide | |
| 34 | +mp_autoteambalance 0 // never move players between teams | |
| 35 | +mp_limitteams 0 // 5v5 is set by the players, not the engine | |
| 36 | +mp_hostagepenalty 0 // irrelevant on de_ maps; avoid accidental kicks | |
| 37 | +mp_forcecamera 2 // dead players locked -- anti-ghosting | |
| 38 | +mp_fadetoblack 0 // most leagues play with this off; agree beforehand</pre> | |
| 39 | +<p><code>mp_forcecamera 2</code> (also seen as <code>mp_forcechasecam</code> on some builds) is the anti-ghosting rule: a dead player cannot free-fly the map and call positions. Confirm the exact cvar name on your build — type it in console with no argument and see if it echoes a value.</p> | |
| 40 | + | |
| 41 | +<h2>4. Movement, sound and rates</h2> | |
| 42 | +<p>Competitive play wants full information and headroom on the network. Keep footsteps and flashlight on, standard movement speed, and generous rates so nobody is rate-limited during a clutch:</p> | |
| 43 | +<pre>// match.cfg -- feel & network | |
| 44 | +mp_footsteps 1 | |
| 45 | +mp_flashlight 1 | |
| 46 | +sv_maxspeed 320 | |
| 47 | +sv_maxrate 25000 | |
| 48 | +sv_minrate 20000 | |
| 49 | +sv_maxupdaterate 101 | |
| 50 | +sv_minupdaterate 60 | |
| 51 | +sv_cheats 0 | |
| 52 | +mp_logdetail 3 // log attacks + kills for review | |
| 53 | +mp_logmessages 1</pre> | |
| 54 | +<p>The update rate ceiling is only real if your server FPS can sustain it — promising 101 on a 60 FPS box just produces choke. See <a href="/tutorials/sys-ticrate-truth">the sys_ticrate truth</a> and the <a href="/tutorials/essential-server-cvars">essential cvars list</a>.</p> | |
| 55 | + | |
| 56 | +<h2>5. Let a match plugin run the actual match</h2> | |
| 57 | +<p>The config sets the <em>rules</em>; it does not run the <em>match</em>. The score, the MR15 half-switch, the knife round for side selection, the ready-up (<code>.ready</code>/<code>.live</code>), warmup, and the score printout are all the job of a match/PUG plugin. Do not try to reproduce that with <code>mp_maxrounds</code> alone — you will get a map change mid-match at the worst moment. Install a maintained match plugin and let it own the flow; the <a href="/plugins/csb-match-manager">CSB Match Manager</a> handles ready-up, knife round, half-switch and score for a standard 5v5. On <a href="/tutorials/install-regamedll-cs16">ReGameDLL</a> these plugins are more reliable because round-end and money hooks are exposed cleanly through ReAPI.</p> | |
| 58 | + | |
| 59 | +<h2>Common errors</h2> | |
| 60 | +<ul> | |
| 61 | +<li><strong>Map changes in the middle of a match</strong> — you left <code>mp_maxrounds</code> or <code>mp_timelimit</code> non-zero and it fired. Zero both and let the match plugin end the map.</li> | |
| 62 | +<li><strong>Buytime is way too long</strong> — <code>mp_buytime 15</code> is 15 <em>minutes</em>. Use <code>0.25</code> for 15 seconds.</li> | |
| 63 | +<li><strong>Dead players calling positions</strong> — <code>mp_forcecamera</code> is 0. Set it to lock spectating; confirm the cvar name your build uses.</li> | |
| 64 | +<li><strong>Teams get shuffled at halftime</strong> — <code>mp_autoteambalance 1</code> is still on from the public config. The match overlay must set it to 0.</li> | |
| 65 | +<li><strong>Public settings never came back</strong> — you execed <code>match.cfg</code> but never restored the public config. Keep a <code>public.cfg</code> and exec it (or change the map) after the match.</li> | |
| 66 | +<li><strong>A cvar \"does not exist\"</strong> — it is a ReGameDLL-only cvar and you are on stock CS. Install ReGameDLL or drop that line.</li> | |
| 67 | +</ul> | |
| 68 | + | |
| 69 | +<h2>Verification</h2> | |
| 70 | +<p>Load the config and read the key values back before anyone joins:</p> | |
| 71 | +<pre>exec match.cfg | |
| 72 | +mp_freezetime | |
| 73 | +mp_roundtime | |
| 74 | +mp_friendlyfire | |
| 75 | +mp_autoteambalance</pre> | |
| 76 | +<p>Each should echo the competitive value. Then run a knife round through your match plugin and confirm the side switch and score are correct at MR15. Finally, <code>exec public.cfg</code> and verify friendly fire and auto-balance return to your public defaults — the overlay is only safe if it cleanly reverts.</p> |
cs16-connection-failed-retries-client/en.md
A
| @@ -0,0 +1,45 @@ | ||
| 1 | +--- | |
| 2 | +title: "Fix: 'Connection failed after 4 retries' in CS 1.6 (Client Side)" | |
| 3 | +excerpt: "The client-side causes of CS 1.6's 'Connection failed after 4 retries' error — wrong port, blocked UDP, firewall, protocol mismatch — and how to work through each." | |
| 4 | +category: "client" | |
| 5 | +tags: "connect, network" | |
| 6 | +image: "" | |
| 7 | +read_time: "8 min read" | |
| 8 | +--- | |
| 9 | +<p>You type an address, the game tries, and after a few seconds you get:</p> | |
| 10 | +<blockquote>Connection failed after 4 retries.</blockquote> | |
| 11 | +<p>This means your client sent connection requests and heard nothing back. It is a network-reachability failure, not a game bug, and when it happens on servers that other people can join, the cause is on your end. This guide works through the client-side possibilities in the order most likely to be the culprit.</p> | |
| 12 | + | |
| 13 | +<h2>1. Confirm the address and port are exactly right</h2> | |
| 14 | +<p>The commonest cause is a wrong port. CS 1.6 defaults to <strong>27015</strong>, but many community servers share one IP and differ only by port:</p> | |
| 15 | +<pre>connect 203.0.113.10:27016</pre> | |
| 16 | +<p>A single wrong digit, or omitting the port on a server that does not use 27015, produces this exact error because your packets go nowhere. Copy the address fresh from the source and include the port explicitly. If you reached it before, use <code>retry</code> rather than retyping.</p> | |
| 17 | + | |
| 18 | +<h2>2. Check the server is actually up and not full</h2> | |
| 19 | +<p>Before blaming your machine, confirm someone else can join. If the server is down, restarting, or full, everyone gets the retries error — that is not yours to fix. A server mid map-change also refuses connections for a few seconds; wait and <code>retry</code>.</p> | |
| 20 | + | |
| 21 | +<h2>3. Rule out your firewall and antivirus</h2> | |
| 22 | +<p>CS 1.6 talks over <strong>UDP</strong>. A firewall or antivirus that blocks outbound UDP from <code>hl.exe</code> lets nothing through and every server fails identically. On Windows, allow Half-Life / Counter-Strike through the firewall for both private and public networks, and whitelist <code>hl.exe</code> in your antivirus. The tell here is that <em>every</em> server fails, including ones you connected to yesterday.</p> | |
| 23 | + | |
| 24 | +<h2>4. Restart your router and clear a stuck NAT</h2> | |
| 25 | +<p>Home routers occasionally wedge the UDP mapping the game needs. A full power-cycle of the router (off 30 seconds, on) clears stale NAT entries. If you are behind a strict or double NAT (a second router, some mobile hotspots, or carrier-grade NAT), outbound UDP to game ports can be dropped entirely — test on a different connection to confirm.</p> | |
| 26 | + | |
| 27 | +<h2>5. Check for a protocol or version mismatch</h2> | |
| 28 | +<p>After the 2023 25th Anniversary update, some servers and clients ended up on incompatible protocols, and a mismatched client can fail to complete the handshake. If you can reach old servers but not updated ones (or vice versa), roll your client between the current build and the <code>steam_legacy</code> beta branch — the same fix used for <a href="/tutorials/cs16-crashes-on-startup">startup crashes after the update</a>. Right-click Counter-Strike in Steam, Properties, Betas, and pick <code>steam_legacy</code> to opt into the pre-update build, or None to return to current.</p> | |
| 29 | + | |
| 30 | +<h2>6. Try a clean network path</h2> | |
| 31 | +<p>A VPN, proxy, or aggressive "gaming optimizer" can mangle UDP. Disable them and connect directly. If a VPN is the only way you reach a geo-restricted server, try a different endpoint — some VPN exit nodes block game UDP.</p> | |
| 32 | + | |
| 33 | +<h2>Common errors</h2> | |
| 34 | +<ul> | |
| 35 | +<li><strong>Every server fails, including ones that worked before</strong> — local: firewall/antivirus blocking <code>hl.exe</code>, a wedged router, or a VPN. Work through steps 3–6.</li> | |
| 36 | +<li><strong>Only one server fails</strong> — that server is down, full, restarting, or you have the wrong port. Not your client. Confirm with <a href="/tutorials/cs16-connect-via-console">a direct console connect</a> on the exact port.</li> | |
| 37 | +<li><strong>Fails only on updated (or only on legacy) servers</strong> — protocol mismatch from the Anniversary update. Switch the <code>steam_legacy</code> beta branch.</li> | |
| 38 | +<li><strong>Connects then instantly drops with the same message</strong> — a rate or client-command setting the server rejects; reset your rates to defaults and retry.</li> | |
| 39 | +<li><strong>Works on mobile hotspot but not home</strong> — your home firewall or router is blocking UDP. Fix the firewall rule and power-cycle the router.</li> | |
| 40 | +</ul> | |
| 41 | + | |
| 42 | +<h2>Verification</h2> | |
| 43 | +<p>The fastest way to isolate the fault is to connect to a busy, known-good server by console:</p> | |
| 44 | +<pre>connect 203.0.113.10:27015</pre> | |
| 45 | +<p>If that joins, your network is fine and the original server was the problem. If it also fails, the cause is local — recheck the firewall and router first. To prove it is not the whole install, host a listen server (Create Server from the menu) and connect to <code>127.0.0.1</code>; a loopback join that works confirms the game is healthy and the issue is purely reaching the internet. Once you can join one real server reliably, the retries error is beaten.</p> |
hlds-vs-rehlds-explained/en.md
A
| @@ -0,0 +1,52 @@ | ||
| 1 | +--- | |
| 2 | +title: "HLDS vs ReHLDS: What Changed and Why Admins Switched" | |
| 3 | +excerpt: "A straight comparison of Valve's original HLDS engine and the ReHLDS reimplementation: performance, security fixes, extra cvars, and how it fits with ReGameDLL and ReAPI." | |
| 4 | +category: "misc" | |
| 5 | +tags: "rehlds, comparison" | |
| 6 | +image: "" | |
| 7 | +read_time: "8 min read" | |
| 8 | +--- | |
| 9 | +<p>For years there was one way to run a CS 1.6 server: Valve's <strong>HLDS</strong> (Half-Life Dedicated Server), a closed binary that had not meaningfully changed in a decade. Today most serious servers run <strong>ReHLDS</strong> instead — a clean-room reimplementation of that same engine maintained by the <code>rehlds</code> project. It is a drop-in replacement, not a mod, and understanding what it does (and does not) change clears up most of the confusion around the modern "Re" stack.</p> | |
| 10 | + | |
| 11 | +<h2>1. What HLDS actually is</h2> | |
| 12 | +<p>HLDS is the dedicated-server build of the GoldSrc engine — the executable and <code>engine</code> shared library (<code>engine_i486.so</code> on Linux, <code>swds.dll</code> on Windows) that runs the networking, physics, entity system and master-server heartbeat. On top of it sits the game logic (<code>mp.dll</code> / <code>cs.so</code>), and on top of that Metamod and AMX Mod X. HLDS is stable and battle-tested, but Valve stopped developing it, so its old bugs, exploits and limits are frozen in place.</p> | |
| 13 | + | |
| 14 | +<h2>2. What ReHLDS replaces</h2> | |
| 15 | +<p>ReHLDS reimplements the engine layer only — you swap the engine binary and keep everything else. Because it is binary-compatible, your existing <a href="/tutorials/install-metamod-r">Metamod</a>, <a href="/tutorials/what-is-amx-mod-x">AMX Mod X</a> and plugins keep working unchanged. It does not touch game rules; that is <a href="/tutorials/install-regamedll-cs16">ReGameDLL_CS</a>'s job. The three layers of the "Re" stack are independent:</p> | |
| 16 | +<table> | |
| 17 | +<thead><tr><th>Layer</th><th>Original</th><th>Re-implementation</th></tr></thead> | |
| 18 | +<tbody> | |
| 19 | +<tr><td>Engine</td><td>HLDS</td><td>ReHLDS</td></tr> | |
| 20 | +<tr><td>Game rules</td><td>mp.dll / cs.so</td><td>ReGameDLL_CS</td></tr> | |
| 21 | +<tr><td>Metamod loader</td><td>Metamod-P</td><td>Metamod-r</td></tr> | |
| 22 | +</tbody> | |
| 23 | +</table> | |
| 24 | + | |
| 25 | +<h2>3. Why admins switched</h2> | |
| 26 | +<ul> | |
| 27 | +<li><strong>Performance.</strong> ReHLDS is optimized modern C++ and generally runs the same load with lower CPU, which matters when you host <a href="/tutorials/multiple-cs16-servers-one-vps">several servers on one VPS</a> or chase a <a href="/tutorials/stable-1000-fps-linux-server">stable 1000 FPS</a>.</li> | |
| 28 | +<li><strong>Security.</strong> Many remote crashes and buffer-overflow exploits that plague old HLDS are patched. This is the biggest single reason to switch — an unpatched HLDS is a soft target.</li> | |
| 29 | +<li><strong>Extra cvars and hooks.</strong> ReHLDS exposes tuning and hardening cvars (the <code>sv_rehlds_*</code> family) that stock HLDS never had — see the <a href="/tutorials/rehlds-performance-cvars">ReHLDS performance cvars</a>.</li> | |
| 30 | +<li><strong>ReAPI.</strong> ReHLDS + ReGameDLL together enable <a href="/tutorials/reapi-getting-started">ReAPI</a>, a modern plugin API that hooks engine and game events cleanly instead of the old fakemeta/orpheu hacks.</li> | |
| 31 | +<li><strong>Active maintenance.</strong> Bugs get fixed and releases keep coming, which HLDS has not seen in years.</li> | |
| 32 | +</ul> | |
| 33 | + | |
| 34 | +<h2>4. What it does not change</h2> | |
| 35 | +<p>ReHLDS is still the GoldSrc engine — same protocol, same clients, same map format, same content limits in most respects. It does not make your server non-Steam by itself (that is <a href="/tutorials/install-reunion">Reunion</a>), does not add new gameplay (that is ReGameDLL and plugins), and does not magically stop DDoS. It also will not fix a badly configured server: rates, <code>sv_lan 0</code> and firewalling still matter exactly as before. If you are hardening against floods, that is still an OS-level job — see <a href="/tutorials/block-udp-flood-iptables">blocking UDP floods with iptables</a>, independent of which engine you run.</p> | |
| 36 | + | |
| 37 | +<h2>5. Is it a drop-in, really?</h2> | |
| 38 | +<p>In practice, yes. You place the ReHLDS engine binary and its support files over an existing, working HLDS install; the game content, maps, configs and add-ons stay where they are. Nothing about <code>server.cfg</code>, <a href="/tutorials/mapcycle-txt-setup">mapcycle.txt</a> or your <a href="/tutorials/plugins-ini-load-order">plugins.ini</a> changes. Because the engine ABI is preserved, Metamod loads exactly as before and AMXX sits on top unchanged. The main thing to get right is matching the ReHLDS build to your platform — the Linux engine is still 32-bit, so the usual <a href="/tutorials/install-32bit-libraries-cs16-linux">i386 library requirements</a> apply just as they do for stock HLDS. Keep a backup of the original engine binary so you can roll back in seconds if a specific build misbehaves.</p> | |
| 39 | + | |
| 40 | +<h2>6. The 25th Anniversary angle</h2> | |
| 41 | +<p>Valve's 2023 25th Anniversary update changed client behavior and broke a wave of old servers and plugins. ReHLDS tracks these protocol changes and is generally quicker to stay compatible than a frozen HLDS install. If your server broke after that update, moving to a current ReHLDS is often part of the fix — see <a href="/tutorials/fix-25th-anniversary-server-broken">the anniversary breakage guide</a> and the <a href="/tutorials/cs16-steam-legacy-beta">steam_legacy rollback</a>.</p> | |
| 42 | + | |
| 43 | +<h2>Common questions</h2> | |
| 44 | +<ul> | |
| 45 | +<li><strong>Do my plugins need recompiling?</strong> No. ReHLDS is binary-compatible; AMXX plugins run as-is. You only recompile if you adopt ReAPI-based plugins.</li> | |
| 46 | +<li><strong>Can I run ReHLDS without ReGameDLL?</strong> Yes — the layers are independent. But most people who install one install both, because ReAPI and the extra <code>mp_</code> cvars need ReGameDLL.</li> | |
| 47 | +<li><strong>Is it against the rules?</strong> No. It is a widely used, legitimate engine replacement for community servers.</li> | |
| 48 | +<li><strong>Is it harder to install?</strong> Not really — you drop the ReHLDS files over a normal install. See <a href="/tutorials/install-rehlds-on-linux">installing ReHLDS on Linux</a> or <a href="/tutorials/install-rehlds-on-windows">on Windows</a>.</li> | |
| 49 | +</ul> | |
| 50 | + | |
| 51 | +<h2>Verification</h2> | |
| 52 | +<p>After installing ReHLDS, the server console prints the ReHLDS version banner on startup instead of the stock HLDS build string, and the <code>sv_rehlds_*</code> cvars exist (type one with no argument and it echoes a value rather than nothing). Confirm your plugins still load with <code>amxx plugins</code>, then measure CPU under a realistic player count and compare against your old HLDS baseline. If you plan to build the engine yourself for a specific patch level, see <a href="/tutorials/build-rehlds-from-source">building ReHLDS from source</a>.</p> |
per-map-config-files/en.md
A
| @@ -0,0 +1,69 @@ | ||
| 1 | +--- | |
| 2 | +title: "Per-Map Configs (maps/mapname.cfg)" | |
| 3 | +excerpt: "Stock HLDS does not auto-execute a per-map config. Here is the mapchangecfgfile workaround and a small AMX Mod X plugin that reliably execs maps/mapname.cfg on every map." | |
| 4 | +category: "administration" | |
| 5 | +tags: "config, maps" | |
| 6 | +image: "" | |
| 7 | +read_time: "8 min read" | |
| 8 | +--- | |
| 9 | +<p>It is a widespread belief that CS 1.6 automatically runs <code>maps/de_dust2.cfg</code> when it loads <code>de_dust2</code>. It does not. Stock HLDS has no built-in per-map config auto-exec, which is why so many admins swear their <code>maps/*.cfg</code> files are being ignored — they are. This explains what the engine really does, the one stock hook that comes close, and a tiny plugin that gives you true per-map configs.</p> | |
| 10 | + | |
| 11 | +<h2>1. What the engine actually executes on a map change</h2> | |
| 12 | +<p>At the start of every map the engine runs <a href="/tutorials/setup-server-cfg-cs16">server.cfg</a>, and if you have set it, the file named by <code>mapchangecfgfile</code>. That is the whole list. There is no name-based lookup for <code>maps/<currentmap>.cfg</code> anywhere in stock HLDS. Any tutorial that tells you to just drop <code>maps/de_dust2.cfg</code> and expect it to run is repeating a myth.</p> | |
| 13 | + | |
| 14 | +<h2>2. The stock hook: mapchangecfgfile</h2> | |
| 15 | +<p>The engine does expose one config that runs on <em>every</em> map change:</p> | |
| 16 | +<pre>// server.cfg | |
| 17 | +mapchangecfgfile "onchange.cfg"</pre> | |
| 18 | +<p>This is useful for settings that must re-apply after each load, but it is the same file for every map — it is not per-map. You can bootstrap per-map behavior from it (read the current map and exec a matching file), but doing that in a config is clumsy. A plugin is cleaner.</p> | |
| 19 | + | |
| 20 | +<h2>3. The reliable way: a small AMXX plugin</h2> | |
| 21 | +<p>The classic solution is a few lines of Pawn that read the current map name and <code>exec</code> a file named after it. This runs once, early, on every map:</p> | |
| 22 | +<pre>#include <amxmodx> | |
| 23 | + | |
| 24 | +public plugin_init() | |
| 25 | +{ | |
| 26 | + register_plugin("Per-Map Config", "1.0", "CSB") | |
| 27 | + | |
| 28 | + new mapname[32] | |
| 29 | + get_mapname(mapname, charsmax(mapname)) | |
| 30 | + | |
| 31 | + new path[64] | |
| 32 | + formatex(path, charsmax(path), "maps/%s.cfg", mapname) | |
| 33 | + | |
| 34 | + // only exec if the file exists, to avoid a console error | |
| 35 | + new full[96] | |
| 36 | + formatex(full, charsmax(full), "%s", path) | |
| 37 | + if (file_exists(full)) | |
| 38 | + server_cmd("exec %s", path) | |
| 39 | +}</pre> | |
| 40 | +<p>Compile it, drop the <code>.amxx</code> in <code>addons/amxmodx/plugins/</code>, and add it to <a href="/tutorials/plugins-ini-load-order">plugins.ini</a>. The <code>exec</code> path is relative to the <code>cstrike/</code> game directory, so the files live in <code>cstrike/maps/de_dust2.cfg</code> and so on. If you would rather not compile your own, a maintained equivalent ships as a <a href="/plugins/csb-map-config">CSB Map Config</a> plugin.</p> | |
| 41 | + | |
| 42 | +<h2>4. What belongs in a per-map config</h2> | |
| 43 | +<p>Keep these files small and specific — only the things that genuinely differ per map:</p> | |
| 44 | +<pre>// cstrike/maps/awp_map.cfg | |
| 45 | +mp_startmoney 16000 | |
| 46 | +mp_buytime 0.1 | |
| 47 | +mp_roundtime 3</pre> | |
| 48 | +<pre>// cstrike/maps/cs_assault.cfg | |
| 49 | +mp_startmoney 800 | |
| 50 | +mp_freezetime 4</pre> | |
| 51 | +<p>Because the engine does not <em>reset</em> cvars between maps, anything you change in one map's cfg persists into the next unless the next map's cfg (or server.cfg) sets it back. That is the number-one per-map gotcha — see the errors below. The cvars themselves are documented in the <a href="/tutorials/mp-cvars-reference">mp_ cvars reference</a>.</p> | |
| 52 | + | |
| 53 | +<h2>5. Reset what you change</h2> | |
| 54 | +<p>Because settings leak forward, treat per-map configs as overrides that every map must fully declare, or set your baseline in <code>server.cfg</code> and only override the deltas per map. The cleanest pattern: put normal values in <code>server.cfg</code>, and in each map cfg change <em>only</em> what that map needs — then add the reset to any map that would otherwise inherit an unwanted value. A map that bumps <code>mp_startmoney</code> to 16000 must be followed by maps that set it back to 800, or every map after the money map is rich.</p> | |
| 55 | + | |
| 56 | +<h2>Troubleshooting</h2> | |
| 57 | +<ul> | |
| 58 | +<li><strong>maps/mapname.cfg is ignored</strong> — you expected stock auto-exec, which does not exist. Install the plugin above or use <code>mapchangecfgfile</code>.</li> | |
| 59 | +<li><strong>Settings bleed into the next map</strong> — cvars are not reset between maps. Each map cfg must declare, or your baseline in server.cfg must reassert, the values.</li> | |
| 60 | +<li><strong><code>exec</code> prints "couldn't exec"</strong> — the file name does not match the map exactly (case, or a stray <code>.cfg.cfg</code> from a Windows editor), or it is not under <code>cstrike/maps/</code>. The plugin's <code>file_exists</code> guard avoids the error for maps with no config.</li> | |
| 61 | +<li><strong>Config runs but values do not stick</strong> — a later config (<code>amxx.cfg</code>, a plugin) re-sets them. Trace the execution order.</li> | |
| 62 | +<li><strong>Plugin does nothing</strong> — not listed in <code>plugins.ini</code>, or <code>amxx plugins</code> shows it as <code>bad load</code>. Fix the load first.</li> | |
| 63 | +</ul> | |
| 64 | + | |
| 65 | +<h2>Verification</h2> | |
| 66 | +<p>Create <code>cstrike/maps/de_dust2.cfg</code> with an obvious value like <code>mp_startmoney 16000</code>, change to that map, and read it back in the console:</p> | |
| 67 | +<pre>changelevel de_dust2 | |
| 68 | +mp_startmoney // should echo 16000</pre> | |
| 69 | +<p>Then change to a different map that does not set it and confirm your baseline reasserts — if it stays at 16000, you have found the leak and need a reset line. Once the pattern holds, keep the per-map files short and version them alongside <code>server.cfg</code>.</p> |
unban-a-player/en.md
A
| @@ -0,0 +1,13 @@ | ||
| 1 | +--- | |
| 2 | +title: "How to Unban a Player (banned Files, In-Game, and SQL)" | |
| 3 | +excerpt: "The three places a CS 1.6 ban lives, the removeid/removeip and writeid/writeip commands that actually delete it, the AMXX amx_unban limits, and how SQL-based bans differ." | |
| 4 | +category: "administration" | |
| 5 | +tags: "bans, admin" | |
| 6 | +image: "" | |
| 7 | +read_time: "8 min read" | |
| 8 | +--- | |
| 9 | +<p>Removing a ban is fiddly because a ban can live in three different places, and clearing it from one does not touch the others. A player still blocked after you "unbanned" them is almost always banned somewhere you did not look. This covers the engine ban list, AMX Mod X commands, and database-backed bans, with the exact commands that remove each and persist the change.</p><h2>1. Know which kind of ban you have</h2><p>There are three independent systems:</p><ul><li><strong>Engine SteamID bans</strong> — added with <code>banid</code>, saved to the id ban file with <code>writeid</code>.</li><li><strong>Engine IP bans</strong> — added with <code>addip</code>, saved to the ip ban file with <code>writeip</code>.</li><li><strong>Plugin/SQL bans</strong> — an AMXX ban plugin storing bans in its own file or a MySQL table, independent of the engine list.</li></ul><p>List the engine bans first so you know what you are dealing with:</p><pre>listid | |
| 10 | +listip</pre><p><code>listid</code> prints every banned SteamID; <code>listip</code> every banned IP. If the player's ID or IP is not in either list, the ban is a plugin/SQL ban and the engine commands below will not help.</p><h2>2. Remove an engine SteamID ban</h2><p>Two steps, and the second is the one people skip:</p><pre>removeid STEAM_0:1:12345678 | |
| 11 | +writeid</pre><p><code>removeid</code> drops the ban from the <em>running</em> server's memory; <code>writeid</code> rewrites the id ban file (commonly <code>banned_user.cfg</code>, or <code>banned.cfg</code> on older builds) so the removal survives a restart. <strong>Skip <code>writeid</code> and the ban comes back on the next map change or reboot</strong>, because the file still lists it and is re-read at startup. You can also <code>removeid</code> by the ban's slot number shown in <code>listid</code>.</p><h2>3. Remove an engine IP ban</h2><p>The IP equivalents, same two-step pattern:</p><pre>removeip 203.0.113.45 | |
| 12 | +writeip</pre><p><code>writeip</code> saves the IP list (commonly <code>listip.cfg</code> or <code>banned_ip.cfg</code>). IP bans are blunt — they can catch a whole household or an ISP CGNAT pool — so if you are unbanning because you hit an innocent bystander, prefer SteamID bans in future. Note the engine can also short-circuit IP bans with <code>sv_filterban</code>; that cvar decides whether the list blocks or allows, so an unexpected ban behaviour can trace back to it.</p><h2>4. The AMX Mod X way</h2><p>From in-game as an admin, AMX Mod X exposes an unban command:</p><pre>amx_unban 203.0.113.45</pre><p>Be aware of a real limitation: <code>amx_unban</code> in the stock admin plugin operates on <strong>IP bans</strong> and runs <code>removeip</code>/<code>writeip</code> for you. It does not reliably clear a SteamID ban — for that you still use the console <code>removeid</code> + <code>writeid</code> above, or a ban-manager plugin that wraps SteamID unbanning in a menu. A maintained suite such as the <a href="/plugins/csb-ban-manager">CSB Ban Manager</a> or the <a href="/plugins/csb-admin-menu">CSB Admin Menu</a> gives you a searchable ban list and a one-click unban so you do not fat-finger a raw command.</p><h2>5. SQL / plugin bans are separate</h2><p>If you run a database-backed ban system (the common AMXBans-style setup), the ban lives in a MySQL table, not in the engine files, and the engine <code>removeid</code> will not touch it. Unban through that system's own tool — its web panel, its in-game menu, or a direct <code>DELETE</code> on the bans table keyed by SteamID. Clearing the engine list and leaving the SQL row is the number-one reason a "removed" ban re-applies the moment the plugin re-syncs its bans back into the engine on the next map.</p><h2>Common errors</h2><ul><li><strong>Ban returns after a restart</strong> — you ran <code>removeid</code>/<code>removeip</code> without <code>writeid</code>/<code>writeip</code>. The file still holds the ban and is re-read at boot.</li><li><strong><code>amx_unban</code> "worked" but they are still banned</strong> — it cleared an IP ban but the block is a SteamID ban. Use console <code>removeid</code> + <code>writeid</code>.</li><li><strong>Unbanned in-game, re-banned next map</strong> — a SQL/plugin ban re-synced into the engine. Remove it from the database, not just the engine list.</li><li><strong><code>removeid</code> says no such ban</strong> — wrong ID format or the ban is only an IP ban. Check <code>listid</code> and <code>listip</code> for the exact entry.</li><li><strong>Whole group of players unbanned by accident</strong> — you removed an IP range ban. IP bans are coarse; verify with <code>listip</code> before and after.</li></ul><h2>Verification</h2><p>After unbanning, list the relevant table and confirm the entry is gone:</p><pre>listid | |
| 13 | +listip</pre><p>Then restart the server and run them again — if the entry is still absent, your <code>writeid</code>/<code>writeip</code> (or database delete) stuck and the unban is permanent. Have the player reconnect to confirm. If they still cannot join, the ban lives in a system you have not cleared yet; work through all three sources above. To ban correctly in the first place, see <a href="/tutorials/find-player-steamid">finding a SteamID and banning with persistence</a>.</p> | |
| 0 | 14 |









