Schedulers and Finite State Machines

Hi all,

I am new to this site, but have visited many times over the last few weeks whenever I needed a question answered. I usually just did a search and found the answer right away without having to post on the forums. But, I've come to a bit of a roadblock, so decided to register and try my luck on the forums... Hopefully I am posting this in the correct category!

I have been programming in C++ on and off for a while now, but definitely no expert. I guess I am between the Novice and Intermediate stages of my C++ abilities. A little bit rusty, but I figure the best way to remember as well as get better is to code, code, and then code some more. Anywho, I'll stop blabbing and get to my problem. :)

The project I am on right now is a small, text-based RPG game. I wrote a lot of this game in Perl already a while back, but planning to re-write it in C++. A few lines of pseudocode in, and I'm already seeing a major problem... I think I may have a need for a scheduler in the code to manage things. Not sure if a preemptive or a cooperative scheduler would work better. Actually, I am very new to the idea of scheduler...

I figured that I may have a problem when I started trying to plan the NPCs in my game. How would they move from room to room? What would cause them to attack another player, or possibly another NPC? Doesn't seem that difficult, until I realized that they would have to figure all that out by themselves, while the human player went about his merry way doing whatever it is that he wants to do. Also, how would the program control multiple NPCs moving from room to room, and attacking, etc., all simultaneously?

Started looking into using Finite State Machines (FSMs) to control the behaviors of the NPCs, which seems more efficient than huge if-then statements. But, seems like a FSM would only control how one NPC behaves. I am still seeing the need for a scheduler controlling each NPC (or, at least, scheduling each FSM), as well as handling input from the human player. Unless I can do all that with one complex FSM??

Does using schedulers and/or FSMs seem like a plausible solution to my problem? Also, is it even possible to code a scheduler into a C++ program? Or would I have to use a system scheduler (outside my program)? All I could find on google about schedulers was about the operating system or actual hardware. I just want to create a program that can multitask. I guess it sounds easier than I at first thought...

Any tips or URLs on scheduling in C++ programs would be greatly appreciated. And/or maybe any close-at-hand source code snipets to help my lightbulbs turn on :)
Wow. Now that's what I call overthinking.
http://en.wikipedia.org/wiki/Game_programming#The_game_loop

Even if you don't use that for everything, there are still far better ways than whatever mess you were considering. For example, why write your own scheduler when you can take advantage of the system's and use threads?
And FSM for NPCs? What exactly will these NPCs be doing?
Last edited on
FSMs actually aren't all that uncommon in game NPC AI routines. They are used to implement different AI behaviors. An RPG AI NPC might have numerous different types of behaviors. Patrolling behavior, Sentry behavior, Casual behavior, combat behavior, panic behavior, etc. etc. An FSM would be used to handle which behavior is currently guiding the NPC, and what triggers will cause it to switch behaviors.

A scheduler, on the other hand, is overkill for a small text-based RPG. The standard game loop should be more than sufficient.
Thanks for the quick replies! And yes, I have been told by many people that I think WAY too much :)

I checked out the game loop URL posted, and it sounds like it would work perfectly for what I'm trying to do. But, the first action the loop executes confuses me. How can I check for input while the program is still running? I would still want the game to progress even if the human player has not typed any commands. I think that I might be able to do this with old C-style commands, like capturing one character at a time. But, is there an easier way of capturing a string from input without the program actually pausing to wait for the input? Maybe storing it into a buffer and then the next iteration of the loop checks to see if there is any input in the buffer? That I can figure out, but the program still pauses to wait for input...

I would like to try creating this particular program without using threads, if at all possible. I don't think I am quite experienced enough yet to start multi-threading. Every time I look at pthreads, or even boost::threads for that matter, it makes my brain hurt.
Nothing in the C or C++ standard libraries is prepared to get input in a manner usable by a game. You'll need to either use system calls, or functions provided by a game programming library (or a library of some other kind).

There's really nothing at all complex about threads. Both pthreads and boost::thread are easier to use than, say, the Windows thread API. To be honest, I'm surprised that you find threading hard if you were considering writing a scheduler.
Last edited on
There's really nothing at all complex about threads.


Would you be able to provide any good tutorials on threads? Everything I have found so far seem pretty complex to me... Also, never used the Windows thread API either. In fact, I try to stay as far away from Windows as humanly possible. Microsoft is the devil. :)
[Some thing] is the devil.
*Eyeroll*
While that works on certain communities (communities with generally dim members, mostly), we don't exactly care for that attitude.

Here's a short example with boost::thread. It should be enough to get you started:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <boost/bind.hpp>
#include <boost/thread.hpp>

void f(boost::mutex *m,int x0,int x1){
    for (int a=x0;a<=x1;a++){
        //Always lock access to shared resources (e.g. global variables and
        //objects, buffers, IO streams, etc.). You don't want to have to debug
        //race conditions.
        m->lock();
        std::cout <<a<<std::endl;
        m->unlock();
    }
}

int main(){
    boost::mutex m;
    boost::thread a(boost::bind(f,&m,1000,1100));
    f(&m,2000,2100);
    a.join(); //wait for f() to return
    return 0;
}
Topic archived. No new replies allowed.