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

Add 2 tutorials (2 files)

Browse Source
Daemon666 committed parent 6b32dccfbe commit 94f018f46a4b32c68013c521629add4627d8d46e
2 changed files with 157 additions and 0 deletions
+57 -0 fix-low-server-fps-linux/en.md A
@@ -0,0 +1,57 @@
1 +---
2 +title: "Fix: Server FPS Stuck at 100 / Low Server FPS on Linux"
3 +excerpt: "Why hlds_linux caps at 100 server FPS, how sys_ticrate, the kernel timer and -pingboost interact, and the safe ways to raise and hold a stable server FPS."
4 +category: "errors"
5 +tags: "fps, sys_ticrate"
6 +image: ""
7 +read_time: "8 min read"
8 +---
9 +<p>You check <code>stat</code> or an FPS plugin and the server sits at exactly 100 FPS no matter what you set. Server FPS on the Half-Life engine is how many times per second the server simulates and sends updates; a server pinned at 100 feels laggier than its rate settings suggest, and hitreg suffers. On Linux the cap comes down to how the engine sleeps between frames and how you launch it. Here is how to raise it without setting the CPU on fire.</p>
10 +
11 +<h2>1. See what you actually have</h2>
12 +<p>On the server console:</p>
13 +<pre>stat
14 +sys_ticrate</pre>
15 +<p><code>stat</code> prints the current server FPS. <code>sys_ticrate</code> is the requested maximum. If <code>sys_ticrate</code> is 100 (or unset), 100 is your ceiling by design — the fix is to raise it and to make the engine able to reach it.</p>
16 +
17 +<h2>2. Raise sys_ticrate</h2>
18 +<p>Set it on the launch line or in <code>server.cfg</code>. A common target is 500 or 1000:</p>
19 +<pre>sys_ticrate 1000</pre>
20 +<p>Or on the command line:</p>
21 +<pre>./hlds_run -game cstrike -pingboost 0 -sys_ticrate 1000 \
22 + -ip 0.0.0.0 -port 27015 +maxplayers 20 +map de_dust2</pre>
23 +<p>Raising the number alone is often not enough on stock HLDS, because how the engine waits between frames — the pingboost mode — decides whether it can actually hit that rate.</p>
24 +
25 +<h2>3. Understand -pingboost and the timer</h2>
26 +<p>Stock <code>hlds_run</code> supports <code>-pingboost 1/2/3</code>, which switch the sleep strategy between frames. Higher pingboost modes busy-wait more aggressively and can raise FPS, but they burn CPU and some modes are unstable on modern kernels. This is the classic trade: a higher, steadier FPS costs CPU. Test each mode and watch both <code>stat</code> and host CPU:</p>
27 +<pre>-pingboost 1
28 +-pingboost 2
29 +-pingboost 3</pre>
30 +<p>Do not cargo-cult a mode from a forum — measure on your kernel. If a mode makes FPS erratic or spikes CPU to 100% for no players, it is the wrong mode for your box; see <a href="/tutorials/fix-hlds-100-cpu">the 100% CPU guide</a>.</p>
31 +
32 +<h2>4. Run ReHLDS and let it hold FPS properly</h2>
33 +<p>The clean answer in 2026 is <a href="/tutorials/install-rehlds-on-linux">ReHLDS</a>. Its frame timing is far better than stock HLDS and it holds a requested FPS with much less CPU than pingboost hacks. On ReHLDS, <code>sys_ticrate 1000</code> with the default sleep strategy typically gives a stable 1000 FPS on a modern core, and there are ReHLDS cvars to tune the sleep behaviour if needed. If you care about server FPS at all, the engine swap is the highest-leverage change you can make.</p>
34 +
35 +<h2>5. Do not confuse server FPS with client updates</h2>
36 +<p>Server FPS caps how often the server ticks; it interacts with <code>sv_maxupdaterate</code>. There is no point running 1000 server FPS with <code>sv_maxupdaterate 20</code> — the updates a client receives are bounded by the rate cvars. Keep them coherent:</p>
37 +<pre>sys_ticrate 1000
38 +sv_maxupdaterate 101
39 +sv_maxrate 25000</pre>
40 +
41 +<h2>6. Rule out the host and the timer</h2>
42 +<p>On a shared or heavily oversubscribed VPS you can set <code>sys_ticrate 1000</code>, run ReHLDS, and still not hold it — because the hypervisor is not giving your vCPU consistent time. Two quick checks separate "my config is wrong" from "my host is the problem". First, watch steal time on the host:</p>
43 +<pre>top # look at the %st (steal) column</pre>
44 +<p>Non-trivial steal means the hypervisor is scheduling you off the CPU, and no cvar fixes that — you need a better plan or a dedicated core. Second, confirm the measurement itself: idle FPS and loaded FPS are different worlds, so always judge with players on. A server that holds 1000 empty and 1000 with a full match on a dedicated box is genuinely healthy; the same config on a busy VPS is at the mercy of neighbours.</p>
45 +
46 +<h2>Common errors</h2>
47 +<ul>
48 +<li><strong>FPS stuck at exactly 100</strong> — <code>sys_ticrate</code> is at its default; raise it and confirm the engine can reach it.</li>
49 +<li><strong>Raised sys_ticrate, FPS did not move</strong> — stock HLDS sleep strategy is capping you. Try a <code>-pingboost</code> mode or, better, move to ReHLDS.</li>
50 +<li><strong>High FPS but CPU pinned at 100%</strong> — an aggressive pingboost busy-wait. Expected trade-off; drop the mode or switch engines. See <a href="/tutorials/fix-hlds-100-cpu">the CPU fix</a>.</li>
51 +<li><strong>FPS swings wildly under load</strong> — the box is oversubscribed (shared VPS with noisy neighbours) or the kernel timer is coarse. A dedicated core and ReHLDS fix most of this.</li>
52 +</ul>
53 +
54 +<h2>Verification</h2>
55 +<p>With players on the server (idle FPS is not representative), run repeatedly:</p>
56 +<pre>stat</pre>
57 +<p>You want the FPS to sit at or near your <code>sys_ticrate</code> target and stay there through a full round, while host CPU stays reasonable for the player count. A number that reads 1000 when empty but collapses to 300 under 20 players means you are CPU-bound — reduce pingboost aggressiveness, move to ReHLDS, or get a faster core. Watch it for a whole map, not a single sample.</p>
+100 -0 pawn-basics-for-amxx/en.md A
@@ -0,0 +1,100 @@
1 +---
2 +title: "Pawn Language Basics for AMX Mod X Beginners"
3 +excerpt: "Pawn is not C, and the differences bite: no real strings, one numeric type with tags, and forwards instead of a main(). A concise, correct primer for admins writing their first AMXX plugin."
4 +category: "plugin-dev"
5 +tags: "pawn, basics"
6 +image: ""
7 +read_time: "8 min read"
8 +---
9 +<p>AMX Mod X plugins are written in Pawn, a small embedded language that looks like C but is not C. The differences that trip up experienced programmers are specific and worth learning up front: there is essentially one numeric type, strings are just arrays, and there is no <code>main()</code> &mdash; the engine calls named public functions. Get these five concepts right and the rest of the API is just function lookups.</p>
10 +
11 +<h2>1. Cells, tags, and floats</h2>
12 +<p>Every variable in Pawn is a 32-bit <em>cell</em>. There is no separate <code>int</code>, <code>float</code>, or <code>bool</code> type &mdash; there are <em>tags</em> that reinterpret the cell. A plain cell is an integer; the <code>Float:</code> tag makes it a float:</p>
13 +<pre>new count = 5 // integer cell
14 +new Float:speed = 250.0 // float cell, note the Float: tag
15 +new bool:ready = true // bool tag</pre>
16 +<p>Mixing tags without conversion produces a <em>tag mismatch</em> warning. Convert explicitly with <code>float()</code> and <code>floatround()</code>:</p>
17 +<pre>new Float:half = float(count) / 2.0
18 +new rounded = floatround(speed)</pre>
19 +<p>Float math uses normal operators in modern Pawn, but tag discipline is strict &mdash; treat a warning as an error.</p>
20 +
21 +<h2>2. Strings are arrays of cells</h2>
22 +<p>Pawn has no string type. A string is a <code>char</code>-tagged or plain cell array, null-terminated. You size it yourself:</p>
23 +<pre>new name[32]
24 +new message[192]</pre>
25 +<p>You never assign a string with <code>=</code>. Use the string functions and <code>charsmax()</code>, which is <code>sizeof(arr) - 1</code> &mdash; the size minus the null terminator:</p>
26 +<pre>copy(message, charsmax(message), "Hello")
27 +formatex(message, charsmax(message), "Player %s has %d frags", name, frags)</pre>
28 +<p>Compare strings with <code>equal()</code>, never <code>==</code>. <code>==</code> on arrays compares nothing useful:</p>
29 +<pre>if (equal(cmd, "menu")) { /* ... */ }</pre>
30 +
31 +<h2>3. Variable declaration and scope</h2>
32 +<p>Declare locals with <code>new</code>. There is no <code>int x = 0</code> &mdash; it is <code>new x = 0</code>. Globals are just <code>new</code> at file scope. Constants use <code>const</code> or <code>#define</code>:</p>
33 +<pre>#define MAX_CLIENTS 32
34 +new const VERSION[] = "1.0.0"
35 +new g_iKills[MAX_CLIENTS + 1] // global array, index by player id</pre>
36 +<p>Player IDs run 1&ndash;32, so player arrays are sized <code>[33]</code> (index 0 unused) &mdash; that <code>+ 1</code> is deliberate.</p>
37 +
38 +<h2>4. Function kinds: public, native, stock, forward</h2>
39 +<p>The keyword in front of a function tells the compiler who calls it:</p>
40 +<ul>
41 +<li><strong><code>public</code></strong> &mdash; callable by the engine/AMXX (event handlers, command callbacks, <code>plugin_init</code>). Must be <code>public</code> or the engine cannot find it.</li>
42 +<li><strong><code>native</code></strong> &mdash; a function implemented in a module (C++), declared in an include. You call these; you do not write their bodies.</li>
43 +<li><strong><code>stock</code></strong> &mdash; a helper that is only compiled into the plugin if you actually use it. No warning if unused.</li>
44 +<li><strong><code>forward</code></strong> &mdash; a declaration of a public that AMXX will call (used in includes).</li>
45 +</ul>
46 +<p>A handler you register must be <code>public</code> and its name must match the string you registered:</p>
47 +<pre>public plugin_init() {
48 + register_plugin("My Plugin", "1.0", "Me")
49 + register_clcmd("say /hp", "cmd_hp")
50 +}
51 +public cmd_hp(id) {
52 + client_print(id, print_chat, "You have %d HP", get_user_health(id))
53 + return PLUGIN_HANDLED
54 +}</pre>
55 +
56 +<h2>5. Control flow and operators</h2>
57 +<p>Familiar C syntax: <code>if/else</code>, <code>for</code>, <code>while</code>, <code>switch</code>. One assignment trap: <code>=</code> assigns, <code>==</code> compares &mdash; the compiler warns on <code>if (x = 5)</code> but people still do it. Loop over players by id:</p>
58 +<pre>for (new i = 1; i &lt;= get_maxplayers(); i++) {
59 + if (!is_user_connected(i))
60 + continue
61 + client_print(i, print_chat, "Round starting")
62 +}</pre>
63 +<p><code>switch</code> uses <code>case</code> without fall-through, and multiple values share a case with commas:</p>
64 +<pre>switch (weapon) {
65 + case CSW_AWP, CSW_SCOUT: client_print(id, print_chat, "Sniper")
66 + default: client_print(id, print_chat, "Other")
67 +}</pre>
68 +
69 +<h2>6. Cvars and tasks the AMXX way</h2>
70 +<p>Two idioms you will use in almost every plugin. Register a cvar once and read it through its handle &mdash; caching the pointer is faster than looking it up by name every time:</p>
71 +<pre>new g_pEnabled
72 +
73 +public plugin_init() {
74 + register_plugin("Demo", "1.0", "Me")
75 + g_pEnabled = register_cvar("demo_enabled", "1")
76 +}
77 +
78 +public some_event(id) {
79 + if (!get_pcvar_num(g_pEnabled))
80 + return
81 + // ...
82 +}</pre>
83 +<p>Run code later or on a repeat with <code>set_task</code>. The time is a <code>Float:</code>, and a flag like <code>"b"</code> makes it loop:</p>
84 +<pre>set_task(5.0, "show_advert", _, _, _, "b") // every 5 seconds, forever
85 +
86 +public show_advert() {
87 + client_print(0, print_chat, "Visit our website")
88 +}</pre>
89 +<p>Return values matter for command callbacks: <code>PLUGIN_HANDLED</code> stops the game from also processing the input (so a chat trigger does not leak to public chat), while <code>PLUGIN_CONTINUE</code> lets it through. These are constants from <code>amxmodx.inc</code>, not numbers to memorise.</p>
90 +
91 +<h2>Common mistakes</h2>
92 +<ul>
93 +<li><strong><code>tag mismatch</code></strong> &mdash; mixing <code>Float:</code> and integer cells; convert with <code>float()</code>/<code>floatround()</code>.</li>
94 +<li><strong><code>array must be indexed</code></strong> &mdash; you used a string array where a single cell was expected, or compared strings with <code>==</code>.</li>
95 +<li><strong>Handler never fires</strong> &mdash; the function is not <code>public</code>, or its name does not match the registered string exactly.</li>
96 +<li><strong>Buffer overflow / garbage text</strong> &mdash; you sized a string too small or passed the wrong length to <code>formatex</code>; always use <code>charsmax()</code>.</li>
97 +</ul>
98 +
99 +<h2>Next step</h2>
100 +<p>With the syntax in hand, write something that runs: follow <a href="/tutorials/write-first-amxx-plugin">Write Your First AMX Mod X Plugin</a>, then <a href="/tutorials/compile-sma-to-amxx">compile it to .amxx</a>. For real natives, keep the AMXX include files open &mdash; every function above is declared in <code>amxmodx.inc</code>, <code>cstrike.inc</code>, or <code>fun.inc</code>.</p>
0 101