MonitoringMinecraft MonitoringMinecraft

Breath Weapon

Мод Forge

Библиотека-API для Майнкрафт, позволяющая рендерить модели geckolib как частицы.

59 скачиваний 1 подписчик
Оцените первым

Using BreathWeapon

This guide explains how to integrate the BreathWeapon particle system into your Minecraft mod to create custom particles without writing complex rendering code.

Setup

1. Add Dependency

In your build.gradle, add BreathWeapon to your dependencies:

mavenCentral()
    exclusiveContent {
        forRepository {
            maven {
                name = "Modrinth"
                url = "https://api.modrinth.com/maven"
            }
        }
        forRepositories(fg.repository)
        filter {
            includeGroup "maven.modrinth"
        }
    }

dependencies {
    implementation fg.deobf("maven.modrinth:breath-weapon:0.0.1")
}

2. Import the API

In your code, import the spawning utilities:

import com.dracolich777.breathweapon.util.ParticleSpawner;
import com.dracolich777.breathweapon.api.particle.ParticleRegistry;
import net.minecraft.resources.ResourceLocation;

Quick Start

Minimal Setup

1. Create a particle definition JSON:

src/main/resources/data/yourmodid/particles/my_effect.json
{
  "type": "sprite",
  "lifetime": 50
}

2. Spawn it in code:

ParticleSpawner.spawn(level,
    new ResourceLocation("yourmodid", "my_effect"),
    x, y, z,
    vx, vy, vz);

That's it! The particle will render with default texture and physics.


Creating Particle Definitions

Particle definitions are JSON files placed in your mod's datapacks. Create them at:

src/main/resources/data/yourmodid/particles/particle_name.json

File Structure

src/main/resources/
├── assets/yourmodid/
│   └── textures/
│       └── particle/
│           ├── beam.png
│           ├── spark.png
│           └── smoke.png
└── data/yourmodid/
    └── particles/
        ├── my_beam.json
        ├── my_spark.json
        └── my_smoke.json

Basic JSON Structure

Every particle definition has this structure:

{
  "type": "sprite | beam | geo",
  "texture": "yourmodid:textures/particle/name",
  "lifetime": 200,
  "scale": 1.0,
  "gravity": 0.0,
  "drag": 1.0,
  "light": { ... },
  "animation": { ... }
}

Common Properties

All particle types support:

Property Type Default Description
type string "sprite" Particle type: sprite, beam, or geo
lifetime int 200 Duration in ticks (1 tick = 50ms)
scale float 1.0 Size multiplier (0.1 - 10.0)
gravity float 0.0 Downward acceleration (negative = upward)
drag float 1.0 Velocity damping (0.9 = 10% slowdown/tick)
texture string null Texture path in format modid:path

Light Configuration

Add glow/dynamic lighting to particles:

{
  "type": "sprite",
  "light": {
    "mode": "glow",
    "color": [1.0, 0.5, 0.0],
    "intensity": 1.0
  }
}

Light Modes:

  • "none" - No special lighting
  • "glow" - Constant glow effect
  • "pulse" - Pulsing brightness

For Glow/Pulse:

"light": {
  "mode": "glow",
  "color": [r, g, b],
  "intensity": brightness_0_to_2
}

For Pulse:

"light": {
  "mode": "pulse",
  "color": [r, g, b],
  "intensity": 1.0,
  "pulse_min": 0.3,
  "pulse_max": 1.0,
  "pulse_speed": 0.1
}

Spawning Particles

Basic Spawning

Single particle:

ParticleSpawner.spawn(level,
    new ResourceLocation("yourmodid", "my_particle"),
    x, y, z,
    velocityX, velocityY, velocityZ);

Pattern Spawning

Burst (random directions):

ParticleSpawner.burst(level,
    new ResourceLocation("yourmodid", "spark"),
    center,      // Vec3 position
    count,       // Number of particles (e.g., 10)
    speed);      // Speed in blocks/tick (e.g., 0.5)

Stream (directional):

ParticleSpawner.stream(level,
    new ResourceLocation("yourmodid", "smoke"),
    entity,      // Entity to spawn from
    count,       // Number of particles
    speed,       // Particle speed
    spread);     // Angular spread in radians

Beam Spawning

Uniform beam:

ParticleSpawner.spawnBeam(level,
    new ResourceLocation("yourmodid", "laser"),
    from,        // Vec3 start position
    to,          // Vec3 end position
    width);      // Beam width (e.g., 0.3f)

Tapered beam (width changes along length):

ParticleSpawner.spawnBeam(level,
    new ResourceLocation("yourmodid", "laser"),
    from,           // Vec3 start
    to,             // Vec3 end
    startWidth,     // Width at start (e.g., 0.5f)
    endWidth);      // Width at end (e.g., 0.1f)

Particle Types

Type 1: Sprite (Default)

Simple 2D particles. Fast and lightweight.

Definition:

{
  "type": "sprite",
  "texture": "yourmodid:particle/spark",
  "lifetime": 30,
  "scale": 0.5,
  "gravity": 0.05,
  "drag": 0.98,
  "light": {
    "mode": "glow",
    "color": [1.0, 1.0, 0.0],
    "intensity": 0.8
  }
}

Best for: Sparks, sparkles, dust, simple effects

Type 2: Beam

Billboard between two points. Supports dynamic endpoints.

Definition:

{
  "type": "beam",
  "texture": "yourmodid:particle/laser",
  "lifetime": 100,
  "scale": 1.0,
  "light": {
    "mode": "glow",
    "color": [1.0, 0.0, 0.0],
    "intensity": 1.5
  }
}

Best for: Lasers, energy blasts, directed attacks, tracers

Type 3: Geo (GeckoLib Model)

Full 3D models with animation support.

Definition:

{
  "type": "geo",
  "model": "yourmodid:geo/explosion.geo.json",
  "texture": "yourmodid:textures/particle/explosion.png",
  "animation": "yourmodid:animations/explosion.animation.json",
  "anim_name": "animation.explosion.burst",
  "lifetime": 50,
  "scale": 0.8,
  "gravity": -0.05,
  "drag": 0.95,
  "spin": {
    "yaw": 5.0,
    "pitch": 2.0,
    "roll": 3.0
  }
}

Properties:

  • model - Path to your GeckoLib .geo.json file
  • texture - Texture for the model
  • animation - Path to animation file (optional)
  • anim_name - Which animation to play (optional)
  • spin - Rotation speed in degrees/tick (optional)

Best for: Complex effects, explosions, magical effects, custom models


Advanced Features

Dynamic Beam Endpoints

Make beams that track targets or move over time:

import com.dracolich777.breathweapon.client.particle.SimpleBeamParticle;

// When spawning, you need to access the particle directly
// This requires a custom spawning approach or event listener

SimpleBeamParticle.EndpointProvider provider = (age, lifetime) -> {
    // Calculate new position based on age
    float progress = age / (float) lifetime;
    
    // Example: Spiral endpoint
    double angle = progress * Math.PI * 4; // 2 rotations
    double newX = centerX + Math.cos(angle) * radius;
    double newY = centerY + Math.sin(angle) * radius;
    double newZ = centerZ + Math.sin(progress * Math.PI) * 5;
    
    return new SimpleBeamParticle.BeamEndpoint(newX, newY, newZ);
};

// Set on particle (requires direct particle access via event or hook)
particle.setEndpointProvider(provider);

Physics Customization

Control how particles move:

{
  "gravity": 0.1,      // Fall speed (positive = down, negative = up)
  "drag": 0.95,        // Slow down by 5% each tick
  "scale": 1.5         // Make it 1.5x bigger
}

Examples:

  • Floating effect: "gravity": -0.01, "drag": 1.0
  • Slow fall: "gravity": 0.02, "drag": 0.99
  • Fading out: Use short lifetime + high drag
  • Fast zoom: Use high initial velocity + low gravity

Complete Examples

Example 1: Energy Beam Attack

JSON Definition (data/mymod/particles/energy_blast.json):

{
  "type": "beam",
  "texture": "mymod:particle/energy_beam",
  "lifetime": 80,
  "scale": 0.9,
  "light": {
    "mode": "glow",
    "color": [0.2, 0.7, 1.0],
    "intensity": 1.3
  }
}

Spawning Code (in an ability handler):

@SubscribeEvent
public static void onPlayerAttack(LivingAttackEvent event) {
    if (event.getEntity() instanceof Player player &&
        player.level() instanceof ServerLevel level) {
        
        Vec3 from = player.getEyePosition();
        Vec3 to = from.add(player.getLookAngle().scale(50));
        
        ParticleSpawner.spawnBeam(level,
            new ResourceLocation("mymod", "energy_blast"),
            from, to, 0.2f);
    }
}

Example 2: Explosion Effect

JSON Definition (data/mymod/particles/explosion_burst.json):

{
  "type": "sprite",
  "texture": "mymod:particle/explosion",
  "lifetime": 40,
  "scale": 1.2,
  "gravity": -0.02,
  "drag": 0.96,
  "light": {
    "mode": "pulse",
    "color": [1.0, 0.6, 0.0],
    "intensity": 1.5,
    "pulse_min": 0.5,
    "pulse_max": 1.5,
    "pulse_speed": 0.15
  }
}

Spawning Code:

public static void createExplosion(ServerLevel level, Vec3 center, int power) {
    ParticleSpawner.burst(level,
        new ResourceLocation("mymod", "explosion_burst"),
        center,
        power * 3,  // More particles for bigger explosion
        power * 0.1);  // Faster spread for bigger explosion
}

Example 3: Magical Aura

JSON Definition (data/mymod/particles/mana_dust.json):

{
  "type": "sprite",
  "texture": "mymod:particle/mana",
  "lifetime": 100,
  "scale": 0.6,
  "gravity": -0.005,
  "drag": 0.98,
  "light": {
    "mode": "glow",
    "color": [0.7, 0.3, 1.0],
    "intensity": 0.9
  }
}

Spawning Code (in entity tick):

public void createManaAura(Entity entity, ServerLevel level) {
    Vec3 pos = entity.position().add(0, entity.getBbHeight() / 2, 0);
    
    // Small burst of particles around entity
    ParticleSpawner.burst(level,
        new ResourceLocation("mymod", "mana_dust"),
        pos,
        5,        // 5 particles
        0.3);     // Slow spread
}

Example 4: Status Effect Indicator

JSON Definition (data/mymod/particles/poison_cloud.json):

{
  "type": "sprite",
  "texture": "mymod:particle/poison",
  "lifetime": 60,
  "scale": 0.8,
  "gravity": 0.01,
  "drag": 0.99,
  "light": {
    "mode": "glow",
    "color": [0.3, 0.8, 0.2],
    "intensity": 0.7
  }
}

Spawning Code (while effect active):

@SubscribeEvent
public static void onLivingUpdate(LivingTickEvent event) {
    LivingEntity entity = event.getEntity();
    
    if (entity.hasEffect(MobEffects.POISON) && 
        entity.level() instanceof ServerLevel level &&
        entity.tickCount % 5 == 0) {  // Every 5 ticks
        
        Vec3 pos = entity.position().add(
            (Math.random() - 0.5) * 0.5,
            Math.random() * entity.getBbHeight(),
            (Math.random() - 0.5) * 0.5
        );
        
        ParticleSpawner.spawn(level,
            new ResourceLocation("mymod", "poison_cloud"),
            pos.x, pos.y, pos.z,
            0, -0.05, 0);  // Slight upward drift
    }
}

Checking Particle Availability

Before spawning, verify the particle is registered:

import com.dracolich777.breathweapon.api.particle.ParticleRegistry;

ResourceLocation particleId = new ResourceLocation("yourmodid", "my_particle");

if (ParticleRegistry.has(particleId)) {
    // Safe to spawn
    ParticleSpawner.spawn(level, particleId, x, y, z, 0, 0, 0);
} else {
    LOGGER.warn("Particle not found: {}", particleId);
}

Get particle info:

var definition = ParticleRegistry.get("yourmodid:my_particle");
if (definition != null) {
    int lifetime = definition.getLifetime();
    float scale = definition.getScale();
    String type = definition.getType();  // "beam", "geo", "sprite"
}

Best Practices

1. Organize Your Particles

data/yourmodid/particles/
├── abilities/
│   ├── fireball.json
│   ├── lightning.json
│   └── healing_circle.json
├── effects/
│   ├── hit_effect.json
│   ├── death_burst.json
│   └── buff_indicator.json
└── ambient/
    ├── magical_dust.json
    ├── fire_embers.json
    └── water_splash.json

2. Keep Lifetimes Short

Don't make particles last longer than needed:

  • Sparks: 20-60 ticks
  • Beams: 50-150 ticks
  • Explosions: 30-100 ticks
  • Ambient: 60-200 ticks

3. Test Physics

{
  "gravity": 0.0,    // Start with no gravity
  "drag": 1.0        // Start with no drag
}

Then adjust based on visual appearance.

4. Use Appropriate Types

  • Sprite - Most effects (fast)
  • Beam - Targeted effects, attacks
  • Geo - Special occasions (slower)

5. Reuse Definitions

Create one definition and spawn it multiple times:

for (int i = 0; i < 10; i++) {
    ParticleSpawner.spawn(level,
        new ResourceLocation("mymod", "explosion"),
        x, y, z,
        randomVelX, randomVelY, randomVelZ);
}

6. Add Descriptions to JSONs

{
  "_comment": "Blue energy beam - used for mage spell attacks",
  "type": "beam",
  ...
}

Troubleshooting

Particles Not Showing

Problem: I spawned a particle but it doesn't appear in-game.

Solutions:

  1. Check particle definition is in correct folder: data/yourmodid/particles/name.json
  2. Verify the particle ID matches the JSON filename
  3. Use /reload to reload data
  4. Check texture path exists: assets/yourmodid/textures/particle/name.png
  5. Verify you're on the correct level (ServerLevel, not ClientLevel)

Debug code:

var def = ParticleRegistry.get("yourmodid:my_particle");
if (def == null) {
    LOGGER.error("Particle not found in registry!");
} else {
    LOGGER.info("Particle found: {}", def);
}

Texture Not Loading

Problem: Particle appears but texture is wrong.

Solutions:

  1. Verify texture path uses forward slashes: "mymod:particle/name"
  2. Check texture file is PNG format
  3. Texture path should NOT include .png extension
  4. Texture should be in assets/yourmodid/textures/

Beam Position Wrong

Problem: Beam starts/ends at wrong position.

Solutions:

  1. Use world space coordinates (not relative)
  2. For entities: entity.getEyePosition() for eye level
  3. For blocks: new Vec3(x + 0.5, y + 0.5, z + 0.5) for center
  4. Verify from and to are not the same position

Particle Too Slow/Fast

Problem: Particle movement doesn't match expected velocity.

Solutions:

  1. Increase speed parameter in burst() or stream()
  2. Adjust drag - lower values = keeps velocity longer
  3. Check particle spawn velocity is correct
  4. Use gravity to add momentum over time

GeckoLib Model Not Loading

Problem: Type is "geo" but model doesn't render.

Solutions:

  1. Verify model file path is correct
  2. Check .geo.json file exists
  3. Model path should NOT include .geo.json in JSON (just path without extension)
  4. Texture path must match model's texture reference
  5. Animation name must match exactly (case-sensitive)

API Reference

ParticleSpawner Methods

// Single particle
ParticleSpawner.spawn(level, id, x, y, z, vx, vy, vz);
ParticleSpawner.spawn(level, id, x, y, z, vx, vy, vz, extraData);

// Patterns
ParticleSpawner.burst(level, id, center, count, speed);
ParticleSpawner.stream(level, id, entity, count, speed, spread);

// Beams
ParticleSpawner.spawnBeam(level, id, from, to, width);
ParticleSpawner.spawnBeam(level, id, from, to, startWidth, endWidth);

ParticleRegistry Methods

ParticleRegistry.register(id, definition);
ParticleRegistry.get(id);
ParticleRegistry.has(id);
ParticleRegistry.getAll();
ParticleRegistry.getAllFromMod(namespace);

Need Help?

  • DM me on discord or join my discord server:

Good luck creating amazing particles!

Смотри также

Похожие подборки моды — по версиям Майнкрафта, загрузчикам и жанрам.

Сервера Майнкрафт

Играть интереснее на сервере — выбирай в рейтинге серверов Майнкрафт и заходи прямо сейчас.

SkyBars
SkyBars Java + BE
1170 онлайн
1.8 — 26.2 версия
🎮 ВЫЖИВАНИЕ ⚔️ АНАРХИЯ 🚗 ГТА РП 🎤 ГОЛОСОВОЙ ЧАТ 🎁 БЕСПЛАТНЫЙ ДОНАТ 🌟 СМП 💻 ПК+ТЕЛЕФОН
MigosMc
MigosMc Java + BE
1128 онлайн
1.8 — 26.2 версия
🌿 MigosMc.net | Гриферский сервер с войс-чатом | Награды за онлайн ⭐ ВЫЖИВАНИЕ⭐ ОДИНБЛОК⭐ МИНИ-ИГРЫ
SeasonEra
4 онлайн
26.1.2 версия
Выживание • Экономика • Кланы • Приваты • Донат • PVP • Работа
PLIRGAME - ДЕВУШКИ ВОЙС ЧАТ
31 онлайн
1.21.10 — 26.1.1 версия
❤️ Выживание! ❤️ Войс Чат ❤️ Девушки ❤️ /free
MineLauncher
Лаунчер Майнкрафт без лицензии — все версии
Бесплатный лаунчер для ПК и Андроид — все версии 26.2, 1.21.11, 26.1.2, 1.21.8. Fabric, NeoForge, Forge, шейдеры, моды и скины в один клик.
Без лицензии Fabric, NeoForge, Forge Моды, шейдеры, скины Все версии Майнкрафта ПК и Андроид Для слабых ПК Сервера в лаунчере
Скачать бесплатно
Windows и Андроид · Бесплатно · Без лицензии
Наш чат