doneAction: 2 tells a UGen to free its enclosing synth node when it finishes, preventing silent zombie synths
Without doneAction: 2, a synth that has completed its envelope, Line, or PlayBuf keeps running silently in the server, consuming CPU and accumulating as zombie nodes in the Node Tree. Passing doneAction: 2 to the carrying UGen — typically Line.kr, EnvGen.kr, Env.perc.kr, or PlayBuf.ar — instructs it to free the whole synth node automatically the moment that UGen finishes its job; it is equivalent to the synth calling .free on itself. This is essential for percussive and one-shot sounds. For sustained synths using an ASR/ADSR envelope, closing the gate triggers the release phase, and doneAction: 2 then frees the node after the release completes. The positional shorthand and the keyword form are identical: Env.perc.kr(2) is the same as Env.perc.kr(doneAction: 2), because the positional argument resolves to doneAction.
Examples
// Without doneAction: 2 — zombie node persists silently:
{WhiteNoise.ar(Line.kr(0.2, 0, 2))}.play;
// With doneAction: 2 — node frees itself after 2 s:
{WhiteNoise.ar(Line.kr(0.2, 0, 2, doneAction: 2))}.play;
{PinkNoise.ar(Env.perc.kr(2))}.play; // perc envelope, auto-free
Assessment
Explain why a synth playing a fading Line.kr without doneAction: 2 is wasteful, and fix it with a single argument. Create a percussive synth using Env.perc with doneAction: 2 and verify in the Node Tree that its node disappears after playing; then run the same synth without it and observe the zombie node.