Community listing page, reviews here may not be monitored by the author.
DC Render API
No reviews yet
DC Render API: Custom graphics API powering exclusive visual effects for Dragon Curse Chronicles.
Community voices
Reviews
No reviews yet. Be the first to review this project!
Get it on
Available Platforms
Compatibility
Supported Environments
Must be installed on both the client and the server.
About
Project Details
For authors
Embed Badge
If you're the author of this project, you can embed a live badge anywhere that supports HTML or Markdown. It updates automatically whenever ratings change.
Use HTML for any page that supports it, or Markdown for README files and Markdown-based descriptions.
Identifiers
Platform IDs
About
Description
DC Render API
DC Render API is a Minecraft Forge mod that provides advanced particle rendering and animation systems, offering powerful particle effect creation tools for mod developers.
跳转至中文介绍: README.md
Features
Core Features
- Controllable Particle System: Create and manage controllable particle instances
- Particle Animation System: Built-in multiple preset animation effects and timeline system
- Server-side Particle Synchronization: Achieve particle state synchronization between client and server
- Particle Group Management: Batch management of particle effects
- Particle Emitter System: Create and manage particle emission sources
- Particle Style System: Customize particle appearance and behavior
- Barrage System: Create complex barrage effects
- Display Entity System: Manage and render display entities
- Effect System: Combine multiple particle and animation effects
- Event System: Respond to game events and particle lifecycle
- Noise System: Generate natural random effects
Animation Effects
- Circular orbit animation
- Spiral orbit animation
- Wave motion animation
- Random walk animation
- Ease animation
- Timeline animation
- Combined animation
Project Structure
DC Render API/
├── src/
│ └── main/
│ ├── java/com/qituo/dcrapi/
│ │ ├── DcRenderApi.java # Main mod class
│ │ ├── network/ # Network related classes
│ │ │ ├── DcRenderApiNetwork.java # Network packet registration
│ │ │ ├── ParticleGroupPacket.java # Particle group synchronization packet
│ │ │ └── ParticleSyncPacket.java # Particle synchronization packet
│ │ ├── particles/ # Particle related classes
│ │ │ ├── emitters/ # Particle emitters
│ │ │ │ ├── ParticleEmitter.java # Particle emitter interface
│ │ │ │ └── ParticleEmitterManager.java # Particle emitter manager
│ │ │ ├── style/ # Particle styles
│ │ │ │ ├── ParticleStyle.java # Particle style interface
│ │ │ │ └── ParticleStyleManager.java # Particle style manager
│ │ │ ├── ClientParticleGroupManager.java # Client particle group management
│ │ │ ├── ControlableParticle.java # Controllable particle interface
│ │ │ ├── DcRenderApiParticleManager.java # Particle manager
│ │ │ ├── ParticleAnimationExample.java # Particle animation examples
│ │ │ ├── ServerParticleGroup.java # Server-side particle group
│ │ │ └── ServerParticleGroupManager.java # Server-side particle group management
│ │ └── platform/ # Platform related classes
│ │ └── DcRenderApiServices.java # Service interface
│ └── kotlin/com/qituo/dcrapi/ # Kotlin implementation
│ ├── animation/ # Animation system
│ │ ├── timeline/ # Timeline system
│ │ │ ├── DoubleConstTimeAnimator.kt
│ │ │ ├── Ease.kt
│ │ │ ├── Eases.kt
│ │ │ ├── Timeline.kt
│ │ │ └── ValueConstTimeAnimator.kt
│ │ ├── Animate.kt
│ │ └── AnimateManager.kt
│ ├── barrages/ # Barrage system
│ │ ├── Barrage.kt
│ │ └── BarrageManager.kt
│ ├── color/ # Color system
│ │ └── Color.kt
│ ├── config/ # Configuration system
│ │ ├── Config.kt
│ │ └── ConfigManager.kt
│ ├── display/ # Display entity system
│ │ ├── DisplayEntity.kt
│ │ └── DisplayEntityManager.kt
│ ├── effects/ # Effect system
│ │ ├── Effect.kt
│ │ └── EffectManager.kt
│ ├── event/ # Event system
│ │ ├── Event.kt
│ │ ├── EventBus.kt
│ │ └── Events.kt
│ ├── math/ # Math utilities
│ │ └── Vec3.kt
│ ├── noise/ # Noise system
│ │ ├── Noise.kt
│ │ └── PerlinNoise.kt
│ ├── particles/ # Particle system
│ │ ├── emitters/ # Particle emitter implementation
│ │ │ └── BasicParticleEmitter.kt
│ │ ├── style/ # Particle style implementation
│ │ │ └── BasicParticleStyle.kt
│ │ └── ParticleAnimation.kt # Particle animation implementation
│ ├── render/ # Render system
│ │ ├── Render.kt
│ │ └── RenderManager.kt
│ └── shapes/ # Shape system
│ ├── Circle.kt
│ └── Shape.kt
├── build.gradle # Gradle build file
├── gradle.properties # Gradle properties
└── settings.gradle # Gradle settings
Quick Start
Requirements
- Minecraft 1.20.1+
- Forge 47.4.17+
- Java 17+
Installation
- Place the mod JAR file into the
modsfolder of your Minecraft game directory - Start the game, and the mod will load automatically
API Usage Examples
Creating Controllable Particles
import com.qituo.dcrapi.particles.DcRenderApiParticleManager;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.world.phys.Vec3;
// Create a controllable particle
Vec3 position = new Vec3(0, 0, 0);
int particleId = DcRenderApiParticleManager.createParticle(
ParticleTypes.FLAME,
ParticleTypes.FLAME.get(),
position
);
Using Particle Animations
import com.qituo.dcrapi.particles.ParticleAnimation;
import net.minecraft.world.phys.Vec3;
// Create circular orbit animation
Vec3 center = new Vec3(0, 0, 0);
Vec3 animatedPosition = ParticleAnimation.createCircleOrbit(
center, // Center point
2.0, // Radius
0.1, // Speed
tick // Current tick
);
// Create spiral orbit animation
Vec3 spiralPosition = ParticleAnimation.createSpiralOrbit(
center, // Center point
1.0, // Radius
3.0, // Height
0.1, // Speed
tick // Current tick
);
Server-side Particles
import com.qituo.dcrapi.particles.DcRenderApiParticleManager;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.phys.Vec3;
// Create server-side particle
ServerLevel level = ...;
Vec3 position = new Vec3(0, 0, 0);
DcRenderApiParticleManager.createServerParticle(
level,
ParticleTypes.FLAME,
ParticleTypes.FLAME.get(),
position
);
Particle Group Management
Creating Particle Groups
import com.qituo.dcrapi.particles.ServerParticleGroupManager;
import net.minecraft.world.phys.Vec3;
// Create particle group
Vec3 position = new Vec3(0, 0, 0);
int groupId = ServerParticleGroupManager.createGroup(position);
// Add particle to group
ServerParticleGroupManager.addParticleToGroup(
groupId,
ParticleTypes.FLAME,
ParticleTypes.FLAME.get()
);
// Start group animation
ServerParticleGroupManager.startGroupAnimation(
groupId,
"circle", // Animation type
2.0, // Radius
0.1 // Speed
);
Particle Emitter System
Creating Particle Emitters
import com.qituo.dcrapi.particles.emitters.ParticleEmitterManager;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.world.phys.Vec3;
// Create particle emitter
Vec3 position = new Vec3(0, 0, 0);
int emitterId = ParticleEmitterManager.createEmitter(
position,
ParticleTypes.FLAME,
10, // Particles per second
2.0 // Particle speed
);
// Start emitter
ParticleEmitterManager.startEmitter(emitterId);
// Stop emitter
ParticleEmitterManager.stopEmitter(emitterId);
Particle Style System
Creating Custom Particle Styles
import com.qituo.dcrapi.particles.style.ParticleStyleManager;
import net.minecraft.world.phys.Vec3;
// Create particle style
int styleId = ParticleStyleManager.createStyle(
1.0, // Size
0.5, // Alpha
new Vec3(1, 0, 0), // Color (red)
2.0 // Lifetime
);
// Apply style to particle
ParticleStyleManager.applyStyleToParticle(particleId, styleId);
Barrage System
Creating Barrages
import com.qituo.dcrapi.barrages.BarrageManager;
import net.minecraft.world.phys.Vec3;
// Create barrage
Vec3 position = new Vec3(0, 0, 0);
int barrageId = BarrageManager.createBarrage(
position,
"circle", // Barrage type
10, // Barrage count
2.0, // Barrage speed
1.0 // Barrage radius
);
// Start barrage
BarrageManager.startBarrage(barrageId);
Timeline Animation
Creating Timeline Animations
import com.qituo.dcrapi.animation.timeline.Timeline;
import com.qituo.dcrapi.animation.timeline.Eases;
import net.minecraft.world.phys.Vec3;
// Create timeline
Timeline timeline = new Timeline();
// Add position animation
Vec3 startPos = new Vec3(0, 0, 0);
Vec3 endPos = new Vec3(10, 5, 0);
timeline.addPositionAnimation(
startPos,
endPos,
200, // Duration (ticks)
Eases.easeInOutCubic // Ease function
);
// Add scale animation
timeline.addScaleAnimation(
1.0,
2.0,
200,
Eases.easeOutBounce
);
// Start timeline
timeline.start();
Effect System
Creating Composite Effects
import com.qituo.dcrapi.effects.EffectManager;
import net.minecraft.world.phys.Vec3;
// Create effect
Vec3 position = new Vec3(0, 0, 0);
int effectId = EffectManager.createEffect(position);
// Add particle to effect
EffectManager.addParticleToEffect(effectId, ParticleTypes.FLAME);
// Add animation to effect
EffectManager.addAnimationToEffect(effectId, "spiral", 2.0, 0.1);
// Start effect
EffectManager.startEffect(effectId);
Development Guide
Dependency Configuration
Add the following dependency to your mod's build.gradle file:
dependencies {
implementation fg.deobf("com.qituo:dcrapi:1.0.0")
}
Registering Particle Types
import com.qituo.dcrapi.particles.DcRenderApiParticleManager;
import net.minecraft.core.particles.SimpleParticleType;
import net.minecraftforge.registries.RegistryObject;
// Register custom particle type
public static final RegistryObject<SimpleParticleType> CUSTOM_PARTICLE =
DcRenderApiParticleManager.PARTICLE_TYPES.register(
"custom_particle",
() -> new SimpleParticleType(false)
);
Custom Particle Emitters
import com.qituo.dcrapi.particles.emitters.ParticleEmitter;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.world.phys.Vec3;
// Create custom particle emitter
public class CustomEmitter implements ParticleEmitter {
private Vec3 position;
private int particleCount;
public CustomEmitter(Vec3 position, int particleCount) {
this.position = position;
this.particleCount = particleCount;
}
@Override
public void emit() {
// Custom emission logic
for (int i = 0; i < particleCount; i++) {
// Calculate emission position
Vec3 emitPos = position.add(
(Math.random() - 0.5) * 2,
(Math.random() - 0.5) * 2,
(Math.random() - 0.5) * 2
);
// Emit particle
// Here you can use DcRenderApiParticleManager.createParticle
}
}
@Override
public void update() {
// Custom update logic
}
@Override
public boolean isAlive() {
// Custom alive logic
return true;
}
}
Custom Particle Styles
import com.qituo.dcrapi.particles.style.ParticleStyle;
import net.minecraft.world.phys.Vec3;
// Create custom particle style
public class CustomStyle implements ParticleStyle {
private float size;
private float alpha;
private Vec3 color;
private float lifetime;
public CustomStyle(float size, float alpha, Vec3 color, float lifetime) {
this.size = size;
this.alpha = alpha;
this.color = color;
this.lifetime = lifetime;
}
@Override
public float getSize() {
return size;
}
@Override
public float getAlpha() {
return alpha;
}
@Override
public Vec3 getColor() {
return color;
}
@Override
public float getLifetime() {
return lifetime;
}
@Override
public void update() {
// Custom update logic
size *= 0.99f;
alpha *= 0.95f;
}
}
Custom Animations
import com.qituo.dcrapi.animation.Animate;
import net.minecraft.world.phys.Vec3;
// Create custom animation
public class CustomAnimation implements Animate {
private Vec3 startPos;
private Vec3 endPos;
private int duration;
private int ticks;
public CustomAnimation(Vec3 startPos, Vec3 endPos, int duration) {
this.startPos = startPos;
this.endPos = endPos;
this.duration = duration;
this.ticks = 0;
}
@Override
public Vec3 animate() {
float progress = (float) ticks / duration;
progress = Math.min(progress, 1.0f);
// Custom animation logic
return startPos.add(endPos.subtract(startPos).scale(progress));
}
@Override
public boolean isDone() {
return ticks >= duration;
}
@Override
public void tick() {
ticks++;
}
}
License
This project is licensed under the QSUP License. See the LICENSE.md file for details.
Contributing
Welcome to submit Issues and Pull Requests to improve this project!
Contact
- GitHub: 19136644525lxy/DC-Render-API
DC Render API
DC Render API is an advanced particle rendering & animation library for Minecraft mods. It exposes a complete, production-ready visual system for controllable particles, particle groups, emitters, styles, barrages, display entities, easing timelines and a lightweight event bus — and ships with a built-in mitigation strategy against aggressive
addParticleculling from client-side optimization mods such as Embeddium / Rubidium / Inventory Particles. The project maintains Forge 1.20.1 / Fabric 1.20.1 / NeoForge 1.21.1 with full feature parity across all three loaders.
跳转至中文文档: README.md
Platform Support
| Loader | Minecraft Version | Mod Artifact | JDK | Kotlin Language Adapter |
|---|---|---|---|---|
| Minecraft Forge | 1.20.1 | 0.2.0-1.20.1Forge |
JDK 17+ | Kotlin-for-Forge-*-1.20.1.jar (by thedarkcolour) |
| Fabric | 1.20.1 | 0.2.0-1.20.1Fabric |
JDK 17+ | fabric-language-kotlin-* (by FabricMC) |
| NeoForge | 1.21.1 | 1.0.0-1.21.1NeoForge |
JDK 21+ | Kotlin-for-Forge-*-1.21.1-NeoForge.jar (by thedarkcolour) |
⚠ Mandatory three-jar setup for every loader: install the Kotlin language adapter + DC Render API jar + the main mod that consumes it (e.g. Dragon Curse Chronicles). Missing any one of the three will crash at load.
Core Features
Main Capabilities
- Controllable Particle System: Particle instances tracked by stable
idwith explicit lifecycle & dead flag. - Particle Animation System: Circle orbit, spiral orbit, wave motion, random walk, easing functions, and timeline keyframe interpolation.
- Server-Client Particle Sync: Two dedicated network packets (
ParticleGroupPacket,ParticleSyncPacket) guarantee a consistent view across clients. - Particle Group Management:
ServerParticleGroupManager/ClientParticleGroupManagerfor batched create / tick / destroy. - Particle Emitter System:
ParticleEmitterinterface +ParticleEmitterManagerwith rate & velocity settings. - Particle Style System:
ParticleStylefor size / alpha / RGB / lifetime;createStyle+applyStyleToParticle. - Barrage System:
BarrageManagersupports complex patterns including circular barrages. - Display Entity System: Lightweight wrapper around Minecraft Display Entities:
DisplayEntity+DisplayEntityManager. - Effect System:
Effect+EffectManagercombines multiple particles + animations into one reusable unit. - Event System: Lightweight
EventBus+ParticleEventBus; hooks for collision, hit, on-ground, liquid-entry. - Noise System:
PerlinNoisefor natural-looking randomness. - Smart Particle Dispatcher (pioneered in NeoForge host mod): Frame-aware batching + LOD falloff + object pooling + progressive emission + long-distance packet bypass; works around aggressive culling from client particle mods.
Animation Effects
- Circular Orbit
- Spiral Orbit
- Wave Motion
- Random Walk
- Easing functions (Linear, Quad, Cubic, Quart, Quint, Sine, Expo, Circ, Back, Elastic, Bounce …)
- Timeline interpolation (position, scale, rotation, color)
- Composition / layered animation
Project Structure
DC Render API/ # Standalone monorepo (this directory)
├── src/ # Forge 1.20.1 sources
│ └── main/
│ ├── java/com/qituo/dcrapi/ # Java layer: mod entry, items, network, particles, platform
│ │ ├── DcRenderApi.java # Forge @Mod entry
│ │ ├── items/ParticleTesterItem.java # in-game particle debugger
│ │ ├── network/* # server → client sync packets
│ │ ├── particles/
│ │ │ ├── emitters/* # Emitter interface + manager
│ │ │ ├── style/* # Style interface + manager
│ │ │ ├── DcRenderApiParticleManager.java # Thread-safe particle registry
│ │ │ ├── ControlableParticle.java
│ │ │ └── ServerParticleGroup*.java
│ │ └── platform/DcRenderApiServices.java
│ └── kotlin/com/qituo/dcrapi/ # Kotlin layer: animation, barrage, color, config, display, effect, event, math, noise, render, shape, commands, builder, composition
│ ├── animation/timeline/ # Timeline: Eases.kt, Timeline.kt, DoubleConstTimeAnimator, ValueConstTimeAnimator
│ ├── barrages/ color/ config/ display/ effects/ event/ math/ noise/
│ ├── particles/builder/ParticleGroupBuilder.kt # Recommended builder API
│ ├── particles/command/ particles/composition/ particles/emitters/ particles/style/
│ └── render/ shapes/
├── fabric/DC Render API/ # Fabric 1.20.1 sources (feature parity)
│ ├── src/main/java/ # Fabric particles, network, items, mixin, client initializer
│ ├── src/main/kotlin/ # Same Kotlin subsystem layout as Forge
│ ├── src/main/resources/fabric.mod.json # Fabric metadata
│ └── build.gradle / gradle.properties
├── neoforge/ # NeoForge 1.21.1 sources (feature parity)
│ ├── src/main/java + kotlin/ # Ported to 1.21.1 DataComponents / Holder / Codec / NeoForge.EVENT_BUS
│ └── build.gradle / gradle.properties
├── LICENSE.md # MIT License (mirrors the standalone GitHub repo)
├── build.gradle # Forge 1.20.1 build; registers 'sourcesJar' task
├── gradle.properties # mod_version=0.2.0, mod_id=dcrapi, mod_license=MIT
├── gradlew / gradlew.bat / gradle/ # Gradle Wrapper
└── settings.gradle
Installation (Player Side)
Forge 1.20.1
- Install Minecraft Forge 1.20.1 (47.x or newer).
- Download all three jars and drop them into your
mods/folder:- Kotlin adapter:
Kotlin-for-Forge-*-1.20.1.jar(CurseForge / Modrinth) - DC Render API:
dcrapi-0.2.0-1.20.1Forge.jar - The consuming mod (e.g. Dragon Curse Chronicles Forge edition)
- Kotlin adapter:
- Launch the game.
Fabric 1.20.1
- Install Fabric Loader 0.16.13+ and Fabric API 0.92.11+1.20.1.
- Download all three jars and drop them into your
mods/folder:- Kotlin adapter:
fabric-language-kotlin-*(CurseForge / Modrinth) - DC Render API:
dcrapi-0.2.0-1.20.1Fabric.jar - The consuming mod (e.g. Dragon Curse Chronicles Fabric edition)
- Kotlin adapter:
- Launch the game.
NeoForge 1.21.1
- Install NeoForge 21.1.248+ for Minecraft 1.21.1.
- Download all three jars and drop them into your
mods/folder:- Kotlin adapter:
Kotlin-for-Forge-*-1.21.1-NeoForge.jar(thedarkcolour) - DC Render API:
dcrapi-1.0.0-1.21.1NeoForge.jar - The consuming mod (e.g. Dragon Curse Chronicles NeoForge edition)
- Kotlin adapter:
- Launch the game.
Quick Start (Integrate into a Custom Mod)
Requirements Matrix
| Loader | Requirements |
|---|---|
| Forge 1.20.1 | Forge 47.x / JDK 17+ / Kotlin for Forge |
| Fabric 1.20.1 | Fabric Loader 0.16.13+ / Fabric API / fabric-language-kotlin / JDK 17+ |
| NeoForge 1.21.1 | NeoForge 21.1.248+ / Kotlin for Forge NeoForge / JDK 21+ |
Building Artifacts for All Three Loaders
# ============ Forge 1.20.1 ============
cd "DC Render API"
./gradlew build # outputs → build/libs/dcrapi-0.2.0-1.20.1Forge.jar and -sources.jar
# ============ Fabric 1.20.1 ============
cd "DC Render API/fabric/DC Render API"
./gradlew build # outputs → build/libs/dcrapi-0.2.0-1.20.1Fabric.jar and -sources.jar
# ============ NeoForge 1.21.1 ============
cd "DC Render API/neoforge"
./gradlew build # outputs → build/libs/dcrapi-1.0.0-1.21.1NeoForge.jar and -sources.jar
All three
build.gradlescripts register asourcesJartask, so a-sources.jaris produced automatically on every build.
Core Usage (Java Modders)
1. Create a Particle Group with Builder (Recommended)
import com.qituo.dcrapi.particles.builder.ParticleGroupBuilder;
import com.qituo.dcrapi.particles.ServerParticleGroup;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.phys.Vec3;
ServerLevel level = ...;
Vec3 pos = player.position();
ServerParticleGroup group = new ParticleGroupBuilder()
.position(pos)
.world(level)
.scale(2.0)
.visibleRange(128.0)
.maxTick(200)
.buildAndRegister();
2. Create a Controllable Particle (Server → Client Synced)
import com.qituo.dcrapi.particles.DcRenderApiParticleManager;
import net.minecraft.core.particles.ParticleTypes;
int pid = DcRenderApiParticleManager.createParticle(
ParticleTypes.FLAME,
ParticleTypes.FLAME.get(),
new Vec3(0, 64, 0)
);
3. Circle & Spiral Orbit Animations
import com.qituo.dcrapi.particles.ParticleAnimation;
import net.minecraft.world.phys.Vec3;
Vec3 center = player.position();
Vec3 orbitPos = ParticleAnimation.createCircleOrbit(center, 2.0, 0.1, tick);
Vec3 spiralPos = ParticleAnimation.createSpiralOrbit(center, 1.0, 3.0, 0.1, tick);
4. Particle Hit Event (Deal Damage)
import com.qituo.dcrapi.event.ParticleEventBus;
import com.qituo.dcrapi.event.ParticleEvents.ParticleHitEntityEvent;
ParticleEventBus.INSTANCE.register(ParticleHitEntityEvent.class, ev -> {
ev.getTarget().hurt(ev.getTarget().level().damageSources().magic(), 5.0F);
});
Event Types:
| Event Class | Trigger |
|---|---|
ParticleCollideEvent |
Particle collides with a block |
ParticleHitEntityEvent |
Particle hits a living entity |
ParticleOnGroundEvent |
Particle lands on the ground |
ParticleOnLiquidEvent |
Particle enters a liquid |
5. Particle Style System
import com.qituo.dcrapi.particles.style.ParticleStyleManager;
import net.minecraft.world.phys.Vec3;
int styleId = ParticleStyleManager.createStyle(
1.0F, // size
0.5F, // alpha
new Vec3(1, 0, 0), // color (RGB)
2.0 // lifetime in seconds
);
ParticleStyleManager.applyStyleToParticle(pid, styleId);
6. Timeline & Easing (Kotlin-friendly, Java works too)
import com.qituo.dcrapi.animation.timeline.Timeline;
import com.qituo.dcrapi.animation.timeline.Eases;
Timeline tl = new Timeline();
tl.addPositionAnimation(startPos, endPos, 200, Eases.INSTANCE.getEaseInOutCubic());
tl.addScaleAnimation(1.0F, 2.0F, 200, Eases.INSTANCE.getEaseOutBounce());
tl.start();
7. Config File (config/dcrapi_config.properties)
maxParticleGroups=1000 # Upper bound on active particle groups
defaultVisibleRange=64.0 # Fallback visible range in blocks
particleTickRate=1 # Tick frequency
enableParticleEvents=true # Enables ParticleEventBus dispatching
enableDebugLogging=false # Verbose log output
Performance & Thread Safety
Performance Tips
- Tune
visibleRange: keep it between 32 and 128 blocks; larger values blow up bandwidth and draw cost quickly. - Frame-batched / progressive emission: for burst effects with >1000 particles, use a
SmartParticleDispatcher-style queue pattern (see NeoForge Dragon Curse Chronicles reference implementation) instead of spawning everything in one tick. - Clean up promptly: schedule periodic
ServerParticleGroupManager.clear()to reap dead groups. - Keep handlers light: never do I/O or heavy computation inside ParticleEventBus callbacks.
Thread-Safety Guarantees (in code)
ConcurrentHashMap<Integer, ControlableParticle>backingDcRenderApiParticleManager.PARTICLES.AtomicInteger nextParticleIdto avoid races during id allocation.CopyOnWriteArrayListfor ParticleEventBus handler lists; safe to iterate while registering.- Batch-remove pattern on tick: collect dead particle ids to a list, then
removeAllat once — avoids the ConcurrentHashMap iterator weak-consistency gotcha. - Per-particle try/catch: one misbehaving particle or packet handler can never abort an entire tick.
In-Game Debug Tool
All three loaders register a Particle Tester creative item:
- Right-click: Spawn a standard demo particle group (orbit + style + event hook).
- Sneak + Right-click: Cycle debug mode:
Basic → Builder → Event → Basic … - Storage: the active test mode is now saved on the item stack itself (
CustomData / NBT) instead of a JVM-static field — fixes cross-hand / cross-player state pollution.
Compatibility Matrix
| Feature | Forge 1.20.1 | Fabric 1.20.1 | NeoForge 1.21.1 |
|---|---|---|---|
| MC Version | ✅ | ✅ | ✅ |
| Java | 17 | 17 | 21 |
| Kotlin Adapter | Kotlin-for-Forge | fabric-language-kotlin | Kotlin-for-Forge (NeoForge) |
| Particle Group Sync | ✅ | ✅ | ✅ |
| Particle Tester Item | ✅ | ✅ | ✅ |
| Auto sourcesJar Task | ✅ | ✅ | ✅ |
Build Dependency Snippets (build.gradle)
// Forge 1.20.1:
dependencies {
implementation fg.deobf("com.qituo:dcrapi:0.2.0-1.20.1Forge")
}
// Fabric 1.20.1:
dependencies {
modImplementation("com.qituo:dcrapi:0.2.0-1.20.1Fabric")
}
// NeoForge 1.21.1:
dependencies {
implementation("com.qituo:dcrapi:1.0.0-1.21.1NeoForge")
}
Maven coordinates are the target format; if not yet uploaded to a Maven repo, drop the jars into a local
libs/folder and usefiles(...)as a dependency.
Known Consumer / Real-World Usage
Dragon Curse Chronicles is the first-party reference consumer of DC Render API:
- Pig Talisman laser / Dragon Talisman fireball → circular orbit + wave particle trails
- Uncle's Dried Puffer Fish laser → ~1200 particles with two counter-rotating gradient helices, dispatched progressively via
SmartParticleDispatcher - Origin Aura / Talisman activation effects → particle groups + timeline easing
Migration Guide (0.1.x → 0.2.x)
Before (0.1.x):
ServerParticleGroup group = new ServerParticleGroup();
group.initServerGroup(pos, world);
group.scale = 1.5;
ServerParticleGroupManager.addParticleGroup(group, pos, world);
After (0.2.x, Builder):
ServerParticleGroup group = new ParticleGroupBuilder()
.position(pos).world(world).scale(1.5).visibleRange(64.0).maxTick(100)
.buildAndRegister();
Highlights of the 0.2.0 release:
mod_version=0.2.0, MIT license explicitly declared ingradle.properties+ standaloneLICENSE.md.- All three loader builds register a
sourcesJartask;-sources.jaris produced on every build. ParticleTesterItem: test-mode state moved from a static JVM field into item stackCustomData / NBT; eliminates cross-player state pollution.DcRenderApiParticleManager:nextParticleIdchanged from plainint→AtomicInteger; tick removal switched to batch-remove pattern for stronger consistency.
License & Authors
Released under the MIT License — see the official standalone license blob at LICENSE.md on GitHub.
- Current version: Forge
0.2.0/ Fabric0.2.0-1.20.1Fabric/ NeoForge1.0.0(version numbers are independent per loader) - Authors: QiTuo, Yifei
- Source repo: https://github.com/19136644525lxy/DC-Render-API
- Distribution: CurseForge / Modrinth
Screenshots
Gallery
Versions
Files
Relations
Project Relations
More like this
Similar Mods
Suggestions use data such as tags, dependencies, dependents, descriptions, titles, and more to rank how much they overlap with this mod.
On ModDex
Community snapshot
By the numbers
Statistics
Want to reach Minecraft players?
We're looking for a server hosting partner to feature here and other parts of the site. Interested? Send us a message!
Get in touchGet it on
Available Platforms
On ModDex
Community snapshot
By the numbers