Developer API
Plugins can play any ParticleForge effect, or build one in code. Add softdepend: [ParticleForge] to your plugin.yml.
Fluent API
import com.ttsstudio.particleforge.api.Effects;
import com.ttsstudio.particleforge.api.EffectHandle;
EffectHandle h = Effects.burst()
.at(player.getLocation())
.particle("FLAME")
.count(64)
.speed(0.7)
.duration(10)
.play();
// Later
if (h.isActive()) h.cancel();
For pre-registered effects (loaded from YAML), use Effects.named(...):
Effects.named("crate/legendary-win")
.at(crateLocation)
.param("color", "#ffaa00")
.play();
Turn and move an effect
Effects are built pointing up. Point one along an axis, tilt and turn it by degrees, or shift it by blocks, on either builder:
Effects.named("teleport/portal-arcano")
.at(wallLocation)
.axis("+z") // +x -x +y -y +z -z, or east/west/up/down/south/north
.offset(0, 1, 0) // blocks along the world axes, applied after turning
.spin(30) // keep turning around the vertical, degrees per second
.play();
Effects.helix()
.at(loc)
.rotate(90, player.getLocation().getYaw()) // pitch, then yaw (Minecraft's yaw)
.play();
rotate(pitch, yaw) tilts by pitch (90 lays the effect down pointing south, 180 flips it) and then turns by yaw around the vertical, counted like a player's yaw. EffectTransform.facing(playerPitch, playerYaw) builds the rotation that points where a player looks. The service object takes the same thing as a last argument: pf.play(name, at, overrides, viewers, owner, follow, transform). The turn and move apply to every step of the effect, so bundled and hand-written effects behave the same.
Service lookup
When your plugin soft-depends on ParticleForge, fetch the API service from Bukkit:
RegisteredServiceProvider<ParticleForgeApi> rsp =
Bukkit.getServicesManager().getRegistration(ParticleForgeApi.class);
if (rsp != null) {
ParticleForgeApi pf = rsp.getProvider();
pf.play("crate/legendary-win", location);
}
Integration snippet
package your.plugin.integration;
import com.ttsstudio.particleforge.api.EffectHandle;
import com.ttsstudio.particleforge.api.ParticleForgeApi;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;
public final class ParticleForgeHook {
private final JavaPlugin owner;
private volatile ParticleForgeApi api;
public ParticleForgeHook(JavaPlugin owner) { this.owner = owner; }
public boolean isAvailable() {
if (api != null) return true;
if (!Bukkit.getPluginManager().isPluginEnabled("ParticleForge")) return false;
RegisteredServiceProvider<ParticleForgeApi> rsp =
Bukkit.getServicesManager().getRegistration(ParticleForgeApi.class);
if (rsp == null) return false;
this.api = rsp.getProvider();
return api != null;
}
public EffectHandle play(String effect, Location at) {
return isAvailable() ? api.play(effect, at) : null;
}
}
Don't forget softdepend: [ParticleForge] in your plugin.yml, and gate runtime access with isPluginEnabled("ParticleForge") — not getPlugin() != null — so disabled plugins don't trip you up.