{"id":34676,"date":"2026-06-01T19:36:14","date_gmt":"2026-06-01T16:36:14","guid":{"rendered":"https:\/\/vpesports.com\/minecraft\/mods\/breath-weapon\/"},"modified":"2026-06-01T19:36:14","modified_gmt":"2026-06-01T16:36:14","slug":"breath-weapon","status":"publish","type":"mod","link":"https:\/\/vpesports.com\/minecraft\/mods\/breath-weapon\/","title":{"rendered":"Breath Weapon"},"content":{"rendered":"<p># Using BreathWeapon<\/p>\n<p>This guide explains how to integrate the BreathWeapon particle system into your Minecraft mod to create custom particles without writing complex rendering code.<\/p>\n<p>## Setup<\/p>\n<p>### 1. Add Dependency<\/p>\n<p>In your `build.gradle`, add BreathWeapon to your dependencies:<\/p>\n<p>&#8220;`gradle<br \/>\nmavenCentral()<br \/>\n    exclusiveContent {<br \/>\n        forRepository {<br \/>\n            maven {<br \/>\n                name = &#8220;Modrinth&#8221;<br \/>\n                url = &#8220;https:\/\/api.modrinth.com\/maven&#8221;<br \/>\n            }<br \/>\n        }<br \/>\n        forRepositories(fg.repository)<br \/>\n        filter {<br \/>\n            includeGroup &#8220;maven.modrinth&#8221;<br \/>\n        }<br \/>\n    }<\/p>\n<p>dependencies {<br \/>\n    implementation fg.deobf(&#8220;maven.modrinth:breath-weapon:0.0.1&#8221;)<br \/>\n}<br \/>\n&#8220;`<\/p>\n<p>### 2. Import the API<\/p>\n<p>In your code, import the spawning utilities:<\/p>\n<p>&#8220;`java<br \/>\nimport com.dracolich777.breathweapon.util.ParticleSpawner;<br \/>\nimport com.dracolich777.breathweapon.api.particle.ParticleRegistry;<br \/>\nimport net.minecraft.resources.ResourceLocation;<br \/>\n&#8220;`<\/p>\n<p>&#8212;<\/p>\n<p>## Quick Start<\/p>\n<p>### Minimal Setup<\/p>\n<p>**1. Create a particle definition JSON:**<\/p>\n<p>&#8220;`<br \/>\nsrc\/main\/resources\/data\/yourmodid\/particles\/my_effect.json<br \/>\n&#8220;`<\/p>\n<p>&#8220;`json<br \/>\n{<br \/>\n  &#8220;type&#8221;: &#8220;sprite&#8221;,<br \/>\n  &#8220;lifetime&#8221;: 50<br \/>\n}<br \/>\n&#8220;`<\/p>\n<p>**2. Spawn it in code:**<\/p>\n<p>&#8220;`java<br \/>\nParticleSpawner.spawn(level,<br \/>\n    new ResourceLocation(&#8220;yourmodid&#8221;, &#8220;my_effect&#8221;),<br \/>\n    x, y, z,<br \/>\n    vx, vy, vz);<br \/>\n&#8220;`<\/p>\n<p>That&#8217;s it! The particle will render with default texture and physics.<\/p>\n<p>&#8212;<\/p>\n<p>## Creating Particle Definitions<\/p>\n<p>Particle definitions are JSON files placed in your mod&#8217;s datapacks. Create them at:<\/p>\n<p>&#8220;`<br \/>\nsrc\/main\/resources\/data\/yourmodid\/particles\/particle_name.json<br \/>\n&#8220;`<\/p>\n<p>### File Structure<\/p>\n<p>&#8220;`<br \/>\nsrc\/main\/resources\/<br \/>\n\u251c\u2500\u2500 assets\/yourmodid\/<br \/>\n\u2502   \u2514\u2500\u2500 textures\/<br \/>\n\u2502       \u2514\u2500\u2500 particle\/<br \/>\n\u2502           \u251c\u2500\u2500 beam.png<br \/>\n\u2502           \u251c\u2500\u2500 spark.png<br \/>\n\u2502           \u2514\u2500\u2500 smoke.png<br \/>\n\u2514\u2500\u2500 data\/yourmodid\/<br \/>\n    \u2514\u2500\u2500 particles\/<br \/>\n        \u251c\u2500\u2500 my_beam.json<br \/>\n        \u251c\u2500\u2500 my_spark.json<br \/>\n        \u2514\u2500\u2500 my_smoke.json<br \/>\n&#8220;`<\/p>\n<p>### Basic JSON Structure<\/p>\n<p>Every particle definition has this structure:<\/p>\n<p>&#8220;`json<br \/>\n{<br \/>\n  &#8220;type&#8221;: &#8220;sprite | beam | geo&#8221;,<br \/>\n  &#8220;texture&#8221;: &#8220;yourmodid:textures\/particle\/name&#8221;,<br \/>\n  &#8220;lifetime&#8221;: 200,<br \/>\n  &#8220;scale&#8221;: 1.0,<br \/>\n  &#8220;gravity&#8221;: 0.0,<br \/>\n  &#8220;drag&#8221;: 1.0,<br \/>\n  &#8220;light&#8221;: { &#8230; },<br \/>\n  &#8220;animation&#8221;: { &#8230; }<br \/>\n}<br \/>\n&#8220;`<\/p>\n<p>### Common Properties<\/p>\n<p>All particle types support:<\/p>\n<p>| Property | Type | Default | Description |<br \/>\n|&#8212;&#8212;&#8212;-|&#8212;&#8212;|&#8212;&#8212;&#8212;|&#8212;&#8212;&#8212;&#8212;-|<br \/>\n| `type` | string | &#8220;sprite&#8221; | Particle type: sprite, beam, or geo |<br \/>\n| `lifetime` | int | 200 | Duration in ticks (1 tick = 50ms) |<br \/>\n| `scale` | float | 1.0 | Size multiplier (0.1 &#8211; 10.0) |<br \/>\n| `gravity` | float | 0.0 | Downward acceleration (negative = upward) |<br \/>\n| `drag` | float | 1.0 | Velocity damping (0.9 = 10% slowdown\/tick) |<br \/>\n| `texture` | string | null | Texture path in format `modid:path` |<\/p>\n<p>### Light Configuration<\/p>\n<p>Add glow\/dynamic lighting to particles:<\/p>\n<p>&#8220;`json<br \/>\n{<br \/>\n  &#8220;type&#8221;: &#8220;sprite&#8221;,<br \/>\n  &#8220;light&#8221;: {<br \/>\n    &#8220;mode&#8221;: &#8220;glow&#8221;,<br \/>\n    &#8220;color&#8221;: [1.0, 0.5, 0.0],<br \/>\n    &#8220;intensity&#8221;: 1.0<br \/>\n  }<br \/>\n}<br \/>\n&#8220;`<\/p>\n<p>**Light Modes:**<br \/>\n&#8211; `&#8221;none&#8221;` &#8211; No special lighting<br \/>\n&#8211; `&#8221;glow&#8221;` &#8211; Constant glow effect<br \/>\n&#8211; `&#8221;pulse&#8221;` &#8211; Pulsing brightness<\/p>\n<p>**For Glow\/Pulse:**<br \/>\n&#8220;`json<br \/>\n&#8220;light&#8221;: {<br \/>\n  &#8220;mode&#8221;: &#8220;glow&#8221;,<br \/>\n  &#8220;color&#8221;: [r, g, b],<br \/>\n  &#8220;intensity&#8221;: brightness_0_to_2<br \/>\n}<br \/>\n&#8220;`<\/p>\n<p>**For Pulse:**<br \/>\n&#8220;`json<br \/>\n&#8220;light&#8221;: {<br \/>\n  &#8220;mode&#8221;: &#8220;pulse&#8221;,<br \/>\n  &#8220;color&#8221;: [r, g, b],<br \/>\n  &#8220;intensity&#8221;: 1.0,<br \/>\n  &#8220;pulse_min&#8221;: 0.3,<br \/>\n  &#8220;pulse_max&#8221;: 1.0,<br \/>\n  &#8220;pulse_speed&#8221;: 0.1<br \/>\n}<br \/>\n&#8220;`<\/p>\n<p>&#8212;<\/p>\n<p>## Spawning Particles<\/p>\n<p>### Basic Spawning<\/p>\n<p>**Single particle:**<\/p>\n<p>&#8220;`java<br \/>\nParticleSpawner.spawn(level,<br \/>\n    new ResourceLocation(&#8220;yourmodid&#8221;, &#8220;my_particle&#8221;),<br \/>\n    x, y, z,<br \/>\n    velocityX, velocityY, velocityZ);<br \/>\n&#8220;`<\/p>\n<p>### Pattern Spawning<\/p>\n<p>**Burst (random directions):**<\/p>\n<p>&#8220;`java<br \/>\nParticleSpawner.burst(level,<br \/>\n    new ResourceLocation(&#8220;yourmodid&#8221;, &#8220;spark&#8221;),<br \/>\n    center,      \/\/ Vec3 position<br \/>\n    count,       \/\/ Number of particles (e.g., 10)<br \/>\n    speed);      \/\/ Speed in blocks\/tick (e.g., 0.5)<br \/>\n&#8220;`<\/p>\n<p>**Stream (directional):**<\/p>\n<p>&#8220;`java<br \/>\nParticleSpawner.stream(level,<br \/>\n    new ResourceLocation(&#8220;yourmodid&#8221;, &#8220;smoke&#8221;),<br \/>\n    entity,      \/\/ Entity to spawn from<br \/>\n    count,       \/\/ Number of particles<br \/>\n    speed,       \/\/ Particle speed<br \/>\n    spread);     \/\/ Angular spread in radians<br \/>\n&#8220;`<\/p>\n<p>### Beam Spawning<\/p>\n<p>**Uniform beam:**<\/p>\n<p>&#8220;`java<br \/>\nParticleSpawner.spawnBeam(level,<br \/>\n    new ResourceLocation(&#8220;yourmodid&#8221;, &#8220;laser&#8221;),<br \/>\n    from,        \/\/ Vec3 start position<br \/>\n    to,          \/\/ Vec3 end position<br \/>\n    width);      \/\/ Beam width (e.g., 0.3f)<br \/>\n&#8220;`<\/p>\n<p>**Tapered beam (width changes along length):**<\/p>\n<p>&#8220;`java<br \/>\nParticleSpawner.spawnBeam(level,<br \/>\n    new ResourceLocation(&#8220;yourmodid&#8221;, &#8220;laser&#8221;),<br \/>\n    from,           \/\/ Vec3 start<br \/>\n    to,             \/\/ Vec3 end<br \/>\n    startWidth,     \/\/ Width at start (e.g., 0.5f)<br \/>\n    endWidth);      \/\/ Width at end (e.g., 0.1f)<br \/>\n&#8220;`<\/p>\n<p>&#8212;<\/p>\n<p>## Particle Types<\/p>\n<p>### Type 1: Sprite (Default)<\/p>\n<p>Simple 2D particles. Fast and lightweight.<\/p>\n<p>**Definition:**<\/p>\n<p>&#8220;`json<br \/>\n{<br \/>\n  &#8220;type&#8221;: &#8220;sprite&#8221;,<br \/>\n  &#8220;texture&#8221;: &#8220;yourmodid:particle\/spark&#8221;,<br \/>\n  &#8220;lifetime&#8221;: 30,<br \/>\n  &#8220;scale&#8221;: 0.5,<br \/>\n  &#8220;gravity&#8221;: 0.05,<br \/>\n  &#8220;drag&#8221;: 0.98,<br \/>\n  &#8220;light&#8221;: {<br \/>\n    &#8220;mode&#8221;: &#8220;glow&#8221;,<br \/>\n    &#8220;color&#8221;: [1.0, 1.0, 0.0],<br \/>\n    &#8220;intensity&#8221;: 0.8<br \/>\n  }<br \/>\n}<br \/>\n&#8220;`<\/p>\n<p>**Best for:** Sparks, sparkles, dust, simple effects<\/p>\n<p>### Type 2: Beam<\/p>\n<p>Billboard between two points. Supports dynamic endpoints.<\/p>\n<p>**Definition:**<\/p>\n<p>&#8220;`json<br \/>\n{<br \/>\n  &#8220;type&#8221;: &#8220;beam&#8221;,<br \/>\n  &#8220;texture&#8221;: &#8220;yourmodid:particle\/laser&#8221;,<br \/>\n  &#8220;lifetime&#8221;: 100,<br \/>\n  &#8220;scale&#8221;: 1.0,<br \/>\n  &#8220;light&#8221;: {<br \/>\n    &#8220;mode&#8221;: &#8220;glow&#8221;,<br \/>\n    &#8220;color&#8221;: [1.0, 0.0, 0.0],<br \/>\n    &#8220;intensity&#8221;: 1.5<br \/>\n  }<br \/>\n}<br \/>\n&#8220;`<\/p>\n<p>**Best for:** Lasers, energy blasts, directed attacks, tracers<\/p>\n<p>### Type 3: Geo (GeckoLib Model)<\/p>\n<p>Full 3D models with animation support.<\/p>\n<p>**Definition:**<\/p>\n<p>&#8220;`json<br \/>\n{<br \/>\n  &#8220;type&#8221;: &#8220;geo&#8221;,<br \/>\n  &#8220;model&#8221;: &#8220;yourmodid:geo\/explosion.geo.json&#8221;,<br \/>\n  &#8220;texture&#8221;: &#8220;yourmodid:textures\/particle\/explosion.png&#8221;,<br \/>\n  &#8220;animation&#8221;: &#8220;yourmodid:animations\/explosion.animation.json&#8221;,<br \/>\n  &#8220;anim_name&#8221;: &#8220;animation.explosion.burst&#8221;,<br \/>\n  &#8220;lifetime&#8221;: 50,<br \/>\n  &#8220;scale&#8221;: 0.8,<br \/>\n  &#8220;gravity&#8221;: -0.05,<br \/>\n  &#8220;drag&#8221;: 0.95,<br \/>\n  &#8220;spin&#8221;: {<br \/>\n    &#8220;yaw&#8221;: 5.0,<br \/>\n    &#8220;pitch&#8221;: 2.0,<br \/>\n    &#8220;roll&#8221;: 3.0<br \/>\n  }<br \/>\n}<br \/>\n&#8220;`<\/p>\n<p>**Properties:**<br \/>\n&#8211; `model` &#8211; Path to your GeckoLib `.geo.json` file<br \/>\n&#8211; `texture` &#8211; Texture for the model<br \/>\n&#8211; `animation` &#8211; Path to animation file (optional)<br \/>\n&#8211; `anim_name` &#8211; Which animation to play (optional)<br \/>\n&#8211; `spin` &#8211; Rotation speed in degrees\/tick (optional)<\/p>\n<p>**Best for:** Complex effects, explosions, magical effects, custom models<\/p>\n<p>&#8212;<\/p>\n<p>## Advanced Features<\/p>\n<p>### Dynamic Beam Endpoints<\/p>\n<p>Make beams that track targets or move over time:<\/p>\n<p>&#8220;`java<br \/>\nimport com.dracolich777.breathweapon.client.particle.SimpleBeamParticle;<\/p>\n<p>\/\/ When spawning, you need to access the particle directly<br \/>\n\/\/ This requires a custom spawning approach or event listener<\/p>\n<p>SimpleBeamParticle.EndpointProvider provider = (age, lifetime) -> {<br \/>\n    \/\/ Calculate new position based on age<br \/>\n    float progress = age \/ (float) lifetime;<\/p>\n<p>    \/\/ Example: Spiral endpoint<br \/>\n    double angle = progress * Math.PI * 4; \/\/ 2 rotations<br \/>\n    double newX = centerX + Math.cos(angle) * radius;<br \/>\n    double newY = centerY + Math.sin(angle) * radius;<br \/>\n    double newZ = centerZ + Math.sin(progress * Math.PI) * 5;<\/p>\n<p>    return new SimpleBeamParticle.BeamEndpoint(newX, newY, newZ);<br \/>\n};<\/p>\n<p>\/\/ Set on particle (requires direct particle access via event or hook)<br \/>\nparticle.setEndpointProvider(provider);<br \/>\n&#8220;`<\/p>\n<p>### Physics Customization<\/p>\n<p>Control how particles move:<\/p>\n<p>&#8220;`json<br \/>\n{<br \/>\n  &#8220;gravity&#8221;: 0.1,      \/\/ Fall speed (positive = down, negative = up)<br \/>\n  &#8220;drag&#8221;: 0.95,        \/\/ Slow down by 5% each tick<br \/>\n  &#8220;scale&#8221;: 1.5         \/\/ Make it 1.5x bigger<br \/>\n}<br \/>\n&#8220;`<\/p>\n<p>**Examples:**<\/p>\n<p>&#8211; **Floating effect:** `&#8221;gravity&#8221;: -0.01, &#8220;drag&#8221;: 1.0`<br \/>\n&#8211; **Slow fall:** `&#8221;gravity&#8221;: 0.02, &#8220;drag&#8221;: 0.99`<br \/>\n&#8211; **Fading out:** Use short lifetime + high drag<br \/>\n&#8211; **Fast zoom:** Use high initial velocity + low gravity<\/p>\n<p>&#8212;<\/p>\n<p>## Complete Examples<\/p>\n<p>### Example 1: Energy Beam Attack<\/p>\n<p>**JSON Definition** (`data\/mymod\/particles\/energy_blast.json`):<\/p>\n<p>&#8220;`json<br \/>\n{<br \/>\n  &#8220;type&#8221;: &#8220;beam&#8221;,<br \/>\n  &#8220;texture&#8221;: &#8220;mymod:particle\/energy_beam&#8221;,<br \/>\n  &#8220;lifetime&#8221;: 80,<br \/>\n  &#8220;scale&#8221;: 0.9,<br \/>\n  &#8220;light&#8221;: {<br \/>\n    &#8220;mode&#8221;: &#8220;glow&#8221;,<br \/>\n    &#8220;color&#8221;: [0.2, 0.7, 1.0],<br \/>\n    &#8220;intensity&#8221;: 1.3<br \/>\n  }<br \/>\n}<br \/>\n&#8220;`<\/p>\n<p>**Spawning Code** (in an ability handler):<\/p>\n<p>&#8220;`java<br \/>\n@SubscribeEvent<br \/>\npublic static void onPlayerAttack(LivingAttackEvent event) {<br \/>\n    if (event.getEntity() instanceof Player player &#038;&#038;<br \/>\n        player.level() instanceof ServerLevel level) {<\/p>\n<p>        Vec3 from = player.getEyePosition();<br \/>\n        Vec3 to = from.add(player.getLookAngle().scale(50));<\/p>\n<p>        ParticleSpawner.spawnBeam(level,<br \/>\n            new ResourceLocation(&#8220;mymod&#8221;, &#8220;energy_blast&#8221;),<br \/>\n            from, to, 0.2f);<br \/>\n    }<br \/>\n}<br \/>\n&#8220;`<\/p>\n<p>### Example 2: Explosion Effect<\/p>\n<p>**JSON Definition** (`data\/mymod\/particles\/explosion_burst.json`):<\/p>\n<p>&#8220;`json<br \/>\n{<br \/>\n  &#8220;type&#8221;: &#8220;sprite&#8221;,<br \/>\n  &#8220;texture&#8221;: &#8220;mymod:particle\/explosion&#8221;,<br \/>\n  &#8220;lifetime&#8221;: 40,<br \/>\n  &#8220;scale&#8221;: 1.2,<br \/>\n  &#8220;gravity&#8221;: -0.02,<br \/>\n  &#8220;drag&#8221;: 0.96,<br \/>\n  &#8220;light&#8221;: {<br \/>\n    &#8220;mode&#8221;: &#8220;pulse&#8221;,<br \/>\n    &#8220;color&#8221;: [1.0, 0.6, 0.0],<br \/>\n    &#8220;intensity&#8221;: 1.5,<br \/>\n    &#8220;pulse_min&#8221;: 0.5,<br \/>\n    &#8220;pulse_max&#8221;: 1.5,<br \/>\n    &#8220;pulse_speed&#8221;: 0.15<br \/>\n  }<br \/>\n}<br \/>\n&#8220;`<\/p>\n<p>**Spawning Code**:<\/p>\n<p>&#8220;`java<br \/>\npublic static void createExplosion(ServerLevel level, Vec3 center, int power) {<br \/>\n    ParticleSpawner.burst(level,<br \/>\n        new ResourceLocation(&#8220;mymod&#8221;, &#8220;explosion_burst&#8221;),<br \/>\n        center,<br \/>\n        power * 3,  \/\/ More particles for bigger explosion<br \/>\n        power * 0.1);  \/\/ Faster spread for bigger explosion<br \/>\n}<br \/>\n&#8220;`<\/p>\n<p>### Example 3: Magical Aura<\/p>\n<p>**JSON Definition** (`data\/mymod\/particles\/mana_dust.json`):<\/p>\n<p>&#8220;`json<br \/>\n{<br \/>\n  &#8220;type&#8221;: &#8220;sprite&#8221;,<br \/>\n  &#8220;texture&#8221;: &#8220;mymod:particle\/mana&#8221;,<br \/>\n  &#8220;lifetime&#8221;: 100,<br \/>\n  &#8220;scale&#8221;: 0.6,<br \/>\n  &#8220;gravity&#8221;: -0.005,<br \/>\n  &#8220;drag&#8221;: 0.98,<br \/>\n  &#8220;light&#8221;: {<br \/>\n    &#8220;mode&#8221;: &#8220;glow&#8221;,<br \/>\n    &#8220;color&#8221;: [0.7, 0.3, 1.0],<br \/>\n    &#8220;intensity&#8221;: 0.9<br \/>\n  }<br \/>\n}<br \/>\n&#8220;`<\/p>\n<p>**Spawning Code** (in entity tick):<\/p>\n<p>&#8220;`java<br \/>\npublic void createManaAura(Entity entity, ServerLevel level) {<br \/>\n    Vec3 pos = entity.position().add(0, entity.getBbHeight() \/ 2, 0);<\/p>\n<p>    \/\/ Small burst of particles around entity<br \/>\n    ParticleSpawner.burst(level,<br \/>\n        new ResourceLocation(&#8220;mymod&#8221;, &#8220;mana_dust&#8221;),<br \/>\n        pos,<br \/>\n        5,        \/\/ 5 particles<br \/>\n        0.3);     \/\/ Slow spread<br \/>\n}<br \/>\n&#8220;`<\/p>\n<p>### Example 4: Status Effect Indicator<\/p>\n<p>**JSON Definition** (`data\/mymod\/particles\/poison_cloud.json`):<\/p>\n<p>&#8220;`json<br \/>\n{<br \/>\n  &#8220;type&#8221;: &#8220;sprite&#8221;,<br \/>\n  &#8220;texture&#8221;: &#8220;mymod:particle\/poison&#8221;,<br \/>\n  &#8220;lifetime&#8221;: 60,<br \/>\n  &#8220;scale&#8221;: 0.8,<br \/>\n  &#8220;gravity&#8221;: 0.01,<br \/>\n  &#8220;drag&#8221;: 0.99,<br \/>\n  &#8220;light&#8221;: {<br \/>\n    &#8220;mode&#8221;: &#8220;glow&#8221;,<br \/>\n    &#8220;color&#8221;: [0.3, 0.8, 0.2],<br \/>\n    &#8220;intensity&#8221;: 0.7<br \/>\n  }<br \/>\n}<br \/>\n&#8220;`<\/p>\n<p>**Spawning Code** (while effect active):<\/p>\n<p>&#8220;`java<br \/>\n@SubscribeEvent<br \/>\npublic static void onLivingUpdate(LivingTickEvent event) {<br \/>\n    LivingEntity entity = event.getEntity();<\/p>\n<p>    if (entity.hasEffect(MobEffects.POISON) &#038;&#038;<br \/>\n        entity.level() instanceof ServerLevel level &#038;&#038;<br \/>\n        entity.tickCount % 5 == 0) {  \/\/ Every 5 ticks<\/p>\n<p>        Vec3 pos = entity.position().add(<br \/>\n            (Math.random() &#8211; 0.5) * 0.5,<br \/>\n            Math.random() * entity.getBbHeight(),<br \/>\n            (Math.random() &#8211; 0.5) * 0.5<br \/>\n        );<\/p>\n<p>        ParticleSpawner.spawn(level,<br \/>\n            new ResourceLocation(&#8220;mymod&#8221;, &#8220;poison_cloud&#8221;),<br \/>\n            pos.x, pos.y, pos.z,<br \/>\n            0, -0.05, 0);  \/\/ Slight upward drift<br \/>\n    }<br \/>\n}<br \/>\n&#8220;`<\/p>\n<p>&#8212;<\/p>\n<p>## Checking Particle Availability<\/p>\n<p>Before spawning, verify the particle is registered:<\/p>\n<p>&#8220;`java<br \/>\nimport com.dracolich777.breathweapon.api.particle.ParticleRegistry;<\/p>\n<p>ResourceLocation particleId = new ResourceLocation(&#8220;yourmodid&#8221;, &#8220;my_particle&#8221;);<\/p>\n<p>if (ParticleRegistry.has(particleId)) {<br \/>\n    \/\/ Safe to spawn<br \/>\n    ParticleSpawner.spawn(level, particleId, x, y, z, 0, 0, 0);<br \/>\n} else {<br \/>\n    LOGGER.warn(&#8220;Particle not found: {}&#8221;, particleId);<br \/>\n}<br \/>\n&#8220;`<\/p>\n<p>Get particle info:<\/p>\n<p>&#8220;`java<br \/>\nvar definition = ParticleRegistry.get(&#8220;yourmodid:my_particle&#8221;);<br \/>\nif (definition != null) {<br \/>\n    int lifetime = definition.getLifetime();<br \/>\n    float scale = definition.getScale();<br \/>\n    String type = definition.getType();  \/\/ &#8220;beam&#8221;, &#8220;geo&#8221;, &#8220;sprite&#8221;<br \/>\n}<br \/>\n&#8220;`<\/p>\n<p>&#8212;<\/p>\n<p>## Best Practices<\/p>\n<p>### 1. Organize Your Particles<\/p>\n<p>&#8220;`<br \/>\ndata\/yourmodid\/particles\/<br \/>\n\u251c\u2500\u2500 abilities\/<br \/>\n\u2502   \u251c\u2500\u2500 fireball.json<br \/>\n\u2502   \u251c\u2500\u2500 lightning.json<br \/>\n\u2502   \u2514\u2500\u2500 healing_circle.json<br \/>\n\u251c\u2500\u2500 effects\/<br \/>\n\u2502   \u251c\u2500\u2500 hit_effect.json<br \/>\n\u2502   \u251c\u2500\u2500 death_burst.json<br \/>\n\u2502   \u2514\u2500\u2500 buff_indicator.json<br \/>\n\u2514\u2500\u2500 ambient\/<br \/>\n    \u251c\u2500\u2500 magical_dust.json<br \/>\n    \u251c\u2500\u2500 fire_embers.json<br \/>\n    \u2514\u2500\u2500 water_splash.json<br \/>\n&#8220;`<\/p>\n<p>### 2. Keep Lifetimes Short<\/p>\n<p>Don&#8217;t make particles last longer than needed:<br \/>\n&#8211; Sparks: 20-60 ticks<br \/>\n&#8211; Beams: 50-150 ticks<br \/>\n&#8211; Explosions: 30-100 ticks<br \/>\n&#8211; Ambient: 60-200 ticks<\/p>\n<p>### 3. Test Physics<\/p>\n<p>&#8220;`json<br \/>\n{<br \/>\n  &#8220;gravity&#8221;: 0.0,    \/\/ Start with no gravity<br \/>\n  &#8220;drag&#8221;: 1.0        \/\/ Start with no drag<br \/>\n}<br \/>\n&#8220;`<\/p>\n<p>Then adjust based on visual appearance.<\/p>\n<p>### 4. Use Appropriate Types<\/p>\n<p>&#8211; **Sprite** &#8211; Most effects (fast)<br \/>\n&#8211; **Beam** &#8211; Targeted effects, attacks<br \/>\n&#8211; **Geo** &#8211; Special occasions (slower)<\/p>\n<p>### 5. Reuse Definitions<\/p>\n<p>Create one definition and spawn it multiple times:<\/p>\n<p>&#8220;`java<br \/>\nfor (int i = 0; i < 10; i++) {\n    ParticleSpawner.spawn(level,\n        new ResourceLocation(\"mymod\", \"explosion\"),\n        x, y, z,\n        randomVelX, randomVelY, randomVelZ);\n}\n```\n\n### 6. Add Descriptions to JSONs\n\n```json\n{\n  \"_comment\": \"Blue energy beam - used for mage spell attacks\",\n  \"type\": \"beam\",\n  ...\n}\n```\n\n---\n\n## Troubleshooting\n\n### Particles Not Showing\n\n**Problem:** I spawned a particle but it doesn't appear in-game.\n\n**Solutions:**\n1. Check particle definition is in correct folder: `data\/yourmodid\/particles\/name.json`\n2. Verify the particle ID matches the JSON filename\n3. Use `\/reload` to reload data\n4. Check texture path exists: `assets\/yourmodid\/textures\/particle\/name.png`\n5. Verify you're on the correct level (ServerLevel, not ClientLevel)\n\n**Debug code:**\n```java\nvar def = ParticleRegistry.get(\"yourmodid:my_particle\");\nif (def == null) {\n    LOGGER.error(\"Particle not found in registry!\");\n} else {\n    LOGGER.info(\"Particle found: {}\", def);\n}\n```\n\n### Texture Not Loading\n\n**Problem:** Particle appears but texture is wrong.\n\n**Solutions:**\n1. Verify texture path uses forward slashes: `\"mymod:particle\/name\"`\n2. Check texture file is PNG format\n3. Texture path should NOT include `.png` extension\n4. Texture should be in `assets\/yourmodid\/textures\/`\n\n### Beam Position Wrong\n\n**Problem:** Beam starts\/ends at wrong position.\n\n**Solutions:**\n1. Use world space coordinates (not relative)\n2. For entities: `entity.getEyePosition()` for eye level\n3. For blocks: `new Vec3(x + 0.5, y + 0.5, z + 0.5)` for center\n4. Verify `from` and `to` are not the same position\n\n### Particle Too Slow\/Fast\n\n**Problem:** Particle movement doesn't match expected velocity.\n\n**Solutions:**\n1. Increase `speed` parameter in `burst()` or `stream()`\n2. Adjust `drag` - lower values = keeps velocity longer\n3. Check particle spawn velocity is correct\n4. Use `gravity` to add momentum over time\n\n### GeckoLib Model Not Loading\n\n**Problem:** Type is \"geo\" but model doesn't render.\n\n**Solutions:**\n1. Verify model file path is correct\n2. Check `.geo.json` file exists\n3. Model path should NOT include `.geo.json` in JSON (just `path` without extension)\n4. Texture path must match model's texture reference\n5. Animation name must match exactly (case-sensitive)\n\n---\n\n## API Reference\n\n### ParticleSpawner Methods\n\n```java\n\/\/ Single particle\nParticleSpawner.spawn(level, id, x, y, z, vx, vy, vz);\nParticleSpawner.spawn(level, id, x, y, z, vx, vy, vz, extraData);\n\n\/\/ Patterns\nParticleSpawner.burst(level, id, center, count, speed);\nParticleSpawner.stream(level, id, entity, count, speed, spread);\n\n\/\/ Beams\nParticleSpawner.spawnBeam(level, id, from, to, width);\nParticleSpawner.spawnBeam(level, id, from, to, startWidth, endWidth);\n```\n\n### ParticleRegistry Methods\n\n```java\nParticleRegistry.register(id, definition);\nParticleRegistry.get(id);\nParticleRegistry.has(id);\nParticleRegistry.getAll();\nParticleRegistry.getAllFromMod(namespace);\n```\n\n---\n\n## Need Help?\n\n- DM me on discord or join my discord server:\n  - Discord Server\n  - `.themrsuit`\n\nGood luck creating amazing particles!\n<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is a library\/api mod to render geckolib models as particles<\/p>\n","protected":false},"featured_media":34677,"template":"","meta":{"_minecraft_slug":"breath-weapon","_minecraft_project_id":"DgX86wMm","_minecraft_author":"TheMrSuit","_minecraft_license":"MIT","_minecraft_downloads":45,"_minecraft_follows":1,"_minecraft_client_side":"required","_minecraft_server_side":"required","_minecraft_storage_type":"zip","_minecraft_archive_name":"breath-weapon.zip","_minecraft_size_bytes":5223667,"_minecraft_version_count":9,"_minecraft_updated_at":"2026-05-16T12:40:17.485702Z","_minecraft_date_created":"2026-05-11T16:50:58.688718Z","_minecraft_date_modified":"2026-05-13T18:31:17.934223Z","_minecraft_project_url":"https:\/\/modrinth.com\/mod\/breath-weapon","_minecraft_icon_attachment_id":34677,"_minecraft_imported_at":"2026-06-01T16:36:15+00:00","_minecraft_import_hash":"78f035cdfa112ce05684ee85a77d6cca","_minecraft_versions":"","_minecraft_links":"","_minecraft_gallery":"","_minecraft_api_metadata":""},"mod_category":[104,873],"mod_loader":[106],"minecraft_version":[36],"class_list":["post-34676","mod","type-mod","status-publish","has-post-thumbnail","hentry","mod_category-forge","mod_category-library","mod_loader-forge","minecraft_version-1-20-1"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Breath Weapon - Minecraft<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/vpesports.com\/minecraft\/mods\/breath-weapon\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Breath Weapon - Minecraft\" \/>\n<meta property=\"og:description\" content=\"This is a library\/api mod to render geckolib models as particles\" \/>\n<meta property=\"og:url\" content=\"https:\/\/vpesports.com\/minecraft\/mods\/breath-weapon\/\" \/>\n<meta property=\"og:site_name\" content=\"Minecraft\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/mods\\\/breath-weapon\\\/\",\"url\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/mods\\\/breath-weapon\\\/\",\"name\":\"Breath Weapon - Minecraft\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/mods\\\/breath-weapon\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/mods\\\/breath-weapon\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/breath-weapon-icon-447c5b9f8e3be3a6ba6d5fa2632a7373c415640f.png\",\"datePublished\":\"2026-06-01T16:36:14+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/mods\\\/breath-weapon\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/mods\\\/breath-weapon\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/mods\\\/breath-weapon\\\/#primaryimage\",\"url\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/breath-weapon-icon-447c5b9f8e3be3a6ba6d5fa2632a7373c415640f.png\",\"contentUrl\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/breath-weapon-icon-447c5b9f8e3be3a6ba6d5fa2632a7373c415640f.png\",\"width\":16,\"height\":16},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/mods\\\/breath-weapon\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Mods\",\"item\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/mods\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Breath Weapon\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/#website\",\"url\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/\",\"name\":\"Minecraft\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Breath Weapon - Minecraft","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/vpesports.com\/minecraft\/mods\/breath-weapon\/","og_locale":"en_US","og_type":"article","og_title":"Breath Weapon - Minecraft","og_description":"This is a library\/api mod to render geckolib models as particles","og_url":"https:\/\/vpesports.com\/minecraft\/mods\/breath-weapon\/","og_site_name":"Minecraft","twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/vpesports.com\/minecraft\/mods\/breath-weapon\/","url":"https:\/\/vpesports.com\/minecraft\/mods\/breath-weapon\/","name":"Breath Weapon - Minecraft","isPartOf":{"@id":"https:\/\/vpesports.com\/minecraft\/#website"},"primaryImageOfPage":{"@id":"https:\/\/vpesports.com\/minecraft\/mods\/breath-weapon\/#primaryimage"},"image":{"@id":"https:\/\/vpesports.com\/minecraft\/mods\/breath-weapon\/#primaryimage"},"thumbnailUrl":"https:\/\/vpesports.com\/minecraft\/wp-content\/uploads\/2026\/06\/breath-weapon-icon-447c5b9f8e3be3a6ba6d5fa2632a7373c415640f.png","datePublished":"2026-06-01T16:36:14+00:00","breadcrumb":{"@id":"https:\/\/vpesports.com\/minecraft\/mods\/breath-weapon\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/vpesports.com\/minecraft\/mods\/breath-weapon\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/vpesports.com\/minecraft\/mods\/breath-weapon\/#primaryimage","url":"https:\/\/vpesports.com\/minecraft\/wp-content\/uploads\/2026\/06\/breath-weapon-icon-447c5b9f8e3be3a6ba6d5fa2632a7373c415640f.png","contentUrl":"https:\/\/vpesports.com\/minecraft\/wp-content\/uploads\/2026\/06\/breath-weapon-icon-447c5b9f8e3be3a6ba6d5fa2632a7373c415640f.png","width":16,"height":16},{"@type":"BreadcrumbList","@id":"https:\/\/vpesports.com\/minecraft\/mods\/breath-weapon\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/vpesports.com\/minecraft\/"},{"@type":"ListItem","position":2,"name":"Mods","item":"https:\/\/vpesports.com\/minecraft\/mods\/"},{"@type":"ListItem","position":3,"name":"Breath Weapon"}]},{"@type":"WebSite","@id":"https:\/\/vpesports.com\/minecraft\/#website","url":"https:\/\/vpesports.com\/minecraft\/","name":"Minecraft","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/vpesports.com\/minecraft\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"}]}},"_links":{"self":[{"href":"https:\/\/vpesports.com\/minecraft\/wp-json\/wp\/v2\/mod\/34676","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vpesports.com\/minecraft\/wp-json\/wp\/v2\/mod"}],"about":[{"href":"https:\/\/vpesports.com\/minecraft\/wp-json\/wp\/v2\/types\/mod"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/vpesports.com\/minecraft\/wp-json\/wp\/v2\/media\/34677"}],"wp:attachment":[{"href":"https:\/\/vpesports.com\/minecraft\/wp-json\/wp\/v2\/media?parent=34676"}],"wp:term":[{"taxonomy":"mod_category","embeddable":true,"href":"https:\/\/vpesports.com\/minecraft\/wp-json\/wp\/v2\/mod_category?post=34676"},{"taxonomy":"mod_loader","embeddable":true,"href":"https:\/\/vpesports.com\/minecraft\/wp-json\/wp\/v2\/mod_loader?post=34676"},{"taxonomy":"minecraft_version","embeddable":true,"href":"https:\/\/vpesports.com\/minecraft\/wp-json\/wp\/v2\/minecraft_version?post=34676"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}