Author detailed module data in the editor or in .particle.json profiles. Script the effect's timing and game logic.
Get The Component
use Lenga\Engine\Core\Behaviour;
use Lenga\Engine\Core\ParticleSystem;
final class TorchEffect extends Behaviour
{
private ?ParticleSystem $smoke = null;
public function start(): void
{
$this->smoke = $this->getComponent(ParticleSystem::class);
}
}
ParticleSystem is a component, so it is retrieved the same way as other scene components.
Playback
Use play() for continuous effects.
$particles->play();
Use pause() when you want to freeze simulation without clearing living particles.
$particles->pause();
Use stop() to stop emission. Pass true to clear particles immediately.
$particles->stop();
$particles->stop(true);
Use clear() to remove living particles without changing authored settings.
$particles->clear();
Bursts
Use emit() for immediate bursts.
$particles->emit(24);
For a one-shot effect, a common pattern is:
$particles->stop(true);
$particles->emit(32);
$particles->play();
Use restart() when the whole system should start over.
$particles->restart();
$particles->restart(keepSeed: true);
Keeping the seed is useful when you want the same burst pattern every time.
Manual Simulation
simulate() advances the particle system by a number of seconds.
$particles->simulate(0.5);
$particles->simulate(1.0, restart: true);
Use this for prewarming, deterministic setup, or custom preview behavior. For normal gameplay, let the engine update the system.
Profiles And Textures
Load a profile:
$particles->loadProfile('Assets/Particles/LandingDust.particle.json');
Load a texture:
$particles->loadTexture('Assets/Sprites/Effects/dust.png');
Profile swaps are usually better than setting many module values from PHP. A spell can switch from idle motes to a burst profile without hard-coding all of the shape, color, size, and renderer settings in gameplay code.
Simple Runtime Tuning
The PHP API exposes common values:
$particles->dimension = '3D';
$particles->emissionRate = 20.0;
$particles->lifetime = 0.75;
$particles->startSpeed = 8.0;
$particles->startSize = 0.3;
$particles->endSize = 0.0;
$particles->shapeType = 'Cone3D';
Use these for simple runtime adaptation. For example, increase emission rate when an engine overheats, or switch shape type for a special state.
Avoid using PHP as a full authoring layer for curves and gradients. Author those details in profiles through the editor workflow.
State Inspection
getState() returns diagnostic information.
$state = $particles->getState();
Debug::log('Alive particles: ' . $state['aliveParticleCount']);
Useful keys include:
dimensionisPlayingaliveParticleCountmaxParticlesemissionRatelifetimestartSpeedstartSizetexturePathprofilePathshapeTypesortingLayerorderInLayer
Use getState() for debugging, editor tools, or runtime UI. Prefer typed properties and methods for normal gameplay code.
Example: Landing Dust
use Lenga\Engine\Core\Behaviour;
use Lenga\Engine\Core\ParticleSystem;
final class LandingDust extends Behaviour
{
private ?ParticleSystem $dust = null;
public function start(): void
{
$this->dust = $this->getComponent(ParticleSystem::class);
$this->dust?->loadProfile('Assets/Particles/LandingDust.particle.json');
$this->dust?->stop(true);
}
public function onLanded(): void
{
$this->dust?->restart(true);
$this->dust?->emit(18);
}
}
This keeps authored VFX in the profile and gameplay timing in the script.