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
Promoveaza serverul

Add 7 tutorials (7 files)

Browse Source
Daemon666 committed parent 73da6c2913 commit 2d774b7c2edfed1a6c07dddab89c3315cdfd6b6c
7 changed files with 81 additions and 0 deletions
+11 -0 cs16-toplists-worth-joining/en.md A
@@ -0,0 +1,11 @@
1 +---
2 +title: "CS 1.6 Server Toplists Worth Joining in 2026"
3 +excerpt: "Which server-listing and monitoring sites still send real players in 2026, how each one discovers your server, and the order to register on them once your server is in the master list."
4 +category: "hosting"
5 +tags: "toplists, listing"
6 +image: ""
7 +read_time: "8 min read"
8 +---
9 +<p>A CS 1.6 server that only appears in the in-game browser is leaving most of its potential traffic on the table. The players who fill servers in 2026 find them through external listing and monitoring sites &mdash; pages that query your server every few minutes, publish its live map and player count, and rank it against everyone else. This is which lists are still worth the effort, how each one finds you, and the order to register.</p><h2>1. Get into the master list first &mdash; everything else depends on it</h2><p>Every listing site discovers servers the same way the game does: from the Valve master server, then by sending an A2S_INFO query to your IP and port. If you are not in the master list, most of these sites cannot see you to add you. Confirm the basics before you register anywhere:</p><pre>sv_lan 0
10 +hostname "Your Server Name | fast HP+Ammo"
11 +sv_region 255</pre><p><code>sv_lan 0</code> is mandatory to be listed at all; <code>sv_region</code> sets your advertised region (255 = all). If you are missing from the browser entirely, fix that first with <a href="/tutorials/get-server-in-master-list">get your server in the master list</a> and <a href="/tutorials/fix-server-not-in-master-list">the missing-from-master-list fix</a>. A listing site will simply show your server as offline until it can query you.</p><h2>2. GameTracker &mdash; the one everyone checks</h2><p>GameTracker is the single most valuable listing for a CS 1.6 server. It tracks player history, draws activity graphs, hosts a per-server page you can brand, and provides the signature banner you paste into forums and your MOTD. Its ranking rewards sustained activity and user votes, so claiming and maintaining the page is worth a dedicated guide: see <a href="/tutorials/gametracker-claim-server">claiming and optimizing your GameTracker page</a> and <a href="/tutorials/gametracker-ranking-explained">how the ranking works</a>. Register here first after the master list.</p><h2>3. Tsarvar and the CIS monitors</h2><p>A large share of CS 1.6's remaining population is in the CIS region, and it finds servers through monitoring sites popular there &mdash; Tsarvar chief among them. These sites let you add a server by IP and port, then query it and publish live status, favourites, and a rating. If your audience is Russian/Ukrainian/CIS-speaking, being listed here matters more than any Western list. Walk through it in <a href="/tutorials/list-server-on-tsarvar">listing your server on Tsarvar</a>.</p><h2>4. Game-monitoring and vote sites</h2><p>Beyond the big two there is a long tail of game-monitor and "top servers" vote sites. Their common shape: you submit <code>IP:port</code>, they query it periodically, and players can vote for your server to raise its position on the list. The genuine ones drive a trickle of traffic and cost nothing but a form; treat them as supplementary. Be wary of any that demand you install a plugin, hand over RCON, or pay for placement &mdash; a listing that needs your RCON password is a security risk, not a promotion channel.</p><h2>5. Your own in-game promotion feeds them all</h2><p>Listing sites rank you on how busy you look, so the fastest way to climb every list at once is to actually have players on at consistent times. That is a growth problem, not a listing one &mdash; see <a href="/tutorials/get-players-on-new-server">getting players onto a new server</a> and <a href="/tutorials/first-30-regulars-playbook">the first-30-regulars playbook</a>. Advertise your GameTracker banner and Discord in the MOTD and with an <a href="/plugins/csb-adverts">adverts plugin</a> so the players you do get help you climb.</p><h2>Common errors</h2><ul><li><strong>Listing site shows your server offline</strong> &mdash; it cannot query you. Confirm <code>sv_lan 0</code>, that UDP 27015 (or your port) is open, and that you appear in the in-game browser. See <a href="/tutorials/fix-a2s-info-no-response">A2S_INFO no response</a>.</li><li><strong>Added with the wrong port</strong> &mdash; you listed the game port but the site needs <code>IP:port</code> exactly. A server on a non-default port must be added with that port explicitly.</li><li><strong>Player count reads zero despite players</strong> &mdash; a bot-padding or fake-player setup can confuse queries and get you flagged; see <a href="/tutorials/fake-players-bot-padding">fake players and bot padding</a>.</li><li><strong>Site wants your RCON password</strong> &mdash; do not give it. No legitimate listing needs RCON; it only needs to query your public IP.</li><li><strong>Duplicate listings</strong> &mdash; your server changed IP and the old entry lingers. Claim and update the real one rather than adding a second.</li></ul><h2>Verification</h2><p>After registering, wait for the site's next query cycle (usually a few minutes) and confirm your page shows the correct map and live player count. From a second machine, query your server directly and compare &mdash; the numbers should match what the listing reports. If the listing lags reality by more than its stated refresh, the site is querying a stale address; update the IP on the listing. Once GameTracker and your regional monitor both show you live and accurate, you have covered the two channels that actually move players in 2026.</p>
+15 -0 fix-custom-map-download-fails/en.md A
@@ -0,0 +1,15 @@
1 +---
2 +title: "Fix: Players Can't Download Your Custom Maps"
3 +excerpt: "Why players join a custom map with black checkerboard textures or no map at all, the three cvars that gate downloading, resource precache limits, and how to confirm the file is actually served."
4 +category: "errors"
5 +tags: "maps, fastdl"
6 +image: ""
7 +read_time: "7 min read"
8 +---
9 +<p>You add a custom map to the rotation, the server changes to it, and players either drop with a missing-file message or spawn into a world of black-and-purple checkerboard textures with the map name printed in the console but nothing downloaded. Custom-content downloading in CS 1.6 is gated by a small set of server cvars and by whether the file physically exists where the engine expects it. Work through these in order.</p><h2>1. Turn on downloading at all</h2><p>The master switch is <code>sv_allowdownload</code>. If it is <code>0</code>, a client that lacks the <code>.bsp</code> simply joins without it &mdash; hence the checkerboard. In <a href="/tutorials/setup-server-cfg-cs16">server.cfg</a>:</p><pre>sv_allowdownload 1
10 +sv_allowupload 1</pre><p>This alone lets the engine hand the map over the slow in-game UDP channel. It works, but a 15&ndash;25 MB map trickling at a few KB/s empties your server on every rotation, which is why the real fix is FastDL (step 3). See <a href="/tutorials/sv-allowdownload-settings">the download cvars explained</a> for exactly how each one interacts.</p><h2>2. Confirm the map file is really on the server</h2><p>The engine only offers files it has. The map and every resource it references must live under <code>cstrike/</code>:</p><pre>cstrike/maps/de_rats.bsp
11 +cstrike/maps/de_rats.txt # optional map description/overview
12 +cstrike/gfx/env/*.tga # skybox, if the map uses a custom one
13 +cstrike/sound/... # custom sounds referenced by the map</pre><p>A map that loads fine for you but not for others usually has custom textures compiled <em>into</em> the BSP (fine, they travel with it) versus external resources (skybox, sprites, sounds) that live in separate files the client must also download. Missing skybox shows as a solid colour where the sky should be; missing sounds are silent. Every external file the map needs must be present server-side or it cannot be sent.</p><p>A quick way to enumerate what a map actually pulls is its resource list: the engine sends the client the same file list it precached, so if a texture or sound is baked into a plugin rather than the map, it must still be reachable. When you install a downloaded map, unpack the whole archive &mdash; not just the <code>.bsp</code> &mdash; because the sprites, overview and sound folders in that archive are exactly the external resources clients need.</p><h2>3. Point clients at a FastDL mirror</h2><p>The proper fix is an HTTP mirror so downloads happen at real web speed:</p><pre>sv_downloadurl "http://dl.example.com/cs"</pre><p>The engine appends the full game-relative path <em>including the <code>cstrike/</code> folder</em>, so the client fetches <code>http://dl.example.com/cs/cstrike/maps/de_rats.bsp</code>. Your web root must contain a <code>cstrike/</code> directory mirroring the server's layout. The complete Nginx/Apache walkthrough with bzip2 compression is in the <a href="/tutorials/fastdl-setup-guide">FastDL setup guide</a>; if files 404 over HTTP see <a href="/tutorials/fix-fastdl-404-bz2">the FastDL 404 fix</a>.</p><h2>4. Watch the consumers cvar and resource count</h2><p>CS 1.6 has a hard cap of <strong>512 precached resources</strong> per map (models, sounds, sprites, generic files combined). A map plus a stack of custom-content plugins can hit it, and when it does the server prints:</p><pre>Host_Error: PF_precache_generic: Precache_Generic overflow</pre><p>or a <code>too many files</code> style message, and content silently fails to send. If a specific map breaks downloading while others work, count what your plugins precache and trim decals/sounds you do not need.</p><h2>5. The client can veto it</h2><p>Downloading also depends on the player's own <code>cl_allowdownload</code>, which lives on their machine, not yours. If they set it to <code>0</code>, they join every server with missing content no matter what you configure. It defaults to <code>1</code>, so this only bites players who changed it &mdash; but when one player has missing textures and everyone else is fine, that is the cause and only they can fix it. Tell them to open the console and set it back:</p><pre>cl_allowdownload 1
14 +cl_allowupload 1</pre><p>Some third-party client packs ship with downloading disabled to "speed up" joins; players on those builds will always miss content until they flip it on. There is nothing you can do server-side to override a client that refuses downloads.</p><h2>Common errors</h2><ul><li><strong>Black/purple checkerboard textures</strong> &mdash; <code>sv_allowdownload 0</code>, or the resource is not on the server. Enable the cvar and confirm the file exists under <code>cstrike/</code>.</li><li><strong>Download crawls, server empties on map change</strong> &mdash; no <code>sv_downloadurl</code>, so it fell back to the UDP transfer. Set up FastDL.</li><li><strong>Solid-colour sky, otherwise fine</strong> &mdash; the custom skybox TGAs in <code>cstrike/gfx/env/</code> are missing from the server or the mirror.</li><li><strong><code>Precache_Generic overflow</code></strong> &mdash; you exceeded the 512-resource cap. Reduce custom sounds/models/decals.</li><li><strong>One player misses everything, others are fine</strong> &mdash; that client set <code>cl_allowdownload 0</code>.</li></ul><h2>Verification</h2><p>Delete the map from a test client, connect, and watch the console: you should see it fetch <code>de_rats.bsp</code> (fast over HTTP if the mirror is right). Read the cvar back with no argument to confirm it is set:</p><pre>sv_allowdownload
15 +sv_downloadurl</pre><p>Then join and look at the world &mdash; real textures, a proper sky, audible custom sounds. If the map plays for everyone but downloads slowly, your only missing piece is the FastDL mirror; if it 404s over HTTP, the <code>cstrike/</code> path in the web root is wrong.</p>
+9 -0 fix-master-server-heartbeat-failed/en.md A
@@ -0,0 +1,9 @@
1 +---
2 +title: "Fix: Master Server Heartbeat Failing / No Heartbeats Sent"
3 +excerpt: "Why your server never appears in the internet server list, how to force a heartbeat, the sv_lan and sv_region cvars that gate it, and the firewall/NAT rules the announce needs."
4 +category: "errors"
5 +tags: "heartbeat, master-server"
6 +image: ""
7 +read_time: "8 min read"
8 +---
9 +<p>Your server runs, players who already have the IP can connect and play, but it never shows up in the in-game <strong>Internet</strong> tab or on community trackers. That is a master-server heartbeat problem: the server is not successfully announcing itself to Valve's master server, so nothing that queries the master list ever learns it exists. A heartbeat is a small UDP packet the game server sends the master roughly every few minutes; if it never arrives, you are invisible to everyone but people with your direct address.</p><h2>1. Rule out sv_lan first</h2><p>A LAN server does not heartbeat at all. This is the single most common cause and it is a one-line fix:</p><pre>sv_lan 0</pre><p>At <code>1</code> the engine skips the master entirely &mdash; no heartbeat is ever sent, by design. Put <code>sv_lan 0</code> in <a href="/tutorials/setup-server-cfg-cs16">server.cfg</a> and read it back in the console with <code>sv_lan</code> (no argument) to confirm it stuck. A config executed after yours can flip it back, so check the live value, not just the file.</p><h2>2. Set a region so the master accepts you</h2><p>The master server buckets servers by region. Set it explicitly:</p><pre>sv_region 255</pre><p><code>255</code> means "world / unspecified" and is the safe default; the numbered regions (Europe, US East, and so on) also work but a wrong region hides you from players filtering by area. If <code>sv_region</code> is unset or garbage, some master builds refuse the listing.</p><h2>3. Open UDP 27015 in BOTH directions</h2><p>The heartbeat is outbound UDP from your server port (default <strong>27015</strong>) to the master, and the master and clients then query you inbound on the same port. On a firewalled or NAT'd box you must allow both:</p><ul><li><strong>Outbound UDP</strong> from 27015 to the internet &mdash; without it the heartbeat never leaves.</li><li><strong>Inbound UDP</strong> to 27015 &mdash; without it the master's reply and client A2S queries never arrive, so even a delivered heartbeat leads nowhere.</li></ul><p>Behind a home router, forward UDP 27015 to the server's LAN IP. On a VPS, check the provider firewall and any local <code>iptables</code>/<code>ufw</code> rules. If the box has several IPs, bind explicitly with <code>-ip</code> on the command line so heartbeats leave from the address players can reach.</p><h2>4. Force a heartbeat and watch the console</h2><p>You do not have to wait for the timer. From the server console:</p><pre>heartbeat</pre><p>This sends an immediate announce. Run it with <code>developer 1</code> set and watch for the challenge handshake &mdash; the master replies with a challenge the server must echo before it is listed. If you see the request go out but nothing comes back, the reply is being dropped inbound (step 3). If nothing goes out at all, you are still in LAN mode or bound to the wrong IP.</p><h2>5. Inspect the master list itself</h2><p>The engine keeps a list of master servers it talks to. Print it:</p><pre>setmaster list</pre><p>This shows the masters currently configured. If the list is empty &mdash; which happened to many servers around engine updates when a hardcoded master address changed &mdash; no heartbeat has anywhere to go. You can re-enable the built-in masters with:</p><pre>setmaster enable</pre><p>Do not paste random third-party master addresses from a forum; an unreachable or hostile master just wastes heartbeats. Stick to the engine's built-in Steam master unless you deliberately run your own.</p><h2>Troubleshooting</h2><ul><li><strong>Server plays fine but never lists</strong> &mdash; almost always <code>sv_lan 1</code>. Set it to <code>0</code> and re-check the live value.</li><li><strong>Heartbeat goes out, server still not listed</strong> &mdash; inbound UDP 27015 is blocked, so the master cannot query you back. Test the port from outside with an A2S query tool.</li><li><strong>Lists briefly, then drops off</strong> &mdash; heartbeats are arriving intermittently; a flaky NAT mapping or an aggressive firewall idle-timeout is dropping the outbound path between beats.</li><li><strong><code>setmaster list</code> is empty</strong> &mdash; run <code>setmaster enable</code> to restore the built-in masters, then <code>heartbeat</code>.</li><li><strong>Wrong or double IP</strong> &mdash; a multi-homed box heartbeats from an address clients cannot reach. Pin it with <code>-ip &lt;public-ip&gt;</code> at launch.</li><li><strong>Broke right after the 25th Anniversary update</strong> &mdash; that update changed engine networking and master handling; rolling the client/server to the <code>steam_legacy</code> branch is the known escape while you sort compatibility.</li></ul><h2>Verification</h2><p>With <code>developer 1</code>, run <code>heartbeat</code> and confirm you see the announce leave and a challenge return. Then, from a different machine or network (not the server's own LAN), open CS, go to the Internet tab, and filter by your server name or the map it is running. If it appears, the round trip works. As a lower-level check, use an external A2S query against <code>&lt;your-ip&gt;:27015</code> &mdash; a valid info reply proves inbound UDP is open, which is the half people most often miss. Once it lists reliably, confirm the essentials with <a href="/tutorials/essential-server-cvars">the essential cvars guide</a> so a later config edit does not silently flip <code>sv_lan</code> back.</p>
+10 -0 fix-pterodactyl-cs16-wont-start/en.md A
@@ -0,0 +1,10 @@
1 +---
2 +title: "Fix: Pterodactyl CS 1.6 Server Won't Start (Wings / Egg Issues)"
3 +excerpt: "Why a CS 1.6 server deployed on Pterodactyl sits at 'Starting' forever, how the egg startup command and detection string work, the missing 32-bit library trap, and how to read the Wings console for the real error."
4 +category: "errors"
5 +tags: "pterodactyl, panel"
6 +image: ""
7 +read_time: "8 min read"
8 +---
9 +<p>You imported a CS 1.6 egg into Pterodactyl, deployed a server, and it either sits on <strong>Starting</strong> forever or flips straight back to <strong>Offline</strong>. Pterodactyl adds two layers on top of a plain HLDS install &mdash; the Wings daemon running the container and the egg defining the startup command and detection strings &mdash; and a failure in either looks identical from the panel. This walks through the real causes in the order they actually occur.</p><h2>1. Read the console, not the status pill</h2><p>The status pill lies; the console tells the truth. Open the server's <strong>Console</strong> tab and start it, watching the raw output. HLDS prints its own errors there before Wings gives up. The lines you are looking for are the loader errors, for example:</p><pre>./hlds_run: line 123: ./hlds_linux: not found
10 +error while loading shared libraries: libstdc++.so.6: cannot open shared object file</pre><p>That <code>not found</code> on a file that plainly exists is the classic 32-bit symptom &mdash; the binary is there but the loader for it is not. Note the exact line and move to the matching step below rather than restarting blindly.</p><h2>2. Fix the missing 32-bit libraries</h2><p>HLDS ships a 32-bit <code>hlds_linux</code> binary. If the Docker image the egg points to is 64-bit-only, the kernel cannot load it and you get the <code>not found</code> above. Check the egg's <strong>Docker Image</strong> under the server's <strong>Startup</strong> tab; it must be an image with i386 libraries. A minimal fix is an image based on Debian with <code>libc6:i386</code>, <code>libstdc++6:i386</code>, and <code>libncurses5:i386</code> installed. If you built your own image, add the i386 architecture and those packages; if you used a community egg, switch the Docker image field to the one its documentation specifies. This is the same 32-bit dependency problem covered for bare-metal installs in <a href="/tutorials/install-hlds-on-linux">the HLDS Linux install guide</a>.</p><h2>3. Check the startup command variables</h2><p>Pterodactyl builds the launch line from the egg's startup command plus per-server variables. A wrong variable produces a server that starts and immediately exits. On the <strong>Startup</strong> tab confirm the command resolves to something like:</p><pre>./hlds_run -game cstrike -console +ip 0.0.0.0 -port {{SERVER_PORT}} +map {{SRCDS_MAP}} +maxplayers {{MAX_PLAYERS}}</pre><p>Two variables break servers most often: an empty or misspelled <code>SRCDS_MAP</code> (set it to a map you actually have, e.g. <code>de_dust2</code>), and a <code>MAX_PLAYERS</code> above 32, which CS 1.6 rejects. Bind to <code>0.0.0.0</code> and use <code>{{SERVER_PORT}}</code> so the port matches the allocation Pterodactyl assigned &mdash; hardcoding <code>27015</code> when the panel gave you a different port means the container never binds where Wings expects.</p><h2>4. Confirm the install script finished</h2><p>The egg's install script runs SteamCMD to download HLDS into <code>/mnt/server</code> before the first boot. If that install failed &mdash; Steam rate-limiting, a full disk, a network block &mdash; you have a server directory with no <code>hlds_run</code> in it. In <strong>Settings &rarr; Reinstall Server</strong>, trigger the install again and watch the install log. It must end without SteamCMD errors and leave <code>hlds_run</code> and the <code>cstrike/</code> folder in the root. A half-populated directory is why a freshly created server refuses to boot with no obvious HLDS error at all.</p><h2>5. Fix the 'started' detection string</h2><p>Wings decides a server is <strong>running</strong> by matching a configured string in the console output. If the egg's <strong>Startup Configuration</strong> looks for text HLDS never prints, the process runs fine but the panel shows <strong>Starting</strong> forever and eventually kills it. The reliable marker HLDS emits once it is up is its address line; set the egg's startup detection to a stable substring such as:</p><pre>"Server IP address"</pre><p>Edit this under the egg (Admin area &rarr; Nests &rarr; your egg &rarr; Configuration &rarr; Startup) as valid JSON in the <code>done</code> field. After saving, the next start transitions to <strong>Running</strong> the moment HLDS prints that line.</p><h2>Troubleshooting</h2><ul><li><strong><code>./hlds_linux: not found</code></strong> &mdash; the Docker image lacks 32-bit libraries. Switch to an i386-capable image (step 2).</li><li><strong>Sits on 'Starting' but the console shows the map loaded</strong> &mdash; the Wings detection string does not match HLDS output. Fix the egg's <code>done</code> string (step 5).</li><li><strong>'Container marked as running but process not responding'</strong> &mdash; the process exited immediately; scroll the console up for the real error, usually a bad variable or missing map.</li><li><strong>Flaps between Offline and Starting</strong> &mdash; the install never completed. Reinstall and read the install log (step 4).</li><li><strong>Starts but nobody can connect</strong> &mdash; the port bound does not match the allocation. Use <code>{{SERVER_PORT}}</code> and check the primary allocation. See <a href="/tutorials/fix-rcon-not-working-remote">remote connectivity</a> for the firewall side.</li><li><strong><code>Only 32 player slots supported</code> or silent exit</strong> &mdash; <code>MAX_PLAYERS</code> exceeds 32. Lower it.</li></ul><h2>Verification</h2><p>Start the server and confirm the console reaches the map load and the address line, and that the status pill turns green. From another machine, query the server with <code>status</code> over <a href="/tutorials/fix-rcon-not-working-remote">RCON</a> or connect directly on the panel's allocated IP and port. If it runs cleanly in the console but Wings still will not mark it online, the problem is always the detection string, not HLDS &mdash; and if HLDS itself errors, the first line of that error names the exact cause. Once it boots reliably, layer your plugins on with <a href="/tutorials/install-amx-mod-x-1-9">AMX Mod X</a>.</p>
+13 -0 fix-server-lags-10-players/en.md A
@@ -0,0 +1,13 @@
1 +---
2 +title: "Fix: Server Lags With Only 10 Players"
3 +excerpt: "Why a CS 1.6 server with a handful of players feels laggy, how to check the real server FPS with stats, and the sys_ticrate, rate and ReHLDS fixes that smooth it out."
4 +category: "errors"
5 +tags: "lag, performance"
6 +image: ""
7 +read_time: "8 min read"
8 +---
9 +<p>A server lagging with 32 players is a bandwidth story; a server lagging with <strong>10</strong> is almost always a server-FPS story. GoldSrc simulates the whole world on a single loop, and if that loop is not running fast and steadily, every player feels rubber-banding, hit registration goes soft, and jumps stutter &mdash; regardless of how much bandwidth you have. This walks through diagnosing it properly instead of blaming the players' pings.</p><h2>1. Measure the actual server FPS</h2><p>Do not guess. From the server console (or RCON), run:</p><pre>stats</pre><p>You get a line like <code>CPU In Out Uptime Users FPS Players</code>. The number that matters is <strong>FPS</strong> &mdash; the frames-per-second of the server loop, not anyone's client. On a healthy box this should sit close to your <code>sys_ticrate</code> target (500 or 1000) and stay <em>steady</em>. If it swings between 100 and 900, or sits far below your ticrate, that instability is your lag. A server pinning 1000 FPS with 10 players feels perfect; one bouncing around 200 feels broken even on a LAN.</p><h2>2. Set sys_ticrate correctly</h2><p>The server loop's target rate is <code>sys_ticrate</code>, set on the command line, not in a config:</p><pre>./hlds_run -game cstrike +sys_ticrate 1000 +ip 0.0.0.0 +port 27015 +map de_dust2</pre><p>This is a ceiling, not a guarantee &mdash; on stock HLDS the loop rarely holds a steady 1000 and often will not exceed a few hundred no matter what you set. That is a known HLDS limitation, covered in <a href="/tutorials/fix-sys-ticrate-not-changing-fps">why sys_ticrate does not change your FPS</a>. If <code>stats</code> shows the FPS stuck far below your ticrate, the engine itself is the bottleneck and you need ReHLDS.</p><h2>3. Switch to ReHLDS for a stable loop</h2><p>The single biggest fix for stutter on a low-population server is replacing Valve's HLDS with <strong>ReHLDS</strong>, the reverse-engineered engine that actually holds a steady, high server FPS. On ReHLDS the loop stays pinned at your ticrate instead of oscillating, which is exactly what smooths movement and hitreg. Follow the <a href="/tutorials/install-rehlds-on-linux">ReHLDS install guide</a>; it is a drop-in replacement for the engine binaries and keeps your existing <code>cstrike/</code> content.</p><h2>4. Give clients enough rate</h2><p>Even with a fast loop, a player whose rate is throttled will feel choppy. Set sane server-side ceilings in <a href="/tutorials/setup-server-cfg-cs16">server.cfg</a>:</p><pre>sv_maxrate 25000
10 +sv_maxupdaterate 101
11 +sv_minupdaterate 20
12 +sv_maxcmdrate 101</pre><p>These let modern clients request <code>cl_updaterate 101</code> and a high rate. If your <code>sv_maxrate</code> is left at an old default like <code>10000</code>, you are strangling every client to dial-up speeds &mdash; a classic cause of "lag" that has nothing to do with CPU. Note some of these cvars only take effect on ReHLDS/ReGameDLL; see <a href="/tutorials/fix-sv-maxrate-ignored">when sv_maxrate is ignored</a>.</p><h2>5. Rule out a busy or throttled CPU</h2><p>The <code>CPU</code> column in <code>stats</code> is the fraction of the loop's time budget being consumed. If it is riding near <code>100</code> with only 10 players, something is eating the loop: a heavy plugin running an expensive task every frame, a runaway <code>set_task</code>, or the box being oversold on a cheap VPS that steals CPU. Check for stolen time on Linux:</p><pre>top
13 +# look at the %st (steal) column</pre><p>High <code>%st</code> means the hypervisor is giving your CPU cycles to other tenants &mdash; no config fixes that, only a better host. Also audit plugins: pause them one at a time with <code>amxx pause &lt;plugin&gt;.amxx</code> and watch whether <code>stats</code> FPS recovers.</p><h2>Troubleshooting</h2><ul><li><strong>FPS in <code>stats</code> is fine but players still lag</strong> &mdash; it is bandwidth or a client-side rate, not the server loop. Raise <code>sv_maxrate</code>/<code>sv_maxupdaterate</code> and have players set <code>rate 25000; cl_updaterate 101</code>.</li><li><strong>FPS oscillates wildly on HLDS</strong> &mdash; expected on Valve's engine. Move to <a href="/tutorials/install-rehlds-on-linux">ReHLDS</a> for a stable loop.</li><li><strong>CPU column near 100 with few players</strong> &mdash; a plugin or a stolen-CPU VPS. Pause plugins to find the culprit; check <code>%st</code> in <code>top</code>.</li><li><strong>Lag spikes exactly on map change or when a player connects</strong> &mdash; disk I/O or a slow precache, not the loop. See <a href="/tutorials/fix-stuck-verifying-resources">stuck on verifying resources</a>.</li><li><strong>Only high-ping players lag</strong> &mdash; that is normal geography, not a server fault. Consider <code>sv_maxupdaterate</code> tuning, not a rebuild.</li></ul><h2>Verification</h2><p>Run <code>stats</code> repeatedly under a live 10-player load and confirm the FPS number holds near your <code>sys_ticrate</code> target and the CPU column stays comfortably under 100. Have one player run <code>net_graph 3</code> and watch for a flat, gap-free graph &mdash; steady <code>fps</code> and no choke or loss. If the server FPS is steady and rates are correct but a player still rubber-bands, the problem is that player's connection, not your server. Once the loop is stable, lock in the rate cvars in <a href="/tutorials/setup-server-cfg-cs16">server.cfg</a> so they survive restarts.</p>
+12 -0 fix-wrong-elf-class-elfclass64/en.md A
@@ -0,0 +1,12 @@
1 +---
2 +title: "Fix: 'wrong ELF class: ELFCLASS64' Loading a Module"
3 +excerpt: "Why HLDS refuses a 64-bit .so with 'wrong ELF class: ELFCLASS64', how to find the offending file with the file command, and how to get the 32-bit build it actually needs."
4 +category: "errors"
5 +tags: "linux, 32-bit"
6 +image: ""
7 +read_time: "8 min read"
8 +---
9 +<p>You add a Metamod plugin or an AMX Mod X module, restart, and the console prints a line like this before the module fails to load:</p><pre>dlopen failed: /path/to/module_amxx.so: wrong ELF class: ELFCLASS64</pre><p>This is not a corrupt file and it is not a bad path. It is an architecture mismatch: GoldSrc <strong>HLDS and ReHLDS are 32-bit processes</strong>, and a 32-bit process can only <code>dlopen()</code> a 32-bit shared object. The <code>.so</code> you dropped in is a 64-bit build (ELFCLASS64), so the loader rejects it outright. The fix is always the same shape &mdash; replace the file with the correct 32-bit build &mdash; but you have to find which file is wrong first.</p><h2>1. Confirm the server itself is 32-bit</h2><p>Before blaming the module, prove the process it loads into is 32-bit. Run <code>file</code> on the server binary:</p><pre>file hlds_linux
10 +file engine_i486.so</pre><p>A stock GoldSrc server reports <code>ELF 32-bit LSB executable, Intel 80386</code>. That is expected and correct &mdash; there is no 64-bit HLDS. Everything the engine loads at runtime must match that 32-bit target. This is the same root cause behind <a href="/tutorials/fix-hlds-no-such-file-32bit">'No such file or directory' on a 64-bit host</a>: the whole stack is i386.</p><h2>2. Find the offending .so with file</h2><p>The error message names the exact path that failed &mdash; start there. Run <code>file</code> on it:</p><pre>file addons/amxmodx/modules/mysql_amxx.so</pre><p>A good module reports <code>ELF 32-bit LSB shared object, Intel 80386</code>. The broken one reports <code>ELF 64-bit LSB shared object, x86-64</code>. That single word &mdash; 32-bit vs 64-bit &mdash; is the whole diagnosis. If the message did not name a path clearly, scan every module and plugin binary at once:</p><pre>file addons/amxmodx/modules/*.so addons/metamod/dlls/*.so</pre><p>Anything that prints <code>x86-64</code> is the culprit. On a normal install every one of these should say <code>Intel 80386</code>.</p><h2>3. Replace it with the 32-bit build</h2><p>Modules ship in both flavours, and the download page or archive almost always contains a separate 32-bit file. AMX Mod X module archives include the correct <code>_amxx.so</code> for GoldSrc; the 64-bit variant in the same package is meant for a 64-bit engine you are not running. Pull the 32-bit <code>.so</code> and overwrite the wrong one:</p><pre>cp mysql_amxx_i386.so addons/amxmodx/modules/mysql_amxx.so
11 +file addons/amxmodx/modules/mysql_amxx.so # confirm Intel 80386</pre><p>If you compiled the module yourself, you built for the host architecture by mistake. Rebuild with a 32-bit toolchain &mdash; pass <code>-m32</code> to the compiler and install the 32-bit development libraries &mdash; so the output is ELFCLASS32.</p><h2>4. Check nothing is dragging in 64-bit system libraries</h2><p>A module can be 32-bit and still fail if it links against a system library and <code>LD_LIBRARY_PATH</code> points the loader at 64-bit copies first. The same <code>wrong ELF class</code> message then names a system <code>.so</code> (for example a <code>libssl</code> or <code>libmysqlclient</code>) rather than your module. Inspect the environment the server runs under:</p><pre>echo $LD_LIBRARY_PATH
12 +ldd addons/amxmodx/modules/mysql_amxx.so</pre><p><code>ldd</code> lists the shared libraries the module needs and where the loader resolves each one. If a dependency resolves to a path under <code>/usr/lib/x86_64-linux-gnu/</code>, the loader is handing a 32-bit binary a 64-bit library. Install the i386 version of that library (see <a href="/tutorials/install-32bit-libraries-cs16-linux">installing 32-bit libraries</a>) so the correct copy exists under <code>/usr/lib/i386-linux-gnu/</code>, and make sure the server's launch environment does not force the 64-bit path ahead of it.</p><h2>Common errors</h2><ul><li><strong>Message names a system library, not your module</strong> &mdash; a dependency is being resolved to a 64-bit copy. Install the i386 version and fix <code>LD_LIBRARY_PATH</code>.</li><li><strong>You replaced the file but the error persists</strong> &mdash; you overwrote the wrong path, or a second copy of the module exists elsewhere in the search path. Re-run the <code>file</code> scan across every <code>.so</code>.</li><li><strong>'cannot open shared object file: No such file or directory' instead</strong> &mdash; different problem: the file is missing or a dependency is absent, covered in <a href="/tutorials/fix-amxx-module-failed-to-load">module failed to load</a>.</li><li><strong>Self-compiled module is always 64-bit</strong> &mdash; you omitted <code>-m32</code> or lack the 32-bit dev headers. The build silently targets the host.</li><li><strong>Engine binary itself reports 64-bit</strong> &mdash; you downloaded the wrong server package entirely; GoldSrc HLDS is 32-bit only. Re-fetch the Linux dedicated server files.</li></ul><h2>Verification</h2><p>Run <code>file</code> once more on the file the error named and confirm it now reads <code>ELF 32-bit LSB shared object, Intel 80386</code>. Restart the server and watch the startup log: the module should list as loaded rather than throwing the <code>ELFCLASS64</code> line. For an AMX Mod X module, confirm it at runtime from the server console:</p><pre>amxx modules</pre><p>The module should read <code>running</code>. If every <code>.so</code> in your <code>file</code> scan reports Intel 80386 and the module still will not load, the problem has moved on from architecture to a missing dependency &mdash; trace it with <code>ldd</code> as in step 4.</p>
+11 -0 monetize-cs16-server/en.md A
@@ -0,0 +1,11 @@
1 +---
2 +title: "Monetizing a CS 1.6 Server (VIP and Donations) Without Killing It"
3 +excerpt: "How to earn enough to cover a CS 1.6 server without turning it pay-to-win: what to sell, how to deliver VIP by SteamID, reserved slots, and the mistakes that empty a server."
4 +category: "hosting"
5 +tags: "monetization, vip"
6 +image: ""
7 +read_time: "8 min read"
8 +---
9 +<p>Running a public CS 1.6 server costs real money &mdash; a <a href="/tutorials/choose-vps-for-cs16">VPS</a>, sometimes a domain and a FastDL host. Recovering that cost is reasonable; the trap is selling power. A CS 1.6 community lives or dies on whether regulars feel the game is fair, so the whole art of monetizing is finding value people will pay for that does <strong>not</strong> tilt the round. This walks through what to sell, how to actually deliver it, and where admins wreck their own player count.</p><h2>1. Sell convenience and cosmetics, never advantage</h2><p>Draw a hard line between two categories. <strong>Convenience and cosmetic</strong> perks &mdash; a reserved slot so a donor can always get in, a custom chat tag, a name colour, access to a skins menu, a longer vote weight &mdash; change nothing about who wins the round. <strong>Pay-to-win</strong> perks &mdash; extra HP, more starting money, better guns, spawn armour non-donors do not get &mdash; make every free player feel cheated and they leave. When they leave, the donors have no one to play against and they leave too. The sustainable model is: the round is identical for everyone, VIP just makes the experience nicer around the edges.</p><h2>2. Deliver VIP as an admin flag, keyed to SteamID</h2><p>The clean technical way to grant VIP is an AMX Mod X access flag tied to the donor's SteamID, exactly like an admin entry but with a cosmetic-only flag such as <code>t</code> (custom) instead of command flags. Add the donor to <code>users.ini</code>:</p><pre>; addons/amxmodx/configs/users.ini
10 +; &lt;name or SteamID&gt; &lt;password&gt; &lt;flags&gt; &lt;auth type&gt;
11 +"STEAM_0:1:12345678" "" "t" "ce"</pre><p>The <code>ce</code> auth flags mean "authenticate by SteamID, case-insensitive" &mdash; no password needed, the engine matches their Steam account. A <a href="/plugins/csb-vip-menu">VIP menu plugin</a> then checks for flag <code>t</code> and unlocks the cosmetic perks. See the <a href="/tutorials/amxx-admin-flags-reference">admin flags reference</a> for what each letter does and <a href="/tutorials/users-ini-explained">users.ini explained</a> for the file format.</p><h2>3. Reserved slots are the easiest thing to sell</h2><p>The single most valuable non-abusive perk on a full server is guaranteed entry. When your 24 slots are full, a reserved-slot plugin bumps a non-reserved player so the donor gets in. Grant it with the same flag mechanism and a <a href="/plugins/csb-reserved-slots">reserved slots plugin</a>; the full setup is in <a href="/tutorials/reserved-slots-setup">reserved slots setup</a>. It costs you nothing, it does not affect gameplay, and a popular server can sell every reserved slot it has.</p><h2>4. Handle donations honestly</h2><p>Keep the payment side simple and transparent. State clearly what a donation gets and for how long (a month, permanent), collect the donor's SteamID at payment time because that is what you key the perk to, and deliver promptly. Automating delivery is possible &mdash; a web panel writing to <code>users.ini</code> or a MySQL-backed VIP plugin &mdash; but even a manual process works if you add the SteamID within a day. Be careful with claims: you are accepting a donation for a community server, not selling a licensed product, and Valve owns the game. Do not resell game content, do not imply official status, and check your own country's rules on taking money before you scale it up.</p><h2>5. Price for your size, and reinvest visibly</h2><p>A 30-player server does not command subscription prices. Set VIP low enough that a regular will pay it on a whim, and tell the community the money goes back into the server &mdash; a bigger VPS, DDoS protection, more slots. Players donate to a server they feel part of, not to an anonymous admin. Pair a modest VIP with an active <a href="/plugins/csb-adverts">adverts rotation</a> that mentions how to support the server without nagging every thirty seconds.</p><h2>Common mistakes</h2><ul><li><strong>Player count collapses after adding VIP</strong> &mdash; you sold power. Strip any HP, money, or weapon advantage and keep only cosmetic and convenience perks.</li><li><strong>Donor paid but has no perks</strong> &mdash; wrong SteamID format in <code>users.ini</code>, or the auth flags are missing. Confirm the exact <code>STEAM_0:</code> string with <a href="/tutorials/find-player-steamid">find a SteamID</a> and use <code>ce</code> auth.</li><li><strong>VIP works for you but not the donor</strong> &mdash; the file was not reloaded. <code>users.ini</code> is read on map change; change the map or reload the admin plugin.</li><li><strong>Regulars accuse you of favouritism</strong> &mdash; a cosmetic tag was mistaken for admin power. Make the perks visibly harmless and explain them in the MOTD.</li><li><strong>Chargebacks and disputes</strong> &mdash; treat payments as donations, keep records, and never promise something gameplay-changing you would have to claw back.</li></ul><h2>Verification</h2><p>Add a test SteamID with the VIP flag, change the map, connect on that account, and confirm the VIP menu opens and the cosmetic perks apply. From the admin console, run <code>amx_who</code> and confirm the account shows the <code>t</code> flag. Then join on a non-VIP account and confirm the round plays <em>identically</em> &mdash; same HP, same money, same guns. If a free player can point at anything that makes the donor stronger, you have not monetized safely yet; roll that perk back to cosmetic.</p>
0 12