Game Development Community

Trouble with Schedule

by University_Washington (#0009) · in Game Design and Creative Issues · 03/30/2009 (4:36 am) · 17 replies

Hi all. I'm trying to get a sound to be recursively played by a certain client in my game.

I have these two code things set up in a server side script:

datablock AudioProfile(CreatureBreathingSound)
{
    filename = "~/data/sound/Creature_Breathing.ogg";
    description = AudioClose3d;
    preload = true;
};

function CreatureBreathing(%obj)
{
    ServerPlay3D(CreatureBreathingSound, %obj.getTransform());
    %obj.schedule(2000, "CreatureBreathing", %obj);
}

Where this CreatureBreathing function is being called in the CreaturePlayer function of game.cs (on the server side) by:

CreatureBreathing(%player);

Yet all it does is play that ogg once, then not do anything. Any advice?

#1
03/30/2009 (6:02 am)
I could be wrong but I think the schedule function will only execute the given method once. In your case "CreatureBreathing" is only going to happen 2 sec (2000) after some said event, not every 2 sec. You may want to find a way to loop the breathing sound, maybe execute the sound every 2 secs based on the game clock or system clock. Hope that helps.
#2
03/30/2009 (2:27 pm)
do you need it looping?

IsLooping = true

try that in your datablock
#3
03/30/2009 (2:38 pm)
hi University_Washington (#0009),
i think your problem is one of torquescript function declaration syntax.
the usage "%obj.someFunction()" expects to call a function which has been declared like "function ClassName::someFunction(%this)", but your declaration is lacking the "ClassName::" portion.

you could solve this a couple ways:
* change how you're calling the function
* change how you're declaring the function

the first approach would mean changing the schedule to a global schedule rather than one attached to an object. eg:
schedule(2000, 0, "CreatureBreathing", %obj);

the second approach might look something like this:
// CreatureClass might be "Player" or "AIPlayer" or whatever.
function CreatureClass::CreatureBreathing(%this)
{
    ServerPlay3D(CreatureBreathingSound, %this.getTransform());
    %this.schedule(2000, "CreatureBreathing");   // %this will be implicitly passed
}
#4
03/30/2009 (3:25 pm)
@Orion,

Unless looping is set, that will still play the sound once correct? Or am I missing something in this?
#5
03/30/2009 (3:30 pm)
hey randy -

i'm unfamiliar with "IsLooping",
but if you walk through the code example above it should be clear that it will loop because CreatureBreathing() schedules CreatureBreathing().
#6
03/30/2009 (3:59 pm)
@Orion,

Just going by other scripts I have seen. Curious if he wants the sound to actually be scheduled or simply looping all the time. Only question is what triggers it to stop? If there is no need to stop it, then no need to schedule it.


datablock AudioProfile(CreatureBreathingSound)
{
filename = "~/data/sound/Creature_Breathing.ogg";
description = AudioClose3d;
[bold]isLooping = true[/bold];
preload = true;
};


#7
03/30/2009 (4:14 pm)
excellent points, Randy.

i see isLooping now - yeah, if what you want is for the sound to just repeat over & over, then isLooping seems like a much better way to go.

> what triggers it to stop?
with a construct like this, nothing.

in general if you have a repeating schedule (whether it's playing a sound or whatever it's doing) and want to be able to stop it, i would recommend a pattern sort of like this:

$gMyTimerId = "";

function myTimer_DoTick()
{
   cancel($gMyTimerId);    // this is a safety measure to avoid getting multiple parallel schedules going
   
   doStuff();              // play sound, update AI, whatever..
   
   $gMyTimerId = schedule(<period>, 0, "myTimer_DoTick");
}

function myTimer_Cancel()
{
   cancel($gMyTimerId);
   $gMyTimerId = "";
}
#8
03/30/2009 (4:43 pm)
@Orion,

Now I am following you:)

#9
03/31/2009 (2:50 am)
Thank you ALL for your advice.

I think that I will adopt Orion's pattern because I do want to use this setup for audio in a few areas (breathing, heartbeat, etc) and would like to be able to turn off these audio controls.

I always appreciate the swift replies from the Torque forums.
#10
03/31/2009 (3:03 am)
Would it be possible to do something like this (excuse my syntax)
function EventInterval(timeInterval,method,%obj)
{
$x = 1;
while($x > 0)
{
schedule(timeInterval, method, %obj);
}

And then, as Orion said, create a stopEventInterval function as this IS an infinite loop (dangerous!)?
#11
03/31/2009 (3:07 am)
I don't see why that wouldn't work. As far as I can see, once $x is set to less than or equal to 0, the function wouldn't be scheduled anymore. The only difference that I can understand between your code and Orion's is that your code would wait until the next iteration of "CreatureBreathing" before stopping the schedule as opposed to Orion's method which cancels that schedule event from occurring next.

The difference would be that of one cycle, I suppose.
#12
03/31/2009 (3:13 am)
There is one problem that I've spotted. With $x being a local variable, there would be no way to stop this loop from outside the function.
#13
03/31/2009 (3:25 am)
Someone should create generic

setEventInterval(intervalTime,methodName,intervalID,object)
{
//execute methodName every intervalTime on object. This eventInterval's ID is intervalID
}

and
cancelEventInterval(intervalID)
{
//stop intervalID
}

functions. Would make a very useful resource and I'm suprised they don't already exist.
#14
03/31/2009 (3:48 am)
Orion, this is where you say "oo, oo, oo, pick me, pick me!"
#15
03/31/2009 (9:36 am)
lol oo oo oo, pick me!
just kidding - i think you should give it a go actually.
just a quick note on the while ($x > 0) above though - torquescript is single-threaded, which means execution can only be in one part of the code at a time. if you have a routine which never finishes then the engine never gets a chance to do all its engine stuff like render the scene or execute schedule()s.

also, "$" denotes global variables, so $x is global. %x would be local.
#16
03/31/2009 (9:52 am)
I haven't read too much about them yet but don't finite state machines operate sort of like while statements? Meaning that they continuosly run in the background
#17
03/31/2009 (11:28 am)
they can run in the background, but that's not a defining feature.