Jump to content

  • Log In with Google      Sign In   
  • Create Account

RTS - Detecting when a command finishes


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
6 replies to this topic

#1 Kovaz   Members   -  Reputation: 136

Like
0Likes
Like

Posted 30 August 2014 - 09:20 AM

I'm working on a game that is controlled like an RTS, ie left-click and drag a box to select units, right click to issue a move command, or press a hotkey and left-click to issue some ability command. You can also hold shift to queue commands after the current one (move here, then attack this building).

My question is how I can detect when a command finishes so I can start executing the next one. My current implementation is as follows:
 

I have Command structs that just hold data (MoveCommand holds a world position, AttackCommand holds the id of the unit to attack, etc).

I have a CommandRunner that has a method for each type of command. These methods return a boolean that is true if the command finished, or false otherwise.

I have a CommandManager that has a map that maps IDs to linked lists of commands.

My algorithm is to loop through CommandManager's map. For each element, execute the first command in the list using the CommandRunner. If it returns true, pop it off the front of the list.

This works great, except that my conditions for a command being done aren't good enough. For example, my naive first attempt for MoveCommands was just if( myPosition == goal ). This works for a single unit, but obviously adding any more creates problems since most of the units can't get to their goal. They end up just sitting around the point jostling to get closer, but never actually reaching it.

Obviously the conditions are easy for some commands ( AttackCommand would be if( target.dead() )  ), but I'm not sure of the best way for a Movement Command. I'm thinking I'll have to implement some flocking behaviors, since it seems it would be more reliable to check if the flock as a whole has reached the destination.



Sponsor:

#2 SmkViper   Members   -  Reputation: 1238

Like
0Likes
Like

Posted 30 August 2014 - 12:57 PM

When a command is done is going to depend on the command (is target dead? is the building built?), but for movement you probably want to have a radius - basically, don't check for "am I sitting on my goal", but "am I closer then X units to my goal" which can be done with a simple vector length check.

If you want to get fancier you could look into multi-unit moves as a single large "unit" with the goal checks coming from the center of the mass.

#3 ankhd   Members   -  Reputation: 1358

Like
0Likes
Like

Posted 31 August 2014 - 03:49 AM

Hi.

What could happen is the unit walking to its target could ask idel units in there way to move. This looks good with vehicles.



#4 Kovaz   Members   -  Reputation: 136

Like
0Likes
Like

Posted 31 August 2014 - 07:34 AM

The problem with checking for a radius is it only really works for a certain amount of units. A single unit would stop short of the destination, and repeated clicks wouldn't get him any closer which would be very frustrating and unintuitive to use. Plus it would still run into the same issues with groups too large to fit into the chosen radius.

 

I already have handling for idle units. Basically whenever units collide, I push them each equally away from each other's center just enough to no longer collide, so idle units end up being pushed away. My problem is occuring when multiple units want to move to the same spot, so neither can push the other away.

I'm thinking I'll have to use a mix of approaches, like checking for a radius that's based on how many units were selected, abandoning a move after a certain number of collisions, using flocking to set a different goal than what was clicked, etc.



#5 GaldorPunk   Members   -  Reputation: 1085

Like
0Likes
Like

Posted 31 August 2014 - 10:34 AM

That’s the right idea. Basically the way I deal with this problem in my game is for each unit to keep a list of ids of other units in the flock; whenever two units collide, they offset their destinations so that they’re moving in parallel to areas around the ultimate destination (if they’re moving in the same general direction) and add their own id to the lists in all these connected units so they can keep track of each other. Flocking and keeping a list also means you can eliminate a lot of unnecessary collision detection every update loop, since you know that units that have already been adjusted to move as a group won’t collide with each other again unless some outside unit interferes.

 

There are a lot of special cases to check for, but having some kind of list of nearby units means you can adjust the acceptable distance to the target depending on how many units are around. If you’ve just got one unit, it has to move exactly to the target, but if there are a lot of units moving to the same place, you can have a larger radius based on the number of units and their individual sizes for defining whether each one is close enough for the move order to be satisfied. (They should still keep moving to their destination at least until they collide with another unit, but once they do, they’ll check if they’re already within the group-defined radius of the destination and then either stop or tell the units blocking the way to move.)



#6 BedderDanu   Members   -  Reputation: 283

Like
0Likes
Like

Posted 31 August 2014 - 11:43 AM

Would something like the following work?

 

1) Set location as "target"

2) move unit toward the target

3) if the unit collides with an ally unit, check to see if the target is occupied by an ally unit

  if not) continue as normal

4) if it is, check for the closest point in a ring around the target that isn't occupied by an ally. Set as new target.

5) If no spot is available, increase the ring size and try again.



#7 DerekL   Members   -  Reputation: 253

Like
0Likes
Like

Posted 03 September 2014 - 01:56 PM

Okay so what could work is you could add event listeners to the units following the main unit and when the main unit reaches his destination he dispatches an event letting all the other units know to stop. When this event is recieved just have the units move towards the main unit and if theres no more room to stop, then do this again until no units have any room left in between them.






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS