Routine schedule rookie question

I have had this issue where when I use Routines to make sequences the timing of each triggered event can be irregular. I have attached a simple example here, which seems to lag when run. Can it be helped, is there a scheduler-method or should I revert to either Pbinds or OSC-bundle messages?

Or is this an issue on my machine alone?

s.waitForBoot({
    var logTime, expTime, time;

    time = 0.1;

    logTime = {|time|
        time * 0.707
    };

    expTime = {|time|
        time * 1.07
    };

    SynthDef(\kick, {
        var sig, env;

        env = EnvGen.kr(
            Env.perc(
                \atk.kr(0.01), 
                \rel.kr(0.65),
                curve: -4),
                \t_trig.kr(0),
                doneAction: 2
            );

        sig = SinOsc.ar(
            \freq.kr(30)
        );

        Out.ar([0, 1], sig * 0.5 * env);

    }).add;

    s.sync;

    fork{
        loop{
            Post << "Hello\n\ntime: %\n\n-------------------\n".format(time);
            Synth(\kick, [\t_trig, 1]);
            wait(time);
            time = expTime.value(time);
            if (time > 0.4) {
                time = 0.1;
            }
        }

    }

})

hmmm seems to work fine over here!

I had to raise the frequency and lower the gain to be able to hear the timing. - when the 30 cycle signals overlap you can get cancellations or overs that might obscure the timing.

Of course its hard to tell if geometrically slowing pulse is “even” for me anyhow!

try this (subbing WhiteNoise) - still sounding uneven?

s.waitForBoot({
    var logTime, expTime, time;

    time = 0.1;

    logTime = {|time|
        time * 0.707
    };

    expTime = {|time|
        time * 1.07
    };

    SynthDef(\kick, {
        var sig, env;

        env = EnvGen.kr(
            Env.perc(
                \atk.kr(0.01), 
                \rel.kr(0.65),
                curve: -4),
                \t_trig.kr(0),
                doneAction: 2
            );

        sig = SinOsc.ar(
            \freq.kr(30)
        );

        Out.ar([0, 1], sig * 0.5 * env);

    }).add;

    s.sync;

    fork{
        loop{
            Post << "Hello\n\ntime: %\n\n-------------------\n".format(time);
            Synth(\kick, [\t_trig, 1]);
            wait(time);
            time = expTime.value(time);
            if (time > 0.4) {
                time = 0.1;
            }
        }

    }

})

Calls to Synth.new or .set should be wrapped in Server.default.bind { ... }. This preempts the OSC messages with some latency, dictated by Server.default.latency, and ensures more accurate timing than sending the OSC messages immediately.