Give motion
weight and sound.
Particles and audio are independent runtime systems. Connect them to animation, physics, or gameplay events without coupling them to one renderer or mixer.
Create a pooled system
final sparks = GlintParticleSystem(
const GlintParticleConfig(
maxParticles: 2000,
emissionRate: 180,
lifetime: GlintDoubleRange(.25, 1.1),
startSpeed: GlintDoubleRange(2, 8),
shape: GlintConeParticleShape(
angle: .35,
baseRadius: .1,
),
gravity: Vector3(0, -9.81, 0),
blendMode: GlintParticleBlendMode.additive,
),
seed: 42,
);Particles live in dense reusable typed arrays. Emission and simulation are deterministic for the same seed and fixed update sequence.
Shape emission and appearance
EmittersPoint, box, sphere, and cone shapes plus continuous rates, manual emission, and scheduled bursts.
MotionSpeed ranges, gravity, drag, procedural noise, local or world simulation, and prewarming.
AppearanceSize curves, color/alpha gradients, rotation, alpha or additive blending, sorting, textures, and sprite sheets.
EventsWorld-space spawn, collision, and death signals for gameplay or secondary effects.
sparks.update(dt);
return GlintGameFrame(
camera: camera,
instances: instances,
particles: [sparks.renderBatch],
);Collide through the physics contract
sparks.update(
fixedDt,
collisions: GlintPhysicsParticleCollisionResolver(physics),
);The adapter traces particle movement with backend-neutral queries, then applies the configured response. Local-space systems still query and emit events in world space.
Add the SoLoud backend
flutter pub add glint_soloudfinal audio = GlintAudioEngine(
backend: GlintSoLoudAudioBackend(),
);
await audio.initialize(
config: const GlintAudioConfig(maxActiveVoices: 96),
);
final effects = audio.createBus('effects');
final impact = await audio.load(
const GlintAudioSource.asset('assets/audio/impact.ogg'),
);The core contract supports cached asset, file, bounded network, and encoded-memory sources; buses; voice controls; loading policy; and listener/source state. Apps without glint_soloud do not inherit its native build.
Update the listener and moving voices
audio.listener = GlintAudioListener(
position: camera.position,
forward: camera.target - camera.position,
velocity: cameraVelocity,
);
final voice = audio.playSpatial(
impact,
hit.position,
bus: effects,
options: const GlintSpatialAudioOptions(
minimumDistance: 1,
maximumDistance: 80,
dopplerFactor: 1,
),
);
voice.setSpatialState(car.position, velocity: car.linearVelocity);Distance attenuation, panning, and Doppler depend on consistent world units and meaningful velocity. Update long-lived moving voices every simulation frame.
Choose the right loading mode
MemoryShort effects and anything latency-sensitive. Decode once and reuse the cached clip.
StreamMusic and long ambience. Protect important music voices from ordinary voice-limit stealing.
BusesSeparate music, effects, UI, ambience, and dialogue for independent volume and pause policy.
DisposeStop voices, release clips and buses, then dispose the engine when the owning application scope ends.
The host needs CMake to build flutter_soloud. On macOS, install it with brew install cmake.