Precaching Models, Sounds and Sprites Correctly

March 12, 2026 Daemon666 7 min read 11 görüntülenme

If a plugin plays a custom sound, spawns a custom model, or draws a sprite, the file has to be precached — registered with the engine at map start so it gets an index and is offered to clients. Precache in the wrong place, or with the wrong path, and you get one of two failures: a silent no-op where nothing plays, or a hard Host_Error that kills the map. This guide covers the three precache natives, their path rules, and the overflow that catches everyone eventually.

1. Precache in plugin_precache, never later

The engine only accepts precache calls during initialization. AMXX gives you exactly one place: the plugin_precache() forward, which runs before the map spawns entities. Calling a precache native from plugin_init, a command handler, or a task is too late and errors:

#include <amxmodx>

new g_smokeSpr

public plugin_precache()
{
    precache_model("models/csb/w_medkit.mdl")
    precache_sound("csb/heal.wav")
    g_smokeSpr = precache_model("sprites/smoke.spr")
}

public plugin_init()
{
    register_plugin("Precache Demo", "1.0", "CSB")
}

Store the returned index for anything you reference later by number — sprites used in temp-entity messages, for instance, are addressed by their precache index, not their path.

2. The path rules differ per native

This is the detail that wastes the most time. The base folder is different for models and sounds:

NativePath is relative toExample
precache_modelcstrike/"models/csb/w_medkit.mdl"
precache_soundcstrike/sound/"csb/heal.wav" (no sound/ prefix)
precache_genericcstrike/"sprites/csb/hud.txt"

Models and sprites (both .mdl and .spr go through precache_model) include the folder from cstrike/. Sounds do not include sound/ — the engine adds it. Writing precache_sound("sound/csb/heal.wav") looks for sound/sound/csb/heal.wav and fails silently.

3. Playing what you precached

A precached sound plays with emit_sound or a client command; the path matches what you precached (again, no sound/ prefix for emit_sound):

public heal_effect(id)
{
    emit_sound(id, CHAN_ITEM, "csb/heal.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
}

A model is assigned by writing the path into an entity's model, or by index for effects. A sprite drawn via a temp entity uses the stored index:

// example: reference the precached sprite by its saved index
// (inside a TE message you would write g_smokeSpr as the sprite index)

4. precache_generic for FastDL and non-auto files

Files the engine does not precache automatically — a sprite referenced only inside an event file, a .txt, extra sounds — still need to be offered to clients for download. precache_generic registers them so they are added to the download list without being loaded as a model or sound. This is how custom-content plugins make sure clients actually receive their files over FastDL.

5. The overflow that crashes map load

The engine caps how many models and sounds can be precached (historically around 512 models). Every plugin that precaches adds to a shared pool — so a server running twenty content plugins can blow the limit even though no single plugin is unreasonable. When it overflows, map load dies with a message like:

Host_Error: PF_precache_model_I: Model 'models/...' failed to precache because the item count is over the 512 limit.

The fixes are real work, not a flag: remove duplicate precaches (two plugins caching the same model both count), drop unused content, or move rarely-used models to load-on-demand designs. The dedicated walkthrough is the precache/model overflow fix.

Common errors

  • Sound never plays, no error — you included sound/ in the path. Drop it; precache_sound and emit_sound are relative to sound/ already.
  • failed to precache on map load — either the file is missing on the server, or you hit the overflow limit. Confirm the file exists at the exact path first, then count total precaches.
  • Model shows as a big red ERROR in-game — the .mdl was precached but the client never downloaded it. It needs to be on FastDL and, for some files, registered with precache_generic.
  • Precache call from a command or task — it is ignored or errors. All precaching must happen in plugin_precache.
  • Case-sensitivity on LinuxHeal.wav and heal.wav are different files on a Linux server. Match the case exactly.

Verification

Load the plugin, change the map, and watch the server console during load for any failed to precache line — that is your first signal. In-game, trigger the sound and confirm it plays, and confirm the model renders instead of an ERROR sign. To audit total precache pressure across all your plugins, count how many models and sounds each one caches; the overflow is cumulative. For the deep dive on hitting the limit, see fixing model/precache overflow.

Katkıda bulunanlar: Daemon666 ✦
Paylaş: