Add 3 tutorials (3 files)
Browse Source
3 changed files
with 219 additions and 0 deletions
A
fix-hlds-no-such-file-32bit/en.md
+52 -0
A
fix-segfault-map-change/en.md
+62 -0
A
setup-server-cfg-cs16/en.md
+105 -0
fix-hlds-no-such-file-32bit/en.md
A
| @@ -0,0 +1,52 @@ | ||
| 1 | +--- | |
| 2 | +title: "Fix: './hlds_linux: No such file or directory' (Missing 32-bit Loader)" | |
| 3 | +excerpt: "The confusing 'No such file or directory' error on a file that plainly exists means the 32-bit ELF loader is missing. Enable i386 multiarch and install the runtime HLDS needs." | |
| 4 | +category: "errors" | |
| 5 | +tags: "linux, 32-bit" | |
| 6 | +image: "" | |
| 7 | +read_time: "7 min read" | |
| 8 | +--- | |
| 9 | +<p><code>./hlds_linux: No such file or directory</code> — on a file that is right there, executable, owned by the right user — is one of the most misleading errors in the whole CS 1.6 stack. The file exists. What is missing is the <strong>32-bit ELF interpreter</strong> the kernel needs to load it: <code>/lib/ld-linux.so.2</code>. HLDS is a 32-bit binary from 2003, and a modern 64-bit Debian or Ubuntu install ships none of the 32-bit runtime by default. The kernel cannot find the loader named inside the ELF header, and reports that as "No such file or directory" — about the loader, not about <code>hlds_linux</code>.</p> | |
| 10 | + | |
| 11 | +<h2>1. Prove it is the loader, not the file</h2> | |
| 12 | +<p>Confirm the diagnosis before installing anything. First, the file really is there and is 32-bit:</p> | |
| 13 | +<pre>file hlds_linux</pre> | |
| 14 | +<p>It should say <code>ELF 32-bit LSB executable, Intel 80386</code>. Now ask what interpreter it needs and whether that interpreter resolves:</p> | |
| 15 | +<pre>ldd hlds_linux</pre> | |
| 16 | +<p>If <code>ldd</code> reports <code>not a dynamic executable</code>, or lists the loader as <code>not found</code>, the 32-bit runtime is missing. That is the whole problem.</p> | |
| 17 | + | |
| 18 | +<h2>2. Enable i386 multiarch</h2> | |
| 19 | +<p>On a 64-bit Debian/Ubuntu you must explicitly tell dpkg it is allowed to install 32-bit packages:</p> | |
| 20 | +<pre>sudo dpkg --add-architecture i386 | |
| 21 | +sudo apt update</pre> | |
| 22 | +<p>Without this step, <code>apt</code> cannot even see the <code>:i386</code> packages you are about to ask for.</p> | |
| 23 | + | |
| 24 | +<h2>3. Install the 32-bit runtime</h2> | |
| 25 | +<pre>sudo apt install -y lib32gcc-s1 lib32stdc++6 libc6:i386 libncurses6:i386 libcurl4:i386</pre> | |
| 26 | +<p><code>libc6:i386</code> is the package that actually provides <code>/lib/ld-linux.so.2</code> and the core C library — it is the one that clears this specific error. <code>lib32gcc-s1</code> and <code>lib32stdc++6</code> satisfy the GCC/C++ runtime the engine and its libraries need, <code>libncurses6:i386</code> is for the text console, and <code>libcurl4:i386</code> covers HTTP-using components. On older releases the GCC package is named <code>lib32gcc1</code> instead of <code>lib32gcc-s1</code>; if apt cannot find one, try the other. The full dependency list, including what modules pull in later, is in <a href="/tutorials/install-32bit-libraries-cs16-linux">the 32-bit library guide</a>.</p> | |
| 27 | + | |
| 28 | +<h3>On RHEL, CentOS, AlmaLinux or Rocky</h3> | |
| 29 | +<p>The Red Hat family does not use dpkg multiarch; you install the 32-bit <code>.i686</code> packages directly:</p> | |
| 30 | +<pre>sudo dnf install -y glibc.i686 libstdc++.i686 ncurses-libs.i686 libcurl.i686</pre> | |
| 31 | +<p><code>glibc.i686</code> is the equivalent of <code>libc6:i386</code> — it is the one that provides the 32-bit loader and clears this error. On very old CentOS 7 boxes the command is <code>yum</code> instead of <code>dnf</code>, and the package names are identical.</p> | |
| 32 | + | |
| 33 | +<h2>4. Start the server</h2> | |
| 34 | +<pre>cd /home/steam/hlds | |
| 35 | +./hlds_run -game cstrike -strictportbind -ip 0.0.0.0 -port 27015 \ | |
| 36 | + +map de_dust2 +maxplayers 20 +sv_lan 0</pre> | |
| 37 | +<p>It should now boot to a map instead of dying instantly. Note the distinction between the two binaries: <code>hlds_run</code> is a 64-bit-friendly shell wrapper that launches and, after a crash, relaunches the real 32-bit engine <code>hlds_linux</code>. The "No such file or directory" error is raised by <code>hlds_linux</code> — which is why running <code>hlds_run</code> can appear to start and then immediately die, with the real error buried in <code>debug.log</code> rather than on your terminal. When in doubt, run <code>./hlds_linux</code> directly to see the loader error unfiltered.</p> | |
| 38 | + | |
| 39 | +<h2>Common errors</h2> | |
| 40 | +<ul> | |
| 41 | +<li><strong><code>error while loading shared libraries: libstdc++.so.6: cannot open shared object file</code></strong> — you got past the loader but a 32-bit library is still missing. Install <code>lib32stdc++6</code>. This is the natural next error after fixing the loader, and you fix them one library at a time until <code>ldd</code> is clean.</li> | |
| 42 | +<li><strong><code>ldd</code> still says the loader is not found after installing <code>libc6:i386</code></strong> — you skipped <code>dpkg --add-architecture i386</code>, so apt installed nothing useful. Add the architecture, <code>apt update</code>, and reinstall.</li> | |
| 43 | +<li><strong>The file genuinely is missing</strong> — if <code>file hlds_linux</code> reports the file does not exist, this is not the loader problem; App 90 did not download. Re-run <code>app_update 90 validate</code> per <a href="/tutorials/install-cs16-dedicated-server-linux-steamcmd">the install guide</a>.</li> | |
| 44 | +<li><strong><code>wrong ELF class: ELFCLASS64</code> on a self-built binary</strong> — different problem: you compiled a 64-bit object. See <a href="/tutorials/fix-wrong-elf-class-elfclass64">that error</a>.</li> | |
| 45 | +</ul> | |
| 46 | + | |
| 47 | +<h2>Verification</h2> | |
| 48 | +<p>Re-run the check that diagnosed it:</p> | |
| 49 | +<pre>ldd hlds_linux</pre> | |
| 50 | +<p>Every line must now resolve to a real path — no <code>not found</code>. Then start the server and confirm it reaches a map and binds the port:</p> | |
| 51 | +<pre>ss -lunp | grep 27015</pre> | |
| 52 | +<p>should show <code>hlds_linux</code> listening. A resolving <code>ldd</code>, a server that boots to <code>de_dust2</code>, and a bound UDP port together confirm the 32-bit runtime is complete. From here, layer on <a href="/tutorials/install-rehlds-on-linux">ReHLDS</a> and the rest of the stack.</p> |
fix-segfault-map-change/en.md
A
| @@ -0,0 +1,62 @@ | ||
| 1 | +--- | |
| 2 | +title: "Fix: Server Crashes with a Segfault on Map Change" | |
| 3 | +excerpt: "A CS 1.6 server boots fine but segfaults on changelevel. The real causes — a stale delta.lst, precache overflow, bad plugins, missing map assets — and how to pin the exact one." | |
| 4 | +category: "errors" | |
| 5 | +tags: "segfault, mapchange" | |
| 6 | +image: "" | |
| 7 | +read_time: "8 min read" | |
| 8 | +--- | |
| 9 | +<p>A crash on map change is a distinct and more interesting bug than a startup crash: the server boots, plays a full round, and then dies exactly at <code>changelevel</code> or when the round ends and rotation kicks in. Because it only triggers during the level transition, the causes are specific — the state carried across the boundary, the resources the next map precaches, and plugins that hook the transition. Here is how to find yours.</p> | |
| 10 | + | |
| 11 | +<h2>1. Confirm it is the transition, not the next map</h2> | |
| 12 | +<p>First separate "crashes when leaving any map" from "crashes when loading one specific map". Force changes manually:</p> | |
| 13 | +<pre>changelevel de_dust2 | |
| 14 | +changelevel de_inferno | |
| 15 | +changelevel cs_assault</pre> | |
| 16 | +<ul> | |
| 17 | +<li><strong>Crashes only when loading one map</strong> → that map's assets or precache are the problem (section 4).</li> | |
| 18 | +<li><strong>Crashes leaving any map</strong> → it is state or a plugin at the transition (sections 2–3).</li> | |
| 19 | +</ul> | |
| 20 | + | |
| 21 | +<h2>2. Stale or mismatched delta.lst</h2> | |
| 22 | +<p>If you run <a href="/tutorials/install-regamedll-cs16">ReGameDLL</a>, the number-one cause of transition and connect crashes is a <code>delta.lst</code> that does not match the game DLL. It defines how entity state is serialised across the network and across level changes; a stale one corrupts state at exactly these boundaries. Copy the <code>delta.lst</code> that shipped with your ReGameDLL build over the top:</p> | |
| 23 | +<pre>cp /path/to/regamedll-release/cstrike/delta.lst /home/steam/hlds/cstrike/delta.lst</pre> | |
| 24 | +<p>Restart and re-test the map change. This single file fixes a large share of "random crash on map change" reports.</p> | |
| 25 | + | |
| 26 | +<h2>3. A plugin hooking the transition</h2> | |
| 27 | +<p>Plugins that run on round end, intermission, or map change (map-vote, stats-save, end-of-map handlers) are prime suspects because they only execute at the boundary. Watch the log through a crash:</p> | |
| 28 | +<pre>tail -f /home/steam/hlds/cstrike/addons/amxmodx/logs/*.log</pre> | |
| 29 | +<p>The last plugin to log before the crash is your first suspect. Disable third-party plugins in AMXX's <code>plugins.ini</code>, confirm map changes are clean, then re-enable in batches until it crashes again — see <a href="/tutorials/install-amxx-plugin-files">managing plugins</a>. A stats plugin doing a database write at map end can also crash on a dropped SQL connection; check the module's log too.</p> | |
| 30 | + | |
| 31 | +<h2>4. Precache overflow on the incoming map</h2> | |
| 32 | +<p>CS 1.6 has hard limits on precached models, sounds and generic resources. A map plus your plugins' custom models and sounds can exceed them, and the overflow surfaces as a crash while loading that map. The tell-tale log line is a precache error or:</p> | |
| 33 | +<pre>Host_Error: PF_precache_*: overflow</pre> | |
| 34 | +<p>Reduce what is precached: trim plugin-added models/sounds, or move rarely-used content behind on-demand precache. Maps that reference many external assets are the usual trigger — see <a href="/tutorials/install-custom-maps-cs16-server">adding custom content</a> for what a map pulls in.</p> | |
| 35 | + | |
| 36 | +<h2>5. Missing assets on the target map</h2> | |
| 37 | +<p>A map whose models or sounds are absent from the server can fault as it precaches them. If section 1 pointed at one specific map, verify its assets are all present:</p> | |
| 38 | +<pre>Host_Error: PF_precache_sound_I: '...' failed to load</pre> | |
| 39 | +<p>Copy the map's complete asset set (<code>sound/</code>, <code>models/</code>, WADs). A map that loads standalone but crashes only in rotation is usually this plus precache pressure from plugins that a fresh boot did not have.</p> | |
| 40 | + | |
| 41 | +<h2>6. Engine/game DLL mismatch</h2> | |
| 42 | +<p>If nothing above holds, a mismatched <a href="/tutorials/install-rehlds-on-linux">ReHLDS</a>/ReGameDLL pair can be stable mid-round and crash on transition. Update both to the same-era releases and confirm:</p> | |
| 43 | +<pre>rehlds_version | |
| 44 | +regamedll_version</pre> | |
| 45 | + | |
| 46 | +<h2>Common errors</h2> | |
| 47 | +<ul> | |
| 48 | +<li><strong>Segfault on every <code>changelevel</code>, no useful log</strong> — stale <code>delta.lst</code>. Copy the matching one first.</li> | |
| 49 | +<li><strong><code>Host_Error: PF_precache_* overflow</code></strong> — too many precached resources; trim plugin/map content.</li> | |
| 50 | +<li><strong>Crash right after a map-vote or stats plugin logs</strong> — that plugin. Bisect the plugin list.</li> | |
| 51 | +<li><strong>Crashes loading one map only</strong> — that map's assets are missing or it precaches too much.</li> | |
| 52 | +</ul> | |
| 53 | + | |
| 54 | +<h2>Verification</h2> | |
| 55 | +<p>Prove the fix under the exact condition that failed. Run several forced changes across different maps back to back:</p> | |
| 56 | +<pre>changelevel de_dust2 | |
| 57 | +changelevel de_nuke | |
| 58 | +changelevel de_dust2</pre> | |
| 59 | +<p>Each must complete without a <code>Host_Error</code> or segfault. Then let the server rotate naturally through a full <code>mapcycle.txt</code> with players (or bots) connected — the natural end-of-round transition is where a plugin-driven crash hides that a manual <code>changelevel</code> can miss. If the server cycles through the whole rotation with players on it and no crash, the map-change fault is fixed. A startup-time crash instead points back to <a href="/tutorials/fix-hlds-segfault-startup">the startup segfault guide</a>.</p> | |
| 60 | + | |
| 61 | +<h2>Why map change specifically</h2> | |
| 62 | +<p>It helps to understand why this boundary is special, because it tells you where to look first. A level change is the one moment the engine tears down the entire entity world and rebuilds it: it serialises surviving state, unloads the map, precaches every resource the next map and every plugin ask for, and reconstructs entities from the delta definitions. Three of those steps are exactly where the common causes live — serialisation reads <code>delta.lst</code>, precache hits the resource limits, and plugin end-of-map handlers fire in between. That is why a server can be rock-solid for an entire round and die at the seam. It also explains the ordering of this guide: check <code>delta.lst</code> first because it is both the most common cause and the cheapest to fix, then precache, then plugins, because that is the order the engine actually exercises them during the transition. Fix the delta list, keep precache under its limits, and keep transition-time plugins honest, and map changes stop being the thing you hold your breath through.</p> |
setup-server-cfg-cs16/en.md
A
| @@ -0,0 +1,105 @@ | ||
| 1 | +--- | |
| 2 | +title: "server.cfg for CS 1.6: A Complete, Commented Example" | |
| 3 | +excerpt: "A full, line-by-line server.cfg for CS 1.6 covering identity, rates, gameplay, logging and downloads — with an explanation of when it actually executes." | |
| 4 | +category: "installation" | |
| 5 | +tags: "server.cfg, config" | |
| 6 | +image: "" | |
| 7 | +read_time: "8 min read" | |
| 8 | +--- | |
| 9 | +<p><code>server.cfg</code> is where a CS 1.6 server's personality lives: its name, its rules, its network rates, its logging. The engine executes it automatically at startup and again on every map change, which is both convenient and a trap — anything you want applied once (like <code>maxplayers</code>) does not belong here. This is a complete, commented file you can adapt, with an explanation of what each block does and why.</p> | |
| 10 | + | |
| 11 | +<h2>When server.cfg runs</h2> | |
| 12 | +<p>The engine auto-executes <code>cstrike/server.cfg</code> after it loads a map. So it runs at boot and at every map change. That means:</p> | |
| 13 | +<ul> | |
| 14 | +<li>Gameplay and rate cvars belong here — they should re-apply each map.</li> | |
| 15 | +<li><code>maxplayers</code> does <strong>not</strong> — it is a launch-time value; set it with <a href="/tutorials/hlds-command-line-parameters"><code>+maxplayers</code> on the command line</a>.</li> | |
| 16 | +<li>If a setting "resets every map change", it is because your <code>server.cfg</code> re-applies an old value over your live edit. Change the file, not just the live cvar.</li> | |
| 17 | +</ul> | |
| 18 | + | |
| 19 | +<h2>The file</h2> | |
| 20 | +<p>Create <code>/home/steam/hlds/cstrike/server.cfg</code>:</p> | |
| 21 | +<pre>// ---- Identity ---- | |
| 22 | +hostname "My CS 1.6 Server | example.com" | |
| 23 | +sv_contact "[email protected]" | |
| 24 | + | |
| 25 | +// ---- Passwords / access ---- | |
| 26 | +rcon_password "use-a-long-random-string-here" | |
| 27 | +sv_password "" // set to make the server private | |
| 28 | +sv_rcon_banpenalty 15 // minutes banned after too many bad rcon tries | |
| 29 | +sv_rcon_maxfailures 5 // wrong rcon attempts before a temp ban | |
| 30 | + | |
| 31 | +// ---- Master list / network mode ---- | |
| 32 | +sv_lan 0 // 0 = appear on the internet list. MANDATORY for public. | |
| 33 | +sv_region 255 // 255 = world; or a numeric region code | |
| 34 | + | |
| 35 | +// ---- Network rates ---- | |
| 36 | +sv_maxrate 25000 | |
| 37 | +sv_minrate 15000 | |
| 38 | +sv_maxupdaterate 101 | |
| 39 | +sv_minupdaterate 30 | |
| 40 | +sv_maxcmdrate 101 | |
| 41 | +sv_mincmdrate 30 | |
| 42 | +sv_timeout 60 | |
| 43 | + | |
| 44 | +// ---- Gameplay ---- | |
| 45 | +mp_timelimit 30 // minutes per map | |
| 46 | +mp_maxrounds 0 // 0 = use timelimit instead of round count | |
| 47 | +mp_freezetime 3 | |
| 48 | +mp_roundtime 3 | |
| 49 | +mp_startmoney 800 | |
| 50 | +mp_buytime 0.25 // minutes (0.25 = 15 seconds) | |
| 51 | +mp_c4timer 35 | |
| 52 | +mp_friendlyfire 0 | |
| 53 | +mp_autoteambalance 1 | |
| 54 | +mp_limitteams 2 | |
| 55 | +mp_autokick 0 // 0 = do not auto-kick idlers/TKers | |
| 56 | +mp_flashlight 1 | |
| 57 | +mp_footsteps 1 | |
| 58 | +mp_tkpunish 0 | |
| 59 | + | |
| 60 | +// ---- Voice ---- | |
| 61 | +sv_voiceenable 1 | |
| 62 | +sv_alltalk 0 // 0 = teams cannot hear each other | |
| 63 | + | |
| 64 | +// ---- Downloads (custom maps/sounds) ---- | |
| 65 | +sv_allowdownload 1 | |
| 66 | +sv_allowupload 1 | |
| 67 | +sv_downloadurl "" // fast HTTP redirect; leave empty to use slow UDP download | |
| 68 | + | |
| 69 | +// ---- Logging ---- | |
| 70 | +log on | |
| 71 | +mp_logmessages 1 | |
| 72 | +mp_logdetail 3 // log damage + kills (needed by stats plugins) | |
| 73 | +sv_log_onefile 0 | |
| 74 | +sv_logbans 1 | |
| 75 | +sv_logecho 1 | |
| 76 | + | |
| 77 | +// ---- Execute the map cycle ---- | |
| 78 | +mapcyclefile "mapcycle.txt"</pre> | |
| 79 | + | |
| 80 | +<h2>The blocks that matter most</h2> | |
| 81 | +<h3>sv_lan 0</h3> | |
| 82 | +<p>The single most important line. With <code>sv_lan 1</code> the server never heartbeats the master list and rejects Steam clients with a LAN error. Public servers must have <code>sv_lan 0</code>.</p> | |
| 83 | +<h3>Rates</h3> | |
| 84 | +<p>The rate block controls how much bandwidth and how many updates the server allows per client. <code>sv_maxupdaterate 101</code> and <code>sv_maxcmdrate 101</code> are the modern defaults for a good connection; the min values stop a client from starving itself into rubber-banding. Do not set the max absurdly high — it does not add smoothness beyond the engine's real tick rate, it just wastes bandwidth.</p> | |
| 85 | +<h3>Logging detail</h3> | |
| 86 | +<p><code>mp_logdetail 3</code> is required if you run a stats plugin — stats parse damage and kill log lines, and at lower detail those lines are not written. If your stats plugin "records nothing", check this first.</p> | |
| 87 | +<h3>sv_downloadurl</h3> | |
| 88 | +<p>Leave it empty and clients pull custom maps over the slow in-game UDP channel; point it at an HTTP server hosting your <code>cstrike/</code> files and downloads are far faster. It is worth setting the moment you run custom maps.</p> | |
| 89 | + | |
| 90 | +<h2>Common errors</h2> | |
| 91 | +<ul> | |
| 92 | +<li><strong>Settings do not apply</strong> — the file is named <code>server.cfg.txt</code> (Windows hides the extension), or it is not in <code>cstrike/</code>. It must be <code>cstrike/server.cfg</code> exactly.</li> | |
| 93 | +<li><strong><code>maxplayers</code> in cfg does nothing</strong> — it is a launch-time parameter. Use <code>+maxplayers</code> on the command line.</li> | |
| 94 | +<li><strong>Server shows as LAN / not listed</strong> — <code>sv_lan</code> is 1. Set it to 0.</li> | |
| 95 | +<li><strong>Stats plugin records nothing</strong> — <code>mp_logdetail</code> is too low or <code>log</code> is off. Set <code>log on</code> and <code>mp_logdetail 3</code>.</li> | |
| 96 | +<li><strong>A value "keeps resetting" each map</strong> — <code>server.cfg</code> re-executes on map change and overwrites your live edit. Change it in the file.</li> | |
| 97 | +<li><strong>rcon_password in a shared file leaked</strong> — anyone who reads the file has RCON. Keep the file readable only by the <code>steam</code> user.</li> | |
| 98 | +</ul> | |
| 99 | + | |
| 100 | +<h2>Verification</h2> | |
| 101 | +<p>Start the server and, in the console, echo a few values back to confirm the file executed:</p> | |
| 102 | +<pre>sv_lan | |
| 103 | +mp_timelimit | |
| 104 | +sv_maxupdaterate</pre> | |
| 105 | +<p>Each should return the value you set. Force a map change and re-check — the values should persist because the file re-executes. Once the config is stable, wire the whole thing into a <a href="/tutorials/hlds-systemd-service">systemd service</a> and open the <a href="/tutorials/cs16-server-firewall-ports">right firewall ports</a>, and the server is ready for players.</p> | |
| 0 | 106 |









