# Updating bots/AI behavior after a fixed elapsed timestamp in game loop?

I am developing a HTML5 game in javascript. Now I have created a few bots and they should be able to change their orientation after a few seconds/a fixed timestamp in the game loop.

Suppose my game loop is like this:

function loop() {
bots.updateOrientation();
bots.render();
player.update();
player.render();
requestAnimationFrame(loop);
}


How can I make that happen in my game loop?

The easiest way is to use counters.

If you want your bots to do something in X frames, you'll have:

class Bot {
constructor() {
this.doSomethingCounter = 0;
}

doSomethingInFrames(n) {
this.doSomethingCounter = n;
}

update() {
if (this.doSomethingCounter > 0) {
this.doSomethingCounter--;
if (this.doSomethingCounter === 0) {
this.doSomething();
}
}
}
}


If you want your bots to do something after X milliseconds, have the counter track the number of milliseconds left:

  update(ms) {
if (this.doSomethingMs > 0) {
this.doSomethingMs -= ms;
if (this.doSomethingMs <= 0) {
this.doSomething();
}
}
}


Once you have a large collection of counters, it may be better to use a programming pattern. In the context of AI, you may want to look at a pattern like a behavior tree or FSM. Here's some places to start: New to creating AI - where to start?

Implement a que system, it gives lots of possibilities and freedom, and you'll be able to make chains of actions.

1. Maintain a que with 2 columns: 1) Timestamp and 2) Action

Add to this que new rows at any time. Apparently it's timestamps will be "now + a few milliseconds ... seconds, even hundreds of seconds in future". Each time a row is added, sort the table by timestamp, ascending; ie. the topmost row always holds the closest upcoming action.

1. During each game loop cycle, look at the topmost row. If it's timestamp is passed by teh games internal clock "now" (which ofc grows all time, as the application's internal clock advances), execute the action described it's column 2 and remove that row from the que table. If "now" is still smaller than the topmost timestamp, do nothing. Look only at the topmost row -> potentially each game cycle removes one row, and you'll get up to fps actions at most.

An action that gets executed can add one or several further action(s) to the que, to be executed in say 2 seconds. That action again can add a further one, etc.

To for example move the sun over the sky during an entire day, insert a que entry to happen in for example 10 minutes (action timestamp is Tnow + 600 seconds). As it finally executes (in 10 minutes), let the executed function insert "itself" into the que, with timestamp "now" + 600 seconds -> the sun will move all day.

Actions can be simple integer numbers, like: 1 = re-calc sun position 2 = refresh that guy that blacked out 2 seconds ago, etc.

Then just call the appropriate functionality based on action number. Plus have all the good housekeeping data handy :-).