• Hello [name]! Thanks for joining the GMC. Before making any posts in the Tech Support forum, can we suggest you read the forum rules? These are simple guidelines that we ask you to follow so that you can get the best help possible for your issue.

Question - Code Efficient way to program auto targeting

Kaliam

Member
Hello, I've been trying to implement a reliable form of auto targeting in my RTS that doesn't hit performance too hard. I've created several scripts but the main problem i'm having is finding a way to program auto targeting that doesn't involve every instance looping through every other instance checking their distance and team to find out if it's a valid target.

An example:
Code:
//If the target instance does not exist or is no longer in range
if(!instance_exists(target) || !point_distance(x, y, target.x, target.y) <= a_range){
  
    //With every ship object (Unit in game)
    with(obj_ship){
      
        //if ship is not this object's team
        if(other.team != team){
  
            //if distance to ship is within this object's range
            if(point_distance(x, y, other.x, other.y) <= other.a_range){
      
                //set ship as this object target
                other.target = id;
              
            }
        }
    }
}
This works perfectly but uses far too much processing power as every single unit has to check every other unit.

The other solution I have uses parent team objects where I set unit types to be a child of a specific team object. The problem with this is that there is no way to change the parent of an object later in code, so that unit will always be stuck to the team object that it's a child of. This doesn't work because I want to allow players of different factions to be on the same team. (As far as I can tell there is no way to change inheritance in GML)

An example:
Code:
///If the target instance does not exist or is no longer in range
if(!instance_exists(target) || point_distance(x, y, target.x, target.y) > a_range){
     
     //If there is an instance of obj_ship_team_1 to check
    if(instance_exists(obj_ship_team_1)){

        //Get the distance to the new target
        var newTargetRange = point_distance(x, y, obj_ship_team_1.x, obj_ship_team_1.y);
      
        //Check if the new target is in range
        if(newTargetRange <= a_range){
         
            //set the target to the new target
            target = obj_ship_team_1;
        }
    }
}
The only other solution that I could think of is somehow dividing up the room into zones and have the objects only check other objects that are in it's zone, but I imagine checking all those zone collisions are going to be pretty CPU intensive too.

If anyone has any suggestions or ideas i'd love to hear them!
 

FrostyCat

Member
You can put the instance IDs into lists according to which side it is on and/or which zone it is in, then loop through just one of those lists. As long as you keep the lists updated, it is an easy way to rule out a large number of unrelated instances without compromising correctness.

Another way would be to recompute targets less frequently, say once every half second instead of once every step.
 
Top