Jump to content

Unit AI

Recommended Posts

Some thinking-out-loud about how the unit behaviour should be designed and implemented:

As the most fundamental feature, players should able to give orders to units (usually by clicking on targets or on buttons):

* Stop

* Move (to a target point, generally ignoring enemies)

* AttackMove (to a target point, generally attacking enemies)

* PatrolMove (move to point then repeat the patrol route)

* Attack (either a target entity or a target point)

* Gather

* Build

* Repair

* Garrison (in a building or ship)

* FetchGarrison (ships may need to move towards shore in order to let units on board)

* Unload (let garrisoned units off)

* Pack (siege equipment transforming between modes; can't respond to other orders while changing)

* Unpack

* Are there others that I'm forgetting?

(Most of the stuff here doesn't need to be implemented now, but the design ought to allow it to be added without having to rewrite the whole thing.)

Players should be able to give a series of orders (typically by shift-clicking) - after the first order is completed (or found to be impossible), the unit will start the second order.

Behaviour can be changed by assigning stances:

* Defend (attack nearby enemies, then return to original location/task)

* Attack (attack and chase nearby enemies)

* Avoid (run away from enemies)

* Stand ground (attack enemies in range but don't move)

* Hold fire (don't attack anyone or move at all)

Units can therefore choose to attack an enemy automatically, but the player's orders should usually take priority. (For simplicity, let's say they always take priority. If I tell a unit to attack a particular enemy, he will head towards that enemy no matter what tries to distract him or kill him. Units will only attack automatically if they have no remaining orders.)

State machines are the obvious thing to use. Orders usually involve multiple states, e.g. an attack order requires an 'approach target' state then perhaps a 'charge at target' state (when close enough), then a 'hit target' state and perhaps a 'chase after fleeing target' state.

I think there will often be common behaviour for all the states associated with a particular order - e.g. when executing an attack command, regardless of which particular state has been reached, if the target dies and there are no more orders then the unit should pick a new target to attack; but when executing a gather-resources command, if the target dies then the unit should pick a new one to gather resources from. I'm not entirely convinced but I think it's probably worth using a hierarchical state machine to allow sharing behaviour between sub-states: define a TargetDied handler for the 'attack' state, and it will be used for all the sub-states (attack.approaching, attack.charging, attack.hitting, attack.chasing) unless they override it.

Each unit would have a queue of orders, and the one at the top is what they're currently executing. When they finish, they pop it off the queue and process the next one. If it's a patrol order, they'll add it to the end of the queue so they'll repeat it. If there's no remaining orders, the behaviour depends on the current state and defaults to switching to the 'idle' state. Some of these orders might be automatically generated (when automatically attacking or gathering etc).

Units can be in a few different modes: the standard individual mode; garrisoned (they can respond to attack orders but can't move); in-formation (their movement and attacks are very constrained). Those modes would probably be states in the top level of the hierarchy.

Wild animals should probably use the same basic AI system, but with a completely different (and much simpler) set of states.

I think this ought to be flexible enough to handle adequately intelligent behaviours, and structured enough to be implemented in a relatively-easy-to-edit form (not a tangled mess of code), so I probably just need to try implementing it and see how it breaks...

Link to comment
Share on other sites

Scout sounds like one to add to the list.

Hmm, delete probably wouldn't need to involve the AI so it wouldn't be an order here (it would just force health to 0 or something). Town bell is interesting - maybe it's equivalent to simply selecting each unit and telling them to garrison in the town centre, so it would be the same as the normal Garrison order as far as the AI is concerned, or does it need to act slightly differently?

Link to comment
Share on other sites

Ringing the bell a second time unloaded all the units and sent them back to their previous tasks.
Ah - and if you unring the bell while the units are still heading towards safety (but haven't reached it yet) then they should turn around and go back to their tasks, whereas units carrying out a normal garrison order shouldn't act like that, so it sounds like we do need a separate order and separate states for units that are running for cover vs garrisoning normally (even we didn't need a separate animation for them).

I've started trying to implement some of this, though I thought it was best to start small so I just wrote a chicken brain. Try the Latium map and watch the chickens, and try sending some spearmen to gather from them.

Link to comment
Share on other sites

I think in AOEII if there where more units called by the Bell than there was room in the Town center the extra units would garrison inside of the nearest building. (barracks, stable, tower, etc.) Then they would return to work after the bell rang the second time. If they still ran out of room I think the extra units stood helplessly next to the building they tried to enter.

Might another stance be Protect? This stance would allow for a stronger unit to follow another (weaker) unit and attack any enemy that may try to kill it. Could also protect buildings.

Edited by DerWer
Link to comment
Share on other sites

I've started trying to implement some of this, though I thought it was best to start small so I just wrote a chicken brain. Try the Latium map and watch the chickens, and try sending some spearmen to gather from them.

Cool, the map is instantly more alive. :) I guess they shouldn't be quite as scared as that though, it's impossible to catch them :) (I'm guessing that would not be a problem once killing the animal and then gathering from it is implemented, so the AI part probably won't have to be edited for this to work well. At least not in great detail.)

I doubt healers should flee, after all they're useful (could even be vital) in a battle situation. It would be nice if they automatically tried to be at a distance from the enemy to stay safe, but it's not necessary for now at least. Automatically healing injured units is definitely needed though, not having that makes healers so much less useful in many games ;)

Link to comment
Share on other sites

it's impossible to catch them :)
Yeah, currently the chickens easily outsmart the soldiers - you have to surround them with half a dozen men to stop them getting away. But it's not surprising the chickens want to run, given that you're trying to extract meat from them while they're still alive. It'll be more humane when we get people to kill the animals first, which ought to be pretty easy (just treat the chicken like a normal attackable unit, then have it turn into a corpse almost (though not quite) like any other unit and let people gather resources from its corpse). In the meantime, we can just advertise catch-the-chicken as a fun minigame.
Link to comment
Share on other sites

* Attack (either a target entity or a target point)

If you click to attack on one unit in a group of enemies and it gets killed before you troops reach it, then it would be quite nice if the troops would not just stop but still advance to that group of enemies.

Link to comment
Share on other sites

I rewrote the unit AI to use the new system now, which I think makes more manageable (it's still slightly more complex than I'd like but it's easier to control how it responds to the various events in every possible state).

The user-visible changes are:

* You can queue up orders by holding shift when clicking, and the unit will do them after it's finished what it's currently doing.

* If a unit is attacked (and isn't already in combat), it will attack back and then return to its original task.

* If a unit is building a farm, and has no other orders, it will start gathering from the farm once it's complete.

There's still more that should be added (particularly automatically attacking visible enemies, and automatically moving to new resources after the current one is exhausted) which I'll try to do soon, but I think this works okay as a basic AI framework for now.

Link to comment
Share on other sites

Hi, im just a lurker, but the chicken thing looks interesting :)

The chicken wont need to "detect" an aggresor?

I think that a unit should be able to reach a chicken that is not FLEEING or on an intermediate state (like AWARENESS or WARNING)

That is, the unit kill a normal chicken (busy ROAMING), all the other animals and enemies around change from normal to a warning level, if the unit tries to immediately approach too much to a warning-chicken, it will flee, but if wait a bit, some of them can calm down and return to the normal state (an awareness state can be useful against spy/disguised units too, just remembered the spies and dogs from the old C&C RA)

Well, it is just an idea

I like the way that is progressing all the work, congrats ^^

srry for my english ^^;

*back lurking*

Link to comment
Share on other sites

Welcome :)

That might be an interesting thing to do - you'd be able to hunt some animals easily without chasing them all across the map, but it would effectively limit the rate at which you could hunt a group in a small area (since once you kill one all the others will be hard to catch for a while). We probably shouldn't put too much work into the animal AI, since this isn't a farm simulation game, but if we can do interesting things with the dynamics of hunting and make it slightly more fun than harvesting trees then it may be worthwhile :)

Link to comment
Share on other sites

My two cents: I think harvesting eggs would be something that would become an unnecessary task. Experienced players would probably ignore it and work on only the most efficient ways to build and attack their opponents; while newer players would be busy trying to harvest eggs while the other team rushes them.

The only way I could see this would be in place of a farm. Build a coop or something and chickens will be there. send villagers back and forth to harvest from it. upgrade to larger and larger coop or something if you want to use upgrades.

Otherwise, stick with slaughter, IMHO.

Link to comment
Share on other sites

True, but I think that's a benefit of corralling/herding that it doesn't require you to micromanage it, you just put the animals in the corral and the benefits are automatically rewarding, giving you more time to focus on other things, like combat :)

Link to comment
Share on other sites

Hmm, what time? You find the units on the map, you send them to the corral (if you have it built already, otherwise you have to build it of course, but if you'd remove building I'd say there'd be too little economy in the game :) ), you collect the benefit. A little time, sure, but not too much compared to the benefit it gives. I wouldn't say AoK was all about economy just because there were a few relics you could pick up and send home to your monastery :)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Create New...