Other than state machines

Posted By: jumpman

Other than state machines - 02/17/08 02:55

Not sure how to form this question, but Im going to try and explain whatever Im thinking right now.

ATM I am working on a State Machine AI, so far its reletively easy to implement, but exhaustive. So far I have many different states, some using the same pathfinding functions, which means alot of states might seem redundant. However I do understand that it could be made more modular, such as giving the entity only 1 pathfinding state, but changing the target node variable within that state. But this is the first AI state machine Ive made that works pretty well, so its a learning experience.

So far the problems I have is transitioning from state to state without noticable pauses. The state switching is more apparent when the AI is playing an animation and switching to a different state.

Another apparent sign of a state machine is when the AI state must perform a critical function that requires the AI to wait on other entities to send information back to the AI. This usually means a wait(); must be excecuted until relevent information the AI needs is received. This single wait may seem harmless, but is jarringly noticable for a moving, shooting, thinking AI. An example of this is finding the closest node to the AI, finding the closest enemy to the AI, scanning for enemies, cycling through a huge list or etc.

The only alternative I thought of was splitting the entity into 2 or more entities, each doing their part, even if some are still. I will continue using the single entity state machine for my current game, but would like to split it up for my next game.

My idea was to have the pathfinding function of a soldier be handled by a seperate pathfinding entity, while the animation and "tactical" thinking would be handled by the "model" entity. This way, when my soldier entity has to freeze for a single frame to calculate the A* path, his animation and AI thinking would continue to run, in attempts to help smooth over any stops in movement.

I would like to know if anyone has done a mix of state machines and fussy state machines, and how they went about their AI. Im not asking for code, just experience from people implementing this using 3dgs if possible.
Posted By: Christian__A

Re: Other than state machines - 02/17/08 19:22

I don't understand why you want to use 2 entities for your ai-functions? You can also split up your ai into many functions.

An simple example:
Code:

function ai_loop
{
while (1)
{
ai_think(); //This function retrieves information about the entities environment
ai_act(); //Here the entity realy moves, shoots...
wait(1);
}
}



ai_think sets variables like what_to_do_next... as soon as ai_act is ready with its current action (like shooting), it starts with the work specified in what_to_do_next...
Posted By: zazang

Re: Other than state machines - 02/18/08 02:59

You could even play some animation like "standing" "seaching" while it is doing some extensive AI calculations.
Posted By: PHeMoX

Re: Other than state machines - 02/18/08 16:48

Yeah, you should split up the functions and keep them as short as possible. Obviously pathfinding and so on will require some larger functions, but you can camouflage quite a bit with animations and so on,

Cheers
Posted By: A.Russell

Re: Other than state machines - 02/18/08 17:58

Pathfinding can very processor intensive and is best threaded out, or at least limitted by how many nodes/arcs are processed at one time.

Pathfinding is not really a good state to use. States could be, waiting, walking, fighting... an enity might change state from waiting to walking because of a result from the pathfinding algorithm, for example.

Which still leaves you with the problem of what if an entity changes state while it is still searching for a path (or other critical function)? When the pathfinding (or other critcal function) completes, it sends a message to the affected/ calling entity and the entity then decides what to do with it depending on the state it is in at that time. If changing state means that the pathfinding is no longer relevant, a request to stop searching can be sent. By sending messages between objects, everything can run autonomously. For your animation problem, you don't neccessarily have to stay in the same state because an animation is playing. If you are halfway through a run animation and your player switches to walk, have the walk state begin the walk animation from when the run animation reaches its keyframe.

Fuzzy logic is good if you want it possible for your entity to be in more than one state at any time. For example, in a state of GoingForPowerUp while ShootingTheCrapOutOfEverythingInSight.
Posted By: msl_manni

Re: Other than state machines - 02/19/08 08:24

The problem that Jumpman is having is the way he is coding. He is using wait(); everywhere so the function associated with the ai would pause in that particular frame. I would suggest that you should not use wait unless it is very necessary. Try to multitask your functions. Avoid waits() as these leads to poor programming. There are ways to circumvent it and then you can implement many behavioural types like suggested by others, brain searching for targets, for camouflage, managing health, talking to buddies, etc. Try to think all the tasks a human can handle simaltaneously, yet we have only two parts of brain, one concious, and second sub-concious.
Posted By: MadMark

Re: Other than state machines - 02/22/08 18:39

Hmm, seems the manual and advice in this forum is to use wait() in order to synchronize frames, allow functions to complete, and reduce coding collisions. You have some magic method that eliminates the need for wait()?

Care to share, msl_manni? This old dog is not a great programmer, so I would love to learn new tricks.

Mark
Posted By: msl_manni

Re: Other than state machines - 02/23/08 03:19

Dont be sarcastic. I said that use wait only in situations only necessary. But my dear friend, you are abusing it by using it everywhere. If you post your code then I might show my magic. But for that you have to be polite.
Posted By: MadMark

Re: Other than state machines - 03/13/08 01:30

LOL

No insult intended. Just curious what method you were using to overcome the need to "abuse" wait. Fair enough, no special methods. Of course eliminating unnecessary waits would optimize code. Sometimes you do have to just hurry up and politely wait(!).

Cheers!
Posted By: indiGLOW

Re: Other than state machines - 04/06/08 21:14

An example would be:
 Code:
Function DoThinking
{
	// Maybe search all ents for specific entity
	you = ent_next (NULL); // retrieve first entity
 	while (you != NULL) // repeat until there are no more entities
	{ 
		if(you == entIamlookingfor){dosomething...}
 		you = ent_next (you); // get next entity
 	}
}

Function Take Action
{
	turn to face entIamlookingfor... etc

}

Function AiBrain()
{

	While(me){
		DoThinking();
		TakeAction();
		wait(1);
}


In this example there is only one wait command, in the parent loop. The while loop within the DoThinking, does not wait, it searches ALL entities in 1 frame.

Hope that helps \:\)
Posted By: WolfCoder

Re: Other than state machines - 04/24/08 16:27

In C-Script, I usually have a single wait() function at the end of the entire state blending (it's where I have one, two, or multiple states processed depending on conditions). This will reduce frame rate but the entity would have done everything in a single frame, instead of spread out over multiple frames.

I'm used to writing things in C/C++ where *everything* possible is done in a single frame >_<

For C-Script, I separate the animations from the code like this:

 Code:
// All three of these have a while(my != NULL){... wait(1);} loop in them
// And any sort of 'cleanup' would be done right after the loop
// And any sort of 'init' would be done before the loop
function attach_animate(){...} // Will animate based on variables
function attach_path(){...} // Will decide to move based on variables
function attach_mind(){...} // Will decide to take actions based on variables

// Entity
action ai_ent
{
   // Stuff
   ...
   // Attach processes
   attach_animate();
   attach_path();
   attach_mind();
   // Stuff
   ...
}


Sorting crap into multiple looping functions will actually have the effect of doing everything at once in a single frame as long as each individual loop has just one wait(); in it.

If ya sort it correctly you can call the different functions and leave some out, or add others to quickly blend many different ai methods.

For example, you can separate each mind into different components so it's easy for multiple things to be blended together:
 Code:
function attach_distance_attacker(){...} // If the entity has a gun, then it will keep the distance from the closest target while firing if it decides to attack using a gun
function attach_close_attacker(){...} // If the entity has a sword or close weapon, then it will get in close to the target to attack
function attach_evasive_move_pattern(){...} // When fighting, the entity will focus on being hard to hit and will find ways to be hard to hit
function attach_aggressive_move_pattern(){...} // When fighting, the entity will charge at the target, trying to overwhelm the target preventing escape
function attach_item_search(){...} // The entity will search for items if needed
function attach_target_search(){...} // The entity will really want to find stuff to kill, as opposed to wandering around in exploration


For example, you can combine the charging with the gun, so the entity still keeps a distance, yet it chases after the player with a mechanical rage firing wildly, and the gun combined with the evasive one would have the entity keep distance and hide behind things here and there.

It may be obvious in the melee case to have the entity charge, but you could combine the evasive method to have the entity jump around and try to ambush the player, and run off.

This can be achieved by having the patterns know how much distance the entity wants to keep, and act differently by how close or how far the entity wants to be.

There's lots of ways to get these to work together, but I hope you get the idea.
© 2024 lite-C Forums