American Football AI
Guys:
I'm a bit new when it comes to AI and how it works. My feable brain thinks it might be easy, but as I do more complicated tasks, it may become worthwhile to do it the right way.
So, in theory it should work like this:
Player class
- Handles Collision with other Players
- Contains a Brain (which it updates per frame)
- If not User-Controlled, it uses brain, otherwise its dummy to you.
Brain class (specific qb brain, linebacker brain, etc.)
- Brain is in charge of moving and animating Player class
- Brain is knowledgable about the current animation its in (in case of tackling or being held)
- Contains states for various tasks (EX. PRE_SNAP_LINEUP)
- Each specific class contiains specialized states
Right now, I'm thinking this is all done with states, each state does certain things. Lets take a pre_snap state to mind. After the HUDDLE state, you go to pre_snap which just directs the player to where there suppose to lineup on the field and plays their stance animation.
Is this a good way of doing this? What are the pitfalls if any to this? Can anoyne suggest better alternatives to do this before I start implementation?
Thanks again!!
Jeff.
Using a state machine to represent the logical flow of activity is a very common approach in games and simulations. It's a very good place to start as you'll find a reasonable amount of literature online regarding this approach. You can easily link in animation control into your state machine using OnEnter() and OnExit() methods for each state that start and stop animations respectively (and do whatever else needs to be done to initialise or shutdown a behaviour).
What you need to add over the top of your state machine is the logic to control it's flow. Make sure you separate your logic (data) from your machine implementation (code) so that you can play with your NPC AI without needing to recompile your game. So, how do you design this control flow? Most people do it by hand for simple systems. Sit down and ask yourself what you would do in a given situation and implement that. You can add some vagueness into the execution by not using hard decision thresholds (using instead fuzzy or probabilistic thresholds, for example).
For example: The wide receiver has a set movement pattern during the play setup. When the snap occurs, send a message to your wide receiver player to start his run. His run path may be quite reactive based on opponent players in the way (and whether they're running toward him or elsewhere). At some distance into the run you could have the receiver look back toward the quarterback to determine if the ball was thrown (or you could simply tell the receiver it was thrown and let it decide if it wants to actually look or not). If the receiver looks AND the ball is headed his way, he could try to intercept it by steering toward a point where he could catch it.
You could break this into a hierarchical control. One layer controls the running (steering away from opponents and toward balls in flight), while another layer sets target points for running toward based on what state the receiver is in (e.g., the target point might be an arbitrary spot on the field after the initial snap, but would change to an intercept point after the receiver observes that the quarterback has thrown a pass).
Gridiron is actually a good game for trying out this style of AI because each of the players has clearly defined roles and only a few basic rules to define how they should act in any given situation. The complexity comes from the variety of players and how you decide to deploy them on the field at the start of the play.
So, my summary... yes, pursue a state machine approach... design the logical flow of the machine by hand... separate your logic from your implementation for more rapid design iterations... and have fun! ;)
Cheers,
Timkin
What you need to add over the top of your state machine is the logic to control it's flow. Make sure you separate your logic (data) from your machine implementation (code) so that you can play with your NPC AI without needing to recompile your game. So, how do you design this control flow? Most people do it by hand for simple systems. Sit down and ask yourself what you would do in a given situation and implement that. You can add some vagueness into the execution by not using hard decision thresholds (using instead fuzzy or probabilistic thresholds, for example).
For example: The wide receiver has a set movement pattern during the play setup. When the snap occurs, send a message to your wide receiver player to start his run. His run path may be quite reactive based on opponent players in the way (and whether they're running toward him or elsewhere). At some distance into the run you could have the receiver look back toward the quarterback to determine if the ball was thrown (or you could simply tell the receiver it was thrown and let it decide if it wants to actually look or not). If the receiver looks AND the ball is headed his way, he could try to intercept it by steering toward a point where he could catch it.
You could break this into a hierarchical control. One layer controls the running (steering away from opponents and toward balls in flight), while another layer sets target points for running toward based on what state the receiver is in (e.g., the target point might be an arbitrary spot on the field after the initial snap, but would change to an intercept point after the receiver observes that the quarterback has thrown a pass).
Gridiron is actually a good game for trying out this style of AI because each of the players has clearly defined roles and only a few basic rules to define how they should act in any given situation. The complexity comes from the variety of players and how you decide to deploy them on the field at the start of the play.
So, my summary... yes, pursue a state machine approach... design the logical flow of the machine by hand... separate your logic from your implementation for more rapid design iterations... and have fun! ;)
Cheers,
Timkin
I did this silly demo a while ago to test some hobby work of mine.
In this video it works like this:
A goal-oriented system decide on a particular behavior, like pass , tackle or run to the goal, depending on the game situation.
At each frame, the behavior class selects actions and steering behaviors.
The animation system then makes the player move according to the sum of the steering behaviors, and play any other anim if necessary.
Later on I replaced the goal-oriented system with a planner, and it was much more elegant (simpler scripts for the same-or-better result). It is probably better to begin by a state-machine to select the appropriate behavior class tho.
In this video it works like this:
A goal-oriented system decide on a particular behavior, like pass , tackle or run to the goal, depending on the game situation.
At each frame, the behavior class selects actions and steering behaviors.
The animation system then makes the player move according to the sum of the steering behaviors, and play any other anim if necessary.
Later on I replaced the goal-oriented system with a planner, and it was much more elegant (simpler scripts for the same-or-better result). It is probably better to begin by a state-machine to select the appropriate behavior class tho.
Great stuff!
Thanks guys. OK, I'm proceeding with my original thoughts with state machines.
I have a more specific AI question.
(I used source code tags to preserve my tabs)
Does this seem good?
Thanks again
Jeff.
Thanks guys. OK, I'm proceeding with my original thoughts with state machines.
I have a more specific AI question.
- General:Lets say you have an Offensive Guard. His job is to protect the Quaterback (QB)..- Logic:OnUpdate:* if not in collision battle * Get QB position * Get position of nearest defender * move to point between nearest defender and QB * don't move exactly between qb and nearest defender * move sideways in the path of the nearest defender* else * wait till collision animations are done...Does that seem correct? I will also be updating my position constantly...One more Example..- General:You have a Cornerback (CB). His job is to defend the Wide Receiver (WR)..- Logic:OnUpdate:* if not in collision battle * if the ball has not been thrown * get wr you're guarding * move to point in front of him (in the direction hes going) * else //ball has been thrown * move toward catch point and try to catch* else //in collision * //continue with collision animation.
(I used source code tags to preserve my tabs)
Does this seem good?
Thanks again
Jeff.
Seems like a good start, tho you are likely to discover some traps. For example, if there are two guys near the QB, your Offensive Guard might "jiiter" between two directions, as the "nearest" one can frequently change.
Why didnt you put Collision Battles as a State? It would save you some complexity.
Why didnt you put Collision Battles as a State? It would save you some complexity.
You're going to have to provide some form of communication between your players so that they don't go for the same targets (e.g., two of your players unintentionally blocking the same opponent player, or your corner back trying to catch a ball your wide receiver is already well placed to catch). You could do this either by using a central list of which opponents are already being targeted, or you could have players communicate with just those other friendly players near them (and perhaps restricted to certain types).
Cheers,
Timkin
Cheers,
Timkin
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement