Particle Systems

Overview

The Particle Editor is a standalone tool in ChiselAssetTools.sln for creating and previewing particle systems. Particle systems are saved as .crp files and spawned at runtime via ParticleManager. It reads the same game config as Rockwall 2, so your project’s materials are available for previewing.

A particle system has two levels: the system, which holds global settings, and one or more subsystems, each of which is an independent emitter with its own material, spawn rate, and per-particle behavior. A muzzle flash might have one subsystem for the flash sprite and another for smoke.

Opening the Editor

Set the Particle Editor as the startup project in ChiselAssetTools.sln and run it. The same startup window as Rockwall 2 appears. Once loaded, you’ll see a 3D preview viewport on the right and a control panel on the left. Use File → New to start a blank system, File → Open to load an existing .crp, and File → Save to write it back out. The preview loops continuously.

Note

The particle editor previews collision against a flat ground plane at Y=0. In game, collision uses the actual BSP geometry of your map.

System Settings

These settings apply to the particle system as a whole:

Lifetime

How long each particle lives in seconds. Particles fade from fully opaque to transparent over their lifetime.

Collides With World

When checked, particles bounce and slide along world geometry using the BSP. In the editor this means the Y=0 preview floor.

Bounce

How much velocity is reflected on collision. 0 stops dead, 1 is a fully elastic bounce. Values above 1 cause particles to gain energy on impact.

Velocity Dampening

How quickly horizontal velocity bleeds off after a bounce. Higher values slow particles down faster as they skid along surfaces.

Managing Subsystems

The subsystem list sits below the system settings. Each entry is labeled subsystem:N. Click one to select and edit its properties. Use Add to append a new subsystem with default values and Delete to remove the selected one.

All subsystems run simultaneously. There is no sequencing between them. For a two-stage effect like a flash followed by lingering smoke, use a short lifetime on the flash subsystem and a longer one on the smoke subsystem so they naturally overlap and tail off at different times.

Note

Sequencing is planned.

Subsystem Settings

All range fields use a min/max pair. Each spawned particle picks a random value between the two. Enter vectors as comma-separated X, Y, Z.

Lifetime

How long particles from this subsystem live. Can differ from the system lifetime.

Particles

Maximum particles alive from this subsystem at once. Capped at 255.

Spawn Rate

How many particles per second this subsystem emits. Combined with Particles and Lifetime, this controls density.

Emission Type

Controls how particles are released. Impulse spawns all particles at once. Constant spawns them over time according to Spawn Rate.

Render Type

FaceCamera always faces the viewer like a standard sprite. FaceVelocity aligns the billboard’s up axis with the particle’s velocity direction, giving a streak-like look to fast particles.

Material

The material applied to each particle’s billboard quad. Click to open the material browser. Particles use the diffuse texture with alpha blending, so materials with transparent textures work best.

Gravity

Downward acceleration in units/second squared. Set to 0 for smoke or sparks that should drift without falling.

Start Velocity (Min / Max)

Initial velocity range per particle as an X, Y, Z vector. Upward bursts use a positive Y range; horizontal sprays use X and Z.

Start Position (Min / Max)

Spawn position offset from the system origin. Particles appear at a random position within this box. Use a large range for area effects like rain.

Start Size (Min / Max)

World-space size of each particle’s billboard. Randomized between min and max. Size does not change over lifetime.

Angular Velocity (Min / Max)

How fast the particle rotates around its billboard normal in degrees per second. Randomization here adds variation to sprites that would look repetitive when static.

Spawning Particles in Code

At runtime, use ParticleManager.SpawnParticleSystem(). The file path version is the common case:

ParticleManager.SpawnParticleSystem(
    hitPoint,
    $“{GameEngine.FullPath}/Particles/BulletImpact/impact_concrete.crp”
);

The method returns an integer index you can use to retrieve the spawner later via ParticleManager.GetSpawner(id). For fire-and-forget effects you can ignore the return value entirely since the system removes itself automatically when all particles have died.

An optional third argument is a spawn transformation matrix for effects that should emit relative to an object’s orientation:

Matrix spawnMatrix = Matrix.CreateFromQuaternion(entity.rotation);
ParticleManager.SpawnParticleSystem(entity.position, “Content/Particles/thruster.crp”, spawnMatrix);

Particle files are cached after the first load. The second time you spawn the same path, the engine reuses the deserialized behavior from memory rather than reading from disk.

Note

Up to 512 particle systems can be active at once. When the limit is hit, new spawns overwrite the oldest active system. Avoid spawning large numbers of looping systems without cleaning them up.

Lighting

Particles are lit by the scene at the moment they are spawned. ParticleManager samples the light probe network at the spawn position and stores a single diffuse color that tints all particles in that system for their lifetime. A system spawned in a dark corner will look dimmer than the same system spawned under a bright light, without any extra setup.

File Location

The .crp format is plain JSON. Save particle files anywhere under your content directory and pass the path to SpawnParticleSystem(). The FPS template uses Working/Particles/ as a convention, which becomes Content/Particles on build.

Materials used by a particle system must be mounted before the system is first spawned. If a material name in the .crp can’t be found, the particle renders as a white quad using the engine’s fallback texture.