4 min

Particles

Spawn visual particle effects at positions or attached to entities.

SpawnParticleSystem Packet

Particles are spawned using the SpawnParticleSystem packet:

1SpawnParticleSystem packet = new SpawnParticleSystem(
2 "Poof_Large", // particle name
3 new Position(x, y, z), // spawn position
4 new Direction(0f, 0f, 0f), // direction/velocity
5 1.5f, // scale
6 new Color((byte)-1, (byte)-1, (byte)-1) // color (white)
7);
8
9player.getPlayerConnection().write(packet);
thread safe
Packet sending is thread-safe. No need for world.execute().

Common Particle Names

namedescription
Poof_LargeLarge puff of smoke/dust
Poof_SmallSmall puff effect
HeartsFloating hearts
SparkleShimmering sparkles
FireFire/flame particles
SmokeRising smoke
Water_SplashWater splash effect
ExplosionExplosion burst
finding particles
Explore the game files or server JAR to discover all available particle systems.

Color Parameter

The Color uses bytes (-128 to 127). For RGB values 0-255, cast them:

1// White (255, 255, 255)
2new Color((byte)-1, (byte)-1, (byte)-1)
3
4// Red (255, 0, 0)
5new Color((byte)-1, (byte)0, (byte)0)
6
7// Green (0, 255, 0)
8new Color((byte)0, (byte)-1, (byte)0)
9
10// Blue (0, 0, 255)
11new Color((byte)0, (byte)0, (byte)-1)
12
13// Custom color helper
14public static Color rgbColor(int r, int g, int b) {
15 return new Color((byte)(r - 128), (byte)(g - 128), (byte)(b - 128));
16}

Particle Helper

ParticleHelper.javajava
1public class ParticleHelper {
2
3 public static void spawn(World world, Position pos, String particle) {
4 spawn(world, pos, particle, 1.0f, Color.WHITE);
5 }
6
7 public static void spawn(World world, Position pos, String particle, float scale) {
8 spawn(world, pos, particle, scale, Color.WHITE);
9 }
10
11 public static void spawn(World world, Position pos, String particle, float scale, Color color) {
12 SpawnParticleSystem packet = new SpawnParticleSystem(
13 particle,
14 pos,
15 new Direction(0f, 0f, 0f),
16 scale,
17 color
18 );
19
20 // Broadcast to all players
21 for (Player player : world.getPlayers()) {
22 player.getPlayerConnection().write(packet);
23 }
24 }
25
26 public static void spawnAt(Player player, String particle) {
27 Position pos = getPlayerPosition(player);
28 spawn(player.getWorld(), pos, particle);
29 }
30
31 // Common presets
32 public static final Color WHITE = new Color((byte)-1, (byte)-1, (byte)-1);
33 public static final Color RED = new Color((byte)-1, (byte)0, (byte)0);
34 public static final Color GREEN = new Color((byte)0, (byte)-1, (byte)0);
35 public static final Color BLUE = new Color((byte)0, (byte)0, (byte)-1);
36}

Particle Effects

Spawn at Player

1private void spawnParticleAtPlayer(Player player, String particle) {
2 // Get player position
3 TransformComponent transform = getComponent(player, TransformComponent.class);
4 Position pos = transform.getPosition();
5
6 // Spawn slightly above player
7 Position spawnPos = new Position(pos.x(), pos.y() + 1.5, pos.z());
8
9 SpawnParticleSystem packet = new SpawnParticleSystem(
10 particle,
11 spawnPos,
12 new Direction(0f, 0f, 0f),
13 1.0f,
14 new Color((byte)-1, (byte)-1, (byte)-1)
15 );
16
17 // Send to all nearby players
18 for (Player p : player.getWorld().getPlayers()) {
19 p.getPlayerConnection().write(packet);
20 }
21}

Circle of Particles

1private void spawnParticleCircle(World world, Position center, String particle, float radius, int count) {
2 for (int i = 0; i < count; i++) {
3 double angle = 2 * Math.PI * i / count;
4 double x = center.x() + radius * Math.cos(angle);
5 double z = center.z() + radius * Math.sin(angle);
6
7 Position pos = new Position(x, center.y(), z);
8
9 SpawnParticleSystem packet = new SpawnParticleSystem(
10 particle,
11 pos,
12 new Direction(0f, 0f, 0f),
13 0.5f,
14 new Color((byte)-1, (byte)-1, (byte)-1)
15 );
16
17 for (Player p : world.getPlayers()) {
18 p.getPlayerConnection().write(packet);
19 }
20 }
21}

Timed Particle Burst

1private void particleBurst(Player player, String particle, int bursts, int tickDelay) {
2 World world = player.getWorld();
3 Position pos = getPlayerPosition(player);
4
5 world.execute(() -> {
6 for (int i = 0; i < bursts; i++) {
7 final int burst = i;
8 world.schedule(i * tickDelay, () -> {
9 // Spawn with increasing scale
10 float scale = 0.5f + (burst * 0.3f);
11 ParticleHelper.spawn(world, pos, particle, scale);
12 });
13 }
14 });
15}

Direction Parameter

The direction parameter can add velocity to particles:

1// Particles rising up
2new Direction(0f, 1f, 0f)
3
4// Particles spreading outward
5new Direction(0.5f, 0f, 0.5f)
6
7// No movement
8new Direction(0f, 0f, 0f)

Best Practices

do
Limit particle count per player to avoid client lag.
do
Only send particles to players within viewing distance.
avoid
Don't spawn hundreds of particles simultaneously - stagger them over ticks.