Loop

from acron.particles3d import Loop
class Loop(app, parent, *, geom, amount, lifetime, pos=(0, 0, 0), explosiveness=0.0, randomness=0.0, lifetime_randomness=0.0, preprocess=0.0, direction=(0, 0, 1), spread=0.0, velocity=(0.0, 0.0), gravity=(0, 0, 0), scale=(1.0, 1.0), scale_curve=None, color=(1, 1, 1, 1), color_ramp=None, emission_radius=0.0, emission_surface_radius=0.0, emission_box=None, emission_ring=None, angle=(0.0, 0.0), angular_velocity=(0.0, 0.0), disable_z=False, texture=None, texture_sampler=None, additive=False, billboard=False, align_y=False, shader=None, shader_inputs=(), phase_input=None, index_input=None, two_sided=True, depth_write=False, bin_order=40, name='loop')

Bases: object

A CONTINUOUSLY emitting CPUParticles3D: the reactor core’s plasma.

Burst is one-shot because every emitter that came before this one was – each is fired by an AnimationPlayer track, runs its particles once and frees itself. The four emitters of core.tscn’s Plasma subtree are the other kind: one_shot is false and emitting is true from the moment the level loads, so a particle that reaches the end of its life is RE-EMITTED rather than freed, for as long as the level stands.

The emission schedule is Godot’s own, out of CPUParticles3D::_particles_process:

restart_phase  = i / amount + randomness * rand / amount
restart_phase *= 1.0 - explosiveness
restart_time   = restart_phase * lifetime

– so explosiveness squeezes the whole batch towards the start of each cycle (1.0 emits all of them together), randomness jitters each particle’s restart by up to one slot, re-rolled every cycle, and the cycle itself is always lifetime long however short an individual particle’s own life is. lifetime_randomness is what shortens that life (lifetime * (1 - rand * lifetime_randomness)), and preprocess is simply where the clock starts, which is what makes an emitter look settled on the first frame instead of empty.

Positions are integrated in CLOSED FORM (origin + v t + g t^2 / 2) rather than stepped as Burst does. A one-shot cannot drift far enough for it to matter; a particle that is still being re-emitted an hour later can, and re-deriving the position from the age also means a respawn has nothing to reset. damping and radial_velocity have no stand-in here because none of the four emitters authors either.

What IS here and is not in Burst is what these four need: angle / angular_velocity (Godot’s per-particle roll and its rate – the wisps spin at -160 to -40 deg/s), ring emission, align_y, and phase_input, which feeds each particle’s normalised age to a shader uniform. That last one is how the flare rings scroll: their Godot shader reads INSTANCE_CUSTOM.y, which for a particle IS its phase.

The dying robot’s three StaticParticle emitters (one per flying part, game/enemies/part.py) are the second set of users, and they added the rest of Godot’s emission shapes – emission_box (shape 3) and emission_surface_radius (shape 2, which is the SPHERE SURFACE and not shape 1’s volume) – plus disable_z, which replaces the spread cone with Godot’s 2D form, and index_input, the per-particle constant INSTANCE_ID their shader reads beside the phase.

Inheritance diagram

digraph inheritancee4214dd149 { bgcolor=transparent; rankdir=BT; size="8.0, 12.0"; "Loop" [URL="acron.particles3d.Loop.html#acron.particles3d.Loop",fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=11,height=0.25,shape=box,style="",target="_top",tooltip="A CONTINUOUSLY emitting ``CPUParticles3D``: the reactor core's plasma."]; }