0
\$\begingroup\$

How does a bot know who is an enemy if "enemy" encompasses not only one player, which can be just hardcoded?

For example, in Warcraft 3, we can have two bot teams with faction alliances and they will treat each other as enemies.

What is the mechanism that chooses who is an ally and who is an enemy?

I suppose there is some Map<Team, List< Units >> and every bot is assigned some Team by default at the start, and when bot sees someone and that unit is not in the bot's team it means it is an enemy? But here is no place for allies.

Edit: So I am working on 2d Farm Game and I plan to add another enemy to me fraction and some enemies for all fractions.
Currently I don't have any NPC but later I want to have some units that can gather resources/kill enemies. So I was thinking that there is no difference between my units and enemy units.So there should be some rules that define that this bot treats another bot as ally or an enemy.

PS: The reason I started thinking about that was that I started working on inventory and understood that ideally there should be no difference between me and an npc who gathered a particular resource, so there should be some way to add a resource to same inventory by player controlled character and a bot. This led me thinking that the same should be true for another team, the code should be the same. There shouldn't be FriendlyBot and EnemyBot.Just Bot script for example and some script that assigns team id and later using this team id bot will interact with an inventory.

It seems to me that two topics are pretty close to each other as both need a structure that would allow me to organize bots into teams and inventory belongs to the whole team.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ If you are able to integrate an ai/ bot into the game, you should have easily access to things like team id, positions and basically every other information. Things like alliances are trivial. Having a meaningful support of your ally on the other hand is hard \$\endgroup\$
    – Zibelas
    Jul 20, 2023 at 7:30
  • \$\begingroup\$ I don't know how to do that, that is the reason why I am asking such a question. \$\endgroup\$ Jul 20, 2023 at 7:38
  • 2
    \$\begingroup\$ I sketch one possible implementation of alliances/enemies/allegiances in Unity in this answer. Different games may implement this differently, though. If you're working on a game or game mod of your own and want help making this work in your context, you should edit your question to explain that context, so users here can tailor answers that will be most useful for your needs. \$\endgroup\$
    – DMGregory
    Jul 20, 2023 at 11:19
  • \$\begingroup\$ It would also help to edit your tags to include whatever framework / engine / language you're working with. \$\endgroup\$
    – Pikalek
    Jul 20, 2023 at 14:21

2 Answers 2

1
\$\begingroup\$

Unity has tags and Godot has Groups.

you can put the player into group/tag "player" and the enemy AI will know who is the player.

or use Team1/Team2/Team3

or maybe use "playerID_insert_number_here" for npcs that follow specific players in an online game.

Alternatively you can use GameObject.Find("insert objsect to find") in unity or get.node("insert node to find") in godot but this last method usually doesn't work for multiplayer games

in other game engines or if you are not using a game engine, you could probably just use variables inside the player script like creating an area around the enemy with code and basically saying

if anything touches the area: 
  proceed: 
  if anything in the area has method/variable "player" 
     proceed: 
else : 
    enemy AI does whatever it should do when no players are around 

and you can make as many if/else statements as needed for all the states the AI has, maybe put them into functions() and call each function when needed or use switch case but I've never used switch case so i don't know. But people more expert than me say the less nested if-else statements you use, the better.

Anyway you always rather use tags and groups since it easily works in multiplayer and it's the most performing one becase no area is created around the enemy.

one area can be unnoticeable, but get 20 enemies and that's 20 areas around them... each one needs to get update every single frame.

I personally found incredible performance boosts by not using areas.

\$\endgroup\$
2
  • \$\begingroup\$ Thank you for your comment, I guess using tags is a good idea. It is now clear to me. Because I was thinking about for example bots in CS:GO and how two identical bots treat each other as an enemy or an ally and this logic should be separate from AI code.I guess in this situation we can use tags or some castom script that returns some string and check if it's an enemy or not. \$\endgroup\$ Jul 20, 2023 at 10:28
  • \$\begingroup\$ I would not recommend using tags for this. They're quite limited, and you might want to use them for other things too. In Unity, I'd make an Allegiance component that stores the team association for each unit. A static table of teams can let you look up, for a pair of teams, are they allies, enemies, or neutral. \$\endgroup\$
    – DMGregory
    Jul 20, 2023 at 12:26
0
\$\begingroup\$

In addition to what Cei mentioned, you can accomplish this in Unity by creating a sphere around the object you wish to detect enemies or players as i demonstrate below ,however this system has the disadvantage that enemies may be able to detect you without seeing you. If you were to make the next GTA, it would be unreal so another approach to this issue is make the enemy cast a ray while patrolling around the map

private void Detect()
{

    Collider[] detectedColliders = Physics.OverlapSphere(transform.position, raduis){


        for (int i = 0; i < detectedColliders.Length; i++)
        {

            if (detectedColliders[i].CompareTag("Player")){



                if (!HasTarget)
                {
                    // Do what ever you want the enemy/npc to do 

                    HasTarget = true;
                }

            }
            else
            {
                // Idle 
            }

        }

    }

}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .