Random Event Scripting

Started by SilverSpook, Tue 02/06/2015 11:49:42

Previous topic - Next topic

SilverSpook

What's the best way to go about having a random event happen repeatedly in a room at random time intervals?  For example, a robot does a brief fidgeting / nose scratch animation at a random time.  The first time there is a 8 second delay, the next a 5 second, then ten seconds, etc.. 

Mandle

I forget the exact syntax but something like:

SetTimer Scratch(Random(10)+5);

(Sorry, have a look in the manual for exact syntax or just use the auto-filler in AGS. This is what I always do ;) )

This would give a time between about 5-15 seconds between each scratch.

Slasher

The trouble when using randoms in the same 'condition' is that a random may run the same event again and again before another is run.

if you want three separate events to run one after the other then you could set up separate timers (one for each event of time). when one timer expires it starts the next one etc. on the last timer the first timer gets reset and it all runs again.

This way the timed events run in sequence.

There may (probably) of course be another way...



Snarky

Absolutely not, slasher. You never want to use multiple timers for one linear series of events.

Mandle's solution looks satisfactory in principle (if not in syntax), but if there's some need to vary the actions taken according to some pattern, you can simply use an integer as a simple state machine. (Increase the value each time an event is run, and do a different event depending on what the value is.)

Khris

Here's code:
Code: ags
  // in AfterFadein
  SetTimer(1, 10 * GetGameSpeed()); // start timer loop, ten seconds

  // in RepExec
  if (IsTimerExpired(1)) {
    robotStuff();  // call function
    SetTimer(1, (Random(10) + 5) * GetGameSpeed());  // restart timer, 5 to 15 seconds
  }

Mandle

Quote from: Khris on Tue 02/06/2015 15:55:19
Here's code:
Code: ags
  // in AfterFadein
  SetTimer(1, 10 * GetGameSpeed()); // start timer loop, ten seconds

  // in RepExec
  if (IsTimerExpired(1)) {
    robotStuff();  // call function
    SetTimer(1, (Random(10) + 5) * GetGameSpeed());  // restart timer, 5 to 15 seconds
  }


Firstly Khris: thank you for coming back to these Q&A forums: I always find your words valuable even if they were not something I was concerned about right at the moment

If I understand this code correctly it means that the robotStuff will occur between 5-15 seconds no matter what the game speed is set to by the user?

Awesome learning experience for me! It always annoyed me in AGS games that pumpng up the game speed meant that everything had to run faster and look like a VCR on fast-forward...If you are careful with the coding then you can also set the sprite animation to a global time instead of it speeding up as well I'm guessing?

Khris

Thanks :)
Quote from: Mandle on Tue 02/06/2015 16:17:49If I understand this code correctly it means that the robotStuff will occur between 5-15 seconds no matter what the game speed is set to by the user?
Yes, really helpful for games with a speed slider (or if you start creating a 40 FPS game, then decide to change the speed later on.)

Regarding sprite animations, this shouldn't be necessary though. As I'm sure you know, early games had speed sliders because they relied on CPU cycles for timing; getting the VCR effect is exactly what's supposed to happen; it's about slowing or speeding up the entire game, not just the character's walk speed. That's the only reason for the speed setting, and modern games should not need it at all.

If you need more control over your animation speeds, simply use a higher GameSpeed, but don't allow the player to change it unless there's a compelling reason. For instance if you find that a character's AnimationSpeed setting of 4 is too slow, but 3 is too fast, you can set the game's speed to 60, then use 5 (which is equivalent to 3,333 in a 40 FPS game).

Crimson Wizard

#7
As stated in manual, GetGameSpeed "returns the current game speed (number of cycles per second)".
This means that
Code: ags

int ticks = GetGameSpeed(); // this will be equal to one second
player.Animate(0, GetGameSpeed() * 3); // character will animate for 3 seconds


The problem with GetGameSpeed, however, is that if there is any possibility that game speed may change, you should not store any value calculated with it for a long period of time.
If you store return value of this function in a global variable, then the game speed will be changed somehow (by script, or by user), this value will become obsolete (incorrect in current game state), and you would need to calculate a new one.

Snarky

Quote from: Khris on Tue 02/06/2015 17:16:38
Regarding sprite animations, this shouldn't be necessary though. As I'm sure you know, early games had speed sliders because they relied on CPU cycles for timing; getting the VCR effect is exactly what's supposed to happen; it's about slowing or speeding up the entire game, not just the character's walk speed. That's the only reason for the speed setting, and modern games should not need it at all.

If you need more control over your animation speeds, simply use a higher GameSpeed, but don't allow the player to change it unless there's a compelling reason. For instance if you find that a character's AnimationSpeed setting of 4 is too slow, but 3 is too fast, you can set the game's speed to 60, then use 5 (which is equivalent to 3,333 in a 40 FPS game).

Well, the compelling reason would be to allow players to speed up the game if they want to. People have different preferences and levels of patience.

SMF spam blocked by CleanTalk