How to implement custom particle effects (muzzle flash, smoke, sparks, etc.) in your weapon compiles.
Muzzle smoke is just awesome and stylish. Fire a weapon, let it cool down for a moment and smoke starts trailing out of the barrel. Well, I'm going to demonstrate how to achieve that for CS:S, DOD:S, TF2... basically any Source engine game.
Notice:
If you use this in your own projects, credit Zira for the particle effects. Most of the releases out there are using hers. I had nothing to do with this other than the QC code.
I'm probably not the first person to discover the method, but whatever. : /
The Basics
1.Get a PCF and decide which particle effects to use.
2.Get its required material files.
3.Add the PCF to particles_manifest.txt.
4.Add particle effects to QC sequences. Like this:
{ event AE_CL_CREATE_PARTICLE_EFFECT 20 "particle_effect_here follow_attachment 1" }
The "1" is an $attachment named "1". You could just as easily make an $attachment "barrel" and say "particle_effect follow_attachment barrel".
5.Test in-game and include your PCFs, particles_manifest.txt and materials in your release.
Detailed instructions
- 1.Get your PCFs.
PCF files can be thought of as containers for particle effects. For example, one PCF named "MyParticles.PCF" can contain many different particle effects, like muzzle_smoke, rifle_flash, rifle_sparks, etc. You can view the individual particle effects embedded in a PCF file in one of two ways:
Start a Source engine game with the "-tools" command line option. (CS:S doesn't support this, but TF2, DOD:S, HL2, etc. do. L4D2 has its own tools mode packaged with L4D2 Authoring Tools.) Anyway, choose "Particle editor" from the tools menu and file > open. Open a PCF file and you should be able to see the effect in action. Look in the "string" field to see the materials path.
Alternatively, download VIDE. It's basically a third-party Source SDK. Install/run it, click the particle editor icon and open a PCF file. You won't be able to see the effect until you go in-game, but you can still see a list of all the effects. Click the arrow by any effect and you'll see all kinds of details about it. The "material" line tells you which materials the effect uses.
Whichever method you use, knowing the path to the materials and including them in your release is very important. But, yeah. Drag the PCF file/s and their required materials to your base game folder. Cstrike, for example. Might be a good idea to paste these into a new folder for your release as well.
- 2.Add PCFs to the manifest.
Counter-Strike: Source will not precache any particles not listed in particles_manifest.txt. In other words, if you don't add your custom particles to it, the game won't know to prepare them for use. So, in the cstrike directory, look for particles_manifest.txt. (Or create one.) Add a line to the bottom like this:
"file" "!particles/Your_PCF_File.pcf"
- 3.Create the attachment.
The QC code we're going to use makes the particle emitter "follow" the specified attachment. So, for example, if I have:
$attachment "1" "muzzle" 0 0 0 rotate 0 0 0
that means we have an attachment named "1" which is linked to the "muzzle" bone. That's right: there's a bone named "muzzle" in all of the SMD files and the "1" attachment follows it. In CS:S, the "1" attachment is where the muzzle flash generates by default, so it's an ideal place for smoke, more muzzle flash, sparks. etc.
- 4.Coding
Here's where you tell your weapon to generate the particle/s. Let's start off with a plain shoot sequence.
$sequence shoot1 "shoot1" ACT_VM_PRIMARYATTACK 1 snap fps 40.00 {
{ event 5001 0 "1" }
{ event AE_CLIENT_EFFECT_ATTACH 0 "EjectBrass_9mm 2 100" }
}
Now, add the particle line so that it looks like this:
$sequence shoot1 "shoot1" ACT_VM_PRIMARYATTACK 1 snap fps 40.00 {
{ event 5001 0 "1" }
{ event AE_CLIENT_EFFECT_ATTACH 0 "EjectBrass_9mm 2 100" }
{ event AE_CL_CREATE_PARTICLE_EFFECT 20 "smoke_trail follow_attachment 1" }
}
Now, to break things down a bit.
The "20" simply tells the game on which frame of the animation to start emitting the particle. I advise to put it on the very last frame, but 20 is usually pretty good. The reason for this is: when you fire rapidly, smoke will generate on every shot, making a real mess of smoke. Putting it further in the sequence makes the smoke emit only when you give your gun a little time to cool down. Just like real life, eh?
Note:
If your compiler gives you an error message like "Event # out of range in frame #", that means you tried to emit the particle on a frame of the animation that doesn't exist. So decrease the number. You can quickly see how many frames are in a sequence by opening the model in MDLViewer.



