Advertisement

ai framerate independence

Started by February 07, 2002 09:57 AM
16 comments, last by Edgware 22 years, 9 months ago
Hi All this could be interpreted as a ''not strictly ai question'' but here goes. Say I have several computer controlled characters with some sort of ai. Now say I wanted to update their ai however I dont want to update the characters every frame as the characters do not neccesarily have to be updated every frame (eg updating a bots state 60 frames per second may not be needed - may only update the computer agents state every 20 frames or so). I know that you could work it out with a simple counter and an if statement but are there other approaches eg spreading the ai over several frames? What are the approaches to ai frame rate independence ? Any ideas or suggestions
just look at a timer to get the point of time where the AI should be updated, don''t count frames ... i think that''s all

@$3.1415rin
Advertisement
You could (and probably should) consider threading your AI. It''s then easy to rate-lock your AI by simply putting the thread to sleep when your processing is done for the current time step.

HTH,
ld
No Excuses
Gamasutra had an article a while back which discussed this (among other things). It's a good article and gave me a lot of ideas.
It was something about implementing an "instant replay" feature. Try combining it with a scheduling system as described in their "egocentric AI" article. I have had some good results from this approach.

Edited by - plasmadog on February 7, 2002 8:45:55 PM
You are not the one beautiful and unique snowflake who, unlike the rest of us, doesn't have to go through the tedious and difficult process of science in order to establish the truth. You're as foolable as anyone else. And since you have taken no precautions to avoid fooling yourself, the self-evident fact that countless millions of humans before you have also fooled themselves leads me to the parsimonious belief that you have too.--Daniel Rutter
First of all, your physics and AI and rendering code should be completely independent of each other. So all of your objects should have a render() and update() call. Your main game loop should guarantee an update rate for the logic/AI (say 60hz) and you should render as often as possible.

This way, you guarantee how often your logic/AI code runs and it isn''t tied to how fast you can draw the frame.
I feel a stupid question coming on...

Here it is: How do you thread somehting? What exactly is thread?
Advertisement
multithreading ur ai might not be good - - what was one of those rules? dont multithread if your thread has to wait or sync to other threads? you dont want to start processing ai if your in the middle of rendering...

one thing u can try to do is process ur ai when ur waiting around, to say, sync a frame. this way, you arent necessarily processing ai when you could be drawing. however, this may not guarantee that your ai is ever processed very well, or, it may be over processed (if thats possible), so you will probably want to force process sometime or antoher.

it really depends on what kind of ai u got, is it hardcoded, or a script, or what? its really hard to tell you how/when to process your ai without knowing how ur implementing it.

if your using a script/scriptor, then its always possible to script in very small amounts each iteration. if its hardcoded, then things could get ugly...
umm, if you are multithreading nearly anything you will always have some sort of semaphore. ther are cases were this aint true, but if the thread is that seperated from your processes, then there is no point in running it in your processes. you could easily sync your ai to rendering without the ai interupting the rendering (well to a noticiable point). first you have the ai do its thing every x ms (sleeping when its not doing anything). render thread goes about its merry way except at the end of its cylce does a Sleep(0) to give up its reamaining time. the only time the ai thread haltst he render thread is when it needs to copy the game state. which would not take very long and would only halt the render thread at its start. look into CriticalSections() to ensure your cpu time gets splitthe way you want it, but becareful, you can seriously hose performence if used incorrectly.

now on to the question at hand. multi threading is not the answer. like framerate independent physics, you do the same thing for your ai. you render ai ever x ticks where x is some value of ticks. you can then render physics at some other value of ticks. these ticks are NOT what you get form getTickCount() and are not related. see the fixed time step rendering article which was here or on flipcode.com, it will show you a better idea of whats needed to be done then i will try to explain. but basically you do:

  // PSUDEO code#define TICK_MS_PH 33 // 30 times per second#define TICK_MS_AI 50 // 20 times per second#define MAX_LOOP 7 for(;;){   curTime = gettime();   maxCnt=0;   while((curTime-timeAI)>=TICK_MS_AI || maxCnt>MAX_LOOP)   {      // this would be 1 "frame" of ai      // and should update all things that need to be updated      Do_FakeSmart_Stuff();      timeAI+=TICK_MS_AI;      maxCnt++;   }   // not sure if it would be better to update this   // again or not, test both ways   //  though this way MAY be more accuarte   curTime = gettime();   maxCnt=0;   while((curTime-timePH)>=TICK_MS_PH || maxCnt>MAX_LOOP)   {      Do_Fancy_Moving_Stuff();      timePH+=TICK_MS_PH;      maxCnt++;   }   // physics would dictate the interpolation between frames   float percentInFrame = timePH/TICK_MS_PH;       if(percentInFrame>1.0) // in case you bailed early        percentInFrame=1.0;   Render(percentInFrame);    elapsed=curTime-oldTime;}  


hope that helps explain what ppl have been suggesting (at least thats what i hope ppl were suggesting ). just be forewarned, the above psudeo code has a MAJOR flaw, and that is the ai will NOT see movement if the framerate drops too much. you really should be syncing your ai to your physics since when the world changes the ai should change. otherwise your ai will seem very flaky on slower pcs (any pc that can not handle approx double (this assumes ranges that go from 30-90) the framerate your shooting for in smallest tick length) going after things that are not there and such. you should be able to figure out what goes and what stays.

though for true spreading of ai over frames like you suggest would require multi threading or very good time keepign and a scripting system like in unreal. but in that case you are then doing multi threading any, just not with windows threads.
quote: Original post by Puzzler183
I feel a stupid question coming on...

Here it is: How do you thread somehting? What exactly is thread?
Don''t take this as gospel since it''s just my fairly simplistic understanding, but a thread is like a separate process - a set of instructions that takes up some portion of the cpu''s time.

Most computers only have one cpu, so they can only process one instruction at a time (not strictly true but close enough approximation). So they work on instructions in sequence/serial/one at a time. Creating a thread just means you have a new set of instructions that you want the computer to process. The computer then divides its time between that set of instructions, and any other threads that were already in progress. How the cpu divides up its time between different threads is up to the operating system, although you can usually give it some strong hints as to what you want it to concentrate on.

So for instance if you had 2 threads called a and b, then your cpu "instructions processed" timeline might look like :
ababbababaabaababababbbaabbababababa
The advantage of this is that if there isn''t much being done in a then the processor will do more of b''s instructions. The other (bigger) advantage is that you don''t have to worry about calling the AI to do calculations (much) - most of the time you can be sure that the cpu will be spending some time on the AI if it is in an active thread.

So what is being suggested is that you have the AI in a separate thread so that you have the cpu dividing its time between the main game thread and the AI thread without you having to code specifically for it. However, as has been noted, you don''t want the cpu switching to doing some AI instructions in the middle of an important tasks like updating the graphics. There are solutions to this which include suspending the AI thread until the grphics update is finished or giving it a low priority, but those are just technical details.

Of course there are concerns with threading such as synchronization, but as long as you know what the options are then you know what to look up.


if you thread ANYTHING using the os level calls, make sure you use Sleep() in your game loop or your threads will not get much time at all (read not enough for the ai to be run at a decent rate). if the ai AND game thread both compete for time, its all downhill. multithreading is a pain, and difficult to get right especially in realtime things such as games.

This topic is closed to new replies.

Advertisement