Debugging AMXX Plugins: debug Mode, server_print and Logs

April 23, 2026 Daemon666 7 min read 15 vistas

When an AMXX plugin misbehaves you have three tools, and used together they resolve almost everything: debug mode (so run-time errors carry line numbers), print/log natives (so you can trace state), and the AMXX log files (where the engine already wrote down what went wrong). The mistake most people make is guessing before reading the log. This guide is the order to work in.

1. Read the log first

AMX Mod X writes to dated files under cstrike/addons/amxmodx/logs/. Before changing any code, open the newest one. A run-time error is already recorded there with the plugin name and, if debug mode is on, the exact line:

L 07/15/2026 - 21:14:03: [AMXX] Run time error 4 (index out of bounds)
L 07/15/2026 - 21:14:03: [AMXX]    [0] myplugin.sma::give_award (line 88)

That second line — the call trace with a line number — only appears when the plugin runs in debug mode. Without it you get the error but not the location, which is why step 2 exists.

2. Turn on debug mode

Debug mode is per-plugin and set in plugins.ini. Add the word debug after the plugin filename:

; cstrike/addons/amxmodx/configs/plugins.ini
myplugin.amxx debug

Change the map or restart, reproduce the error, and the log now shows the file, function, and line. Debug mode adds overhead, so use it while investigating and remove it on a busy production server once fixed. Plugins compiled locally already carry debug symbols; the debug keyword is what tells AMXX to use them at runtime.

3. Trace state with server_print and log_amx

server_print writes to the server console immediately — ideal for watching values as they change while you have a console open. log_amx writes to the AMXX log with a timestamp, which survives after the moment passes:

public give_award(id)
{
    server_print("give_award: id=%d alive=%d frags=%d",
        id, is_user_alive(id), get_user_frags(id))

    if (!is_user_connected(id))
    {
        log_amx("give_award called with invalid id %d", id)
        return
    }
    // ...
}

Use server_print for live tracing and log_amx (or log_to_file for a dedicated file) for anything you need to inspect after the fact — an intermittent bug that happens once an hour is not something you will catch staring at the console.

4. Bail out cleanly with set_fail_state

If a plugin cannot run — a required cvar is missing, a module did not load, a table is absent — do not limp on and crash later. set_fail_state stops the plugin with a logged reason:

public plugin_init()
{
    register_plugin("Award", "1.0", "CSB")

    if (!cvar_exists("mp_startmoney"))
        set_fail_state("required cvar mp_startmoney missing")
}

A plugin in the failed state shows as debug/bad load in amxx plugins, with your message in the log — far easier to diagnose than a null-index crash three functions later.

5. Inspect loaded plugins live

From the server console, amxx plugins lists every plugin and its status: running, paused, debug, or bad load. amxx modules does the same for modules. A plugin that depends on fakemeta or reapi showing bad load almost always means the module underneath it failed — check amxx modules before blaming the plugin:

amxx plugins
amxx modules

Common errors and what they mean

  • Run time error 4 (index out of bounds) — an array or player index out of range, very often an id of 0 (the world) or 33+. Guard with is_user_connected. Full walkthrough: run-time error 4.
  • Run time error 10 (native error) — a native was called with a bad argument, e.g. an invalid entity. The trace line points at the call.
  • No line numbers in the trace — debug mode is off. Add debug in plugins.ini and reproduce.
  • Plugin shows bad load — a missing module or a plugin compiled against a newer AMXX. See module failed to load and bad load after upgrading.
  • Console flooded, server lags — you left a server_print inside a per-frame hook like FM_PlayerPreThink. Remove trace prints from hot paths before shipping.

Verification

Reproduce the bug with debug mode on and confirm the log now names the exact line. Fix it, reload, and confirm the error is gone from a fresh log file — not just absent from the console, which can lie if the plugin failed to reload. When a whole plugin refuses to start, amxx plugins plus the newest log file will tell you whether it is the plugin or a module beneath it. To narrow down which of many plugins is crashing the server, see finding the crashing plugin.

Colaboradores: Daemon666 ✦
Compartir: