register_event vs Hamsandwich vs ReAPI: When to Use Which

July 2, 2025 Daemon666 7 min read 189 vizualizări

AMX Mod X gives you three fundamentally different ways to react to what happens in a round, and choosing wrong means either code that cannot see what you need or a dependency you did not have to take on. register_event listens to network messages. Ham Sandwich hooks virtual functions inside the game DLL. ReAPI hooks ReGameDLL's real functions with named arguments. They overlap in what they can do but differ sharply in what they can see, whether they can change it, and what they require to be installed.

1. register_event — the network message layer

Events fire when the game DLL sends a message to a client: someone died (DeathMsg), health changed (Health), a weapon became active (CurWeapon). It is pure core AMXX — no module, no engine replacement — so it runs on stock HLDS as happily as on ReHLDS. See the register_event guide for details.

Its limitation is that it is a notification, not an interception. By the time DeathMsg is sent, the player is already dead. You can react, but you cannot prevent, and you cannot read anything the message does not carry. It is also occasionally lossy: a message that the DLL chooses not to send is an event you never see.

2. Ham Sandwich — virtual function hooks

Ham Sandwich (module hamsandwich) hooks the virtual methods of game entities: Ham_TakeDamage, Ham_Killed, Ham_Spawn, Ham_Player_PreThink. These fire as the function runs, in both a pre and a post variant, so you can read the real arguments and — crucially — block or modify them:

#include <amxmodx>
#include <hamsandwich>

public plugin_init()
{
    register_plugin("Ham Demo", "1.0", "CSB")
    RegisterHam(Ham_TakeDamage, "player", "fw_take_damage", 0)
}

public fw_take_damage(victim, inflictor, attacker, Float:damage, bits)
{
    // halve all incoming damage
    SetHamParamFloat(4, damage * 0.5)
    return HAM_HANDLED
}

Ham Sandwich works on both original CS and ReGameDLL, which is its great advantage: portable damage/spawn/kill hooks that run anywhere. The cost is that it deals in raw offsets — entity classnames, parameter positions — and gives you no named members. See the Ham Sandwich guide.

3. ReAPI — the ReGameDLL native layer

ReAPI (module reapi) exposes ReGameDLL and ReHLDS internals directly: hook chains (RegisterHookChain), named members (get_member/set_member), and high-level natives (rg_give_item, rg_add_account). It is the richest and cleanest of the three — but it requires ReGameDLL. A plugin that #include <reapi> will not load on a server running the stock game DLL.

#include <amxmodx>
#include <reapi>

public plugin_init()
{
    register_plugin("ReAPI Demo", "1.0", "CSB")
    RegisterHookChain(RG_CBasePlayer_TakeDamage, "on_take_damage", 0)
}

public on_take_damage(const victim, inflictor, attacker, Float:damage, bits)
{
    SetHookChainArg(4, ATYPE_FLOAT, damage * 0.5)
    return HC_CONTINUE
}

If you ship a ReAPI plugin, set both reapi_required and regamedll_required in its metadata — the two go together. Install steps are in the ReAPI install guide, which itself depends on ReGameDLL.

4. The decision rule

register_eventHam SandwichReAPI
RequiresCore AMXX onlyhamsandwich moduleReGameDLL + reapi
Can block / modifyNoYesYes
Named argumentsNoNoYes
Runs on stock CS DLLYesYesNo

In practice:

  • You only need to know something happened — a kill for a HUD, a weapon switch for a speed cap — use register_event. It is the lightest and most portable.
  • You need to change damage, spawning, or killing, and the plugin must run on any server — use Ham Sandwich. It is the portable interception layer.
  • You are already on ReGameDLL and want clean, correct, named access — use ReAPI. It replaces piles of Ham + fakemeta guesswork with readable natives, at the price of a hard dependency.

5. They compose

Real plugins mix all three: a register_event on DeathMsg to update a scoreboard, a RegisterHam(Ham_Spawn, ...) to give spawn protection, and — on a ReGameDLL server — rg_add_account to hand out money. There is no rule against combining them; the rule is to take the lightest tool that can see and do what a given feature needs, so the plugin loads on the widest set of servers.

Common mistakes

  • Reaching for ReAPI on a stock-DLL server — the plugin fails to load with a module error. Confirm ReGameDLL first with regamedll_version in the console.
  • Trying to block damage with register_event — impossible; events are notifications. Move the logic to Ham_TakeDamage or the ReAPI hook chain.
  • Hooking the same effect in two layers — e.g. blocking damage in Ham and ReAPI. Pick one; double-hooking produces confusing double-applied modifications.

Verification

For any hook, add a server_print at the top of the handler and confirm it fires exactly once per real in-game event. If a Ham or ReAPI plugin refuses to load, check the AMXX logs for a module-load line — a missing hamsandwich or reapi module is the usual cause, covered in the module-failed-to-load fix.

Contribuitori: Daemon666 ✦
Distribuie: