Effects (.effect)
An .effect file describes a visual effect. There are two types:
- Particle effects (
type: particles): one or more emitters that spray sprites, with optional ribbon trails. Engine exhaust, sparks, smoke. - Sprite effects (
type: sprite): a single shader-drawn sprite with a short lifetime. Muzzle flashes, bolt visuals.
Studio's effect editor writes effects to data/effects/<name>.effect and
registers them under files in the asset registry.
The engine doesn't load .effect files by itself. Your game reads the file
into its own BT objects and creates the effect from them. This example reads
the spawn and emission settings of the first emitter:
include "cturtle/yaml";
include "cturtle/particles";
object EffectSpawn { float rate; int max; }
object EffectEmission { float direction; float spread; array<float> speed; array<float> life; }
object EffectEmitter { EffectSpawn spawn; EffectEmission emission; }
object EffectFile { string name; array<EffectEmitter> emitters; }
fn start_exhaust(float x, float y) -> int {
EffectFile effect = EffectFile { name: "", emitters: new array<EffectEmitter>() };
yamlAssetFileFormat("engine_exhaust", particleEffectFormat())?;
yaml_decode_asset("engine_exhaust", effect)?;
EffectEmitter first = effect.emitters[0];
ParticleEmitterDesc desc = ParticleEmitterDesc {
rate: first.spawn.rate, maxLive: first.spawn.max, x: x, y: y,
direction: first.emission.direction, spread: first.emission.spread,
speedMin: first.emission.speed[0], speedMax: first.emission.speed[1],
lifeMin: first.emission.life[0], lifeMax: first.emission.life[1],
image: "spark", material: "", shader: "", texture: ""
};
return (join particle_create(desc))?;
}
yamlAssetFileFormat makes an effect written for a newer cTurtle (or an
older file that still has version: 1) fail with a clear message instead of
loading wrongly; see File format versions.
See cturtle/particles for
ParticleEmitterDesc and particle_create, and
cturtle/yaml for decoding.
Common fields
| Field | Type | Default | Description |
|---|---|---|---|
format | map | none | Optional file format version; see File format versions. |
type | string | particles | particles or sprite. |
name | string | "" | Effect name, normally the file name without .effect. |
Particle effects
type: particles
name: engine_exhaust
emitters:
- spawn:
rate: 40
max: 90
emission:
position: [0, 0]
direction: 0
spread: 0.45
speed: [70, 200]
life: [0.3, 0.6]
motion:
gravity: [0, 0, 0]
drag: 1.5
spin: [0, 0]
appearance:
size: [7, 2]
color_start: [0.55, 0.75, 1, 1]
color_end: [0.15, 0.35, 0.95, 0]
color_curve: [0.25, 0.1, 0.25, 1]
billboard:
image: spark
material: engine_spark
blend: alpha
layer: -0.6
trail:
enabled: true
from_emitter: true
points: 24
width_head: 6
width_tail: 1
color: [0.7, 0.88, 1, 0.45]
texture: ribbon
lifetime: 0.55
emitters is a list of emitters. Every emitter field is optional. Where a
default says "0 means", leaving the value at zero gives you that engine
default instead.
spawn
| Field | Type | Default | Description |
|---|---|---|---|
spawn.rate | number | 0 | Particles per second. 0 means particles only appear when your code fires a burst. |
spawn.max | integer | 0 means 256 | Most particles alive at once. |
emission
| Field | Type | Default | Description |
|---|---|---|---|
emission.position | [x, y] | [0, 0] | Offset from the emitter's position. |
emission.direction | number | 0 | Direction particles fly, in radians. |
emission.spread | number | 0 | Random angle added either side of direction, in radians. |
emission.speed | [min, max] | [0, 0] | Starting speed range, units per second. |
emission.life | [min, max] | [0, 0] means [1, 1] | How long each particle lives, in seconds. |
motion
| Field | Type | Default | Description |
|---|---|---|---|
motion.gravity | [x, y, z] | [0, 0, 0] | Constant acceleration, units per second². |
motion.drag | number | 0 | How quickly particles slow down. |
motion.spin | [min, max] | [0, 0] | Rotation speed range, radians per second. |
appearance
| Field | Type | Default | Description |
|---|---|---|---|
appearance.size | [start, end] | [0, 0] means [16, 0] | Particle size in pixels at birth and at death. |
appearance.size_curve | [x1, y1, x2, y2] | linear | Easing from start to end size, like CSS cubic-bezier. Each value 0–1. |
appearance.color_start | [r, g, b, a] | [0, 0, 0, 0] | Color at birth. |
appearance.color_end | [r, g, b, a] | [0, 0, 0, 0] | Color at death. If both colors are all zero, particles fade from white to transparent. |
appearance.color_curve | [x1, y1, x2, y2] | linear | Easing from start to end color. |
billboard
How each particle is drawn.
| Field | Type | Default | Description |
|---|---|---|---|
billboard.image | string | "" | Image asset name. Up to 95 characters. |
billboard.material | string | "" | Sprite material to use. If no material with this name exists, one is made from image with this name. Up to 31 characters. |
billboard.shader | string | default sprite shader | Shader asset name. Up to 31 characters. |
billboard.blend | string | alpha | alpha (normal), additive (glows, brightens what's behind) or premultiplied. In ParticleEmitterDesc these are 0, 1 and 2. |
billboard.layer | number | 0 | Draw order. |
With no image and no material, particles aren't drawn, which is useful for a trail-only effect.
trail
| Field | Type | Default | Description |
|---|---|---|---|
trail.enabled | bool | false | Draw a ribbon trail. |
trail.from_emitter | bool | false | true draws one ribbon following the emitter; false draws one per particle. |
trail.points | integer | 0 means 12 | Ribbon smoothness: points along the trail, 2–24. |
trail.width_head | number | 0 | Half-width at the front, in pixels. |
trail.width_tail | number | 0 | Half-width at the end, in pixels. |
trail.color | [r, g, b, a] | [0, 0, 0, 0] | Color at the front. |
trail.texture | string | "" (solid) | Image asset name. Up to 95 characters. |
trail.lifetime | number | 0 (off) | If above 0, the trail fades out over this many seconds. |
particle_create rejects names longer than the limits above.
Sprite effects
There is no built-in reader for sprite effects: Studio previews them, and your game decodes them. The fields below are the ones Studio's editor uses.
type: sprite
name: muzzle_flare
sprite:
shader: weapon_vfx
kind: flare
size: [18, 18]
color: [1, 0.35, 0.2, 1.8]
lifetime: 0.18
| Field | Type | Default | Description |
|---|---|---|---|
sprite.shader | string | — | Required. Shader asset name. |
sprite.image | string | "" | Image asset used as a mask. Without it, a plain white image is used. |
sprite.kind | string or number | bolt | For the weapon_vfx shader: bolt (0) or flare (1). Custom shaders can take a number. |
sprite.size | [w, h] | [1, 1] | Size. Both values above 0. |
sprite.color | [r, g, b, a] | [1, 1, 1, 1] | Tint. Values above 1 glow when bloom is on. |
sprite.lifetime | number | 0.1 | Seconds the sprite lasts. Above 0. |
sprite.angle_offset | number | 0 | Extra rotation, in radians. |
sprite.layer_offset | number | 0 | Draw order offset. |
sprite.animate_age | bool | true | Let the shader animate over the sprite's lifetime. |
Errors in Studio
| Message | Cause |
|---|---|
file is `<type>`, not `particles` / not `sprite` | The file's type doesn't match the editor you opened it in. |
sprite effect requires a shader and positive size/lifetime | Missing shader, or size or lifetime not above 0. |
animate_age must be true or false | Invalid animate_age. |
effect file: `version: 1` is no longer used | Delete the version line (an older file). |
effect file uses format version X; this cTurtle reads format … | The file was written for a newer cTurtle; see File format versions. |
See also
- Asset registry: registering effects, images, shaders and materials
cturtle/particles