Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: MaximusDecimus on Mon 17/10/2011 05:29:19

Title: Should I be using the Wait function or timers?
Post by: MaximusDecimus on Mon 17/10/2011 05:29:19
I'm making a RPG battle simulation game (it has a battle system similar to Quest for Glory II). I've set the opponent to attack repeatedly using the repeatedly execute function in the global script. But, if I want the opponent to attack the player every X game loops, I have to either use timers or the Wait function. With timers, it's overly complicated and I can't get everything to work properly, but if I use the Wait function, it also freezes all other scritps!! It be so much simpler if AGS had a delay function or something: wait X game loops, then proceed to the next line while not pausing all the scripts.   :-\

Specifically, when the opponent starts an attack, the function needs to wait 4 game loops before playing the attack sound. Then, after 10 game loops, it has to play the hit sound and subtract some hit points, after 80 loops the opponent can attack again ... How to do these simple delays? Please help because I'm kind of stuck.  
Title: Re: Should I be using the Wait function or timers?
Post by: Gilbert on Mon 17/10/2011 06:07:30
Or, try the third option. Use a variable as your own timer/counter.

You set a variable to a certain value at the beginning and then decrement it every game loop. You can use if{}else{} statements to trap the variable and do whatever you want when the counter reaches a certain value. Something like:
First declare the variable on top of the room script:
int attcoutn;
When entering a room:
attcoutn=80;
Then in repeatedly_execute():

attcoutn--;
if (attcoutn==76){ //after 4 loops
  //play attack sound
} else if (attcoutn==66) {//10 more loops
  //play hit sound
  //subtract hit point
} else if (attcoutn==0){
  attcoutn=80;
}
Title: Re: Should I be using the Wait function or timers?
Post by: MaximusDecimus on Mon 17/10/2011 06:33:18
Thanks for the fast reply! I'll try it out.
Title: Re: Should I be using the Wait function or timers?
Post by: Khris on Mon 17/10/2011 09:52:22
Quote from: MaximusDecimus on Mon 17/10/2011 05:29:19With timers, it's overly complicated and I can't get everything to work properly, but if I use the Wait function, it also freezes all other scritps!! It be so much simpler if AGS had a delay function or something: wait X game loops, then proceed to the next line while not pausing all the scripts.   :-\

You're funny.
Title: Re: Should I be using the Wait function or timers?
Post by: Snarky on Mon 17/10/2011 11:26:58
I don't think it's at all an unreasonable thing to wish for. So instead of something like:


function foo()
{
  // script part 1
  SetTimer(1,40);
}

function bar()
{
  // script part 2
}

function repeatedly_execute()
{
  if(IsTimerExpired(1) == 1)
    bar();
}


You'd get something like:


function foo_bar()
{
  // script part 1
  WaitNonBlocking(40);
  // script part 2
}


That would obviously be much more straightforward to code and read (especially for newbies), and since in my experience this is often the effect you're trying to create, it would be nice if AGS streamlined it more.

Of course, I can see how it opens up a lot of other issues, like storing/restoring the stack (i.e. the expectation would now be that local variables could still be referenced after the pause), figuring out the order of execution, and dealing with all the fun new ways people could shoot themselves in the foot.
Title: Re: Should I be using the Wait function or timers?
Post by: Khris on Mon 17/10/2011 12:05:09
I guess purely from a technical standpoint it would be possible to have a keyword that gets the function to run in its own thread so one could actually use Wait().

What I meant by my comment is that while the request does sound reasonable, it's a SMOP.
The way I see it, being able to deal with this limitation is simply a required skill.
Title: Re: Should I be using the Wait function or timers?
Post by: Snarky on Mon 17/10/2011 12:23:08
Well, a more reasonable solution, and what you'd do in many languages (such as Javascript, IIRC), is to call a timer with an event handler that you provide as an in-line anonymous function. Something along the lines of (in pseudo-script):


function foo_bar()
{
  // script part 1
  SetTimer(40, new function()
  {
    // script part 2
  });
}


Not denying that it'd be a lot of work to add function pointers to AGS script, mind.
Title: Re: Should I be using the Wait function or timers?
Post by: Calin Leafshade on Mon 17/10/2011 13:14:42
I dont think function pointers (which is essentially what youre talking about) would actually be that much work to implement.

AGS obviously already links functions and stuff. You just need to save the pointer and run it at the right time. its just a variable really and AGS already runs script functions from their pointer.

Teaching the compiler to behave as Snarky describes is more difficult but something like this is more likely:


function foo() {
//lol
}

function bar() {
  DoShit(foo);
  //or possibly without altering the compiler
  DoShit("foo");
}
Title: Re: Should I be using the Wait function or timers?
Post by: Calin Leafshade on Mon 17/10/2011 15:49:39
BAM!

http://www.thethoughtradar.com/AGS/AGSDelegates.zip

Delegates for ags. Used like this (obviously this is a silly example but delegates can be used as variables in functions like snarky suggested above):


Delegate *del;
int counter = -1;

// put here anything you want to happen every game cycle, even when the game is blocked
function repeatedly_execute_always()
{

 if (counter > 0) counter --;
 if (counter == 0 && del != null)
 {
   del.Run();
   counter = -1;
 }
}

function theCallback()
{
 Display("A ha!");
}

// called when a key is pressed. keycode holds the key's ASCII code
function on_key_press(eKeyCode keycode)
{
 if (IsGamePaused()) keycode = 0; // game paused, so don't react to keypresses
 if (keycode == eKey0)
 {
     counter = 100;
     del = Delegate.Create("theCallback");
 }

}


the delegated function must be in the global script but i guess i could set a switch so you can use it in rooms too.

I know no one will use this but it was a nice proof of concept.
Title: Re: Should I be using the Wait function or timers?
Post by: monkey0506 on Tue 18/10/2011 19:27:51
Calin, I'm sure you're already aware of this, but dynamic delegates also would allow run-time scripting to take place...that is pretty nifty I think, and it was listed as one of the selling points of both the C# Runner and the Lua plugins. Neither were, to my knowledge, raging successes that took the AGS world by storm, but still cool nonetheless.

void RunScriptFunction(String name)
{
  Delegate *func = Delegate.Create(name);
  func.Run();
}

function txtFunction_Activate()
{
  RunScriptFunction(txtFunction.Text);
}
Title: Re: Should I be using the Wait function or timers?
Post by: MaximusDecimus on Tue 01/11/2011 05:30:38
Ok thanks for all the replies, I got it working now.
Title: Re: Should I be using the Wait function or timers?
Post by: Monsieur OUXX on Tue 01/11/2011 15:54:45
Hey, I hope Calin's delegates will go STRAIGHT to the modules forum, as it's a major hack to AGS' script limitations. All existing modules could potentially take advantage of this (not necessarily from a performance perspective, but from a usability perspective).

Also, how the beep did you do this so quickly and in such a clean manner, the grammar parser is such a mess (that's a rethorical question).