Particle effects (fire, smoke...)
Place lasting particle effects like fires and smoke, fire one-off bursts at a point or on an entity, and find effect names.
The server can play the game’s particle effects (fire, smoke, sparks, blood,
dust) for everyone near them, with the server
Vfx class. A placed effect stays
and streams to whoever comes near. A burst plays once for whoever is there
now.
const at = player.position;const fire = Vfx.spawn("WH_Particels.fires.campfire_a", new Vector3(at.x, at.y + 3, at.z), { prime: true });Vfx.burst("collisions.combat.sword_sword", at);WH_Particels is how the game spells the library. Copy names, do not retype
them.
Find an effect name
Section titled “Find an effect name”A name is library.group.effect.
Vfx.list(prefix?) returns the
whole vocabulary (about 600 names, the same list clients have, and listed in
Particle effects), or those starting with a prefix:
for (const name of Vfx.list("WH_Particels.fires")) console.log(name);A placed effect reads back as effect, library (WH_Particels) and group
(fires).
A resource can ship particle libraries of its own, as
stream/libs/particles/kcdc_<resource>_<name>.xml. Their effects are named
the same way, kcdc_<resource>_<name>.<group>.<effect>, work in every call
on this page and on the client, and are not in Vfx.list. See
Custom assets.
Place a lasting effect
Section titled “Place a lasting effect”Use Vfx.spawn for a campfire, a torch, smoke over a burning house. It is a
replicated entity, so late arrivals see it, and it lasts until destroyed. It
streams within the effect’s own draw distance, clamped to 25 to 250 m.
const smoke = Vfx.spawn( "WH_Particels.fires.campfire_a", new Vector3(1024, 512, 40), { prime: true, // start already running, instead of growing from nothing scale: 1.5, // multiplies every authored size, 0.01 to 32 countScale: 2, // more particles, 0.01 to 16 }, player.virtualWorld,);prime: true is almost always right for fires and plumes. Other options:
| Option | Range | Effect |
|---|---|---|
rotation |
Aims the emitter. | |
speedScale |
0 to 16 | Emission speed. |
timeScale |
0.01 to 16 | The emitter’s clock. |
strength |
-1 to 1 | Feeds the effect’s strength curves; -1 means as authored. |
pulsePeriod |
0 to 600 s | Restarts the emitter every so often, keeping a one-shot effect repeating. |
durationMs |
Ignored by spawn. |
Change a placed effect
Section titled “Change a placed effect”Every tuning value is writable on the handle. Each assignment restarts the effect on every client that sees it, because an emitter reads its settings once. Out-of-range values are clamped.
Play a one-off burst
Section titled “Play a one-off burst”A burst keeps nothing on the server and goes only to clients within draw distance. Someone who walks up a second later sees nothing: right for a spark, wrong for a campfire.
// At a point. durationMs: how long each client keeps the emitter, default 2 s, max 60 s.const told = Vfx.burst("collisions.combat.sword_sword", player.position, { durationMs: 1000 });
// On an entity, following it: any replicated handle, or a bare network id.Vfx.burstOn("collisions.combat.sword_sword", player, { offset: new Vector3(0, 0, 1.2) });Both return how many clients were told (0 when nobody was near). burstOn
takes an offset in the entity’s space, up to 8 m, and a client that has not
streamed the entity drops it. burst takes an optional virtual world last;
burstOn uses the entity’s. Bursts raise no events.
Remove effects
Section titled “Remove effects”const torch = Vfx.spawn("WH_Particels.fires.campfire_a", player.position, { prime: true });
Vfx.all(3); // placed effects in virtual world 3 (omit for all)Vfx.getById(torch.id); // one, or nulltorch.destroy(); // stop this oneVfx.destroyAll(3); // every placed effect in world 3; returns the countVfx.destroyAll(); // every placed effect on the serverBursts are not listed and need no cleanup. Placed effects outlive your
resource, so destroy yours in resourceStop (see
Props).
| Event | Arguments | When |
|---|---|---|
vfxSpawn |
vfx |
Right after an effect is placed. |
vfxDestroy |
vfx |
While it is stopped. The handle still reads. |
When a call fails
Section titled “When a call fails”| Call | Fails when | Result |
|---|---|---|
Vfx.spawn, Vfx.burst |
The name is not an effect, nor one from a library a running resource streams. | Throws. Catch it when the name came from a player. |
| Any numeric option | Out of range. | Clamped. |
| Any effect | A client already plays 192 effects (placed, bursts and client-side, combined). | New ones do not appear. Go easy on long bursts and large countScale. |
On the client
Section titled “On the client”Client resources have their own Vfx that plays on that machine only
(spawn, attach, stop, stopAll, isPlaying, has, list). Nothing is
replicated, so use it for what only that player should see, like a hit marker.
Every effect it starts has a duration and stops when the session ends.
// clientconst me = LocalPlayer;if (me) { const handle = Vfx.spawn("collisions.combat.sword_sword", me.position, { durationMs: 1500 }); console.log(`playing: ${Vfx.isPlaying(handle)}`);}Related
Section titled “Related”- Vfx reference, every option
- Props, to pair a fire with a model
- Custom assets, to ship effects of your own
- Virtual worlds, per-world effects
- Server vs client authority, what client-only means