0
\$\begingroup\$

I'm trying to work out how Factions would work in any Standard MMO

If the player is hostile with a faction, then the NPC's of that faction would attack on sight.

If the player is neutral> with a faction, then the NPC's of that faction wouldn't attack on sight.

The "Reputation Value" would be an integer.

Hostile = 0
Unfriendly = 2000
Neutral = 4000
Friendly = 6000
Honored = 8000
Revered = 10000
Exalted = 12000

Example:

When the player Logs in. The Bandit faction must find out the Player's Reputation Value towards them.

if Player.Bandit.UNFRIENDLY or Player.Bandit.HOSTILE:
    the NPC would be able to attack the player on-sight.
if Player.Bandit.NEUTRAL or FRIENDLY or HONORED or REVERED or EXALTED:
    the NPC won't be able to attack the player on-sight.

or

ReputationValue = Player.Bandit.Reputation

if ReputationValue > 4000
   the NPC won't be able to attack the player on-sight.
else
   the NPC will be able to attack the player on-sight.

This is more complicated than it initially appears. Every player has a FactionList, and the FactionList ReputationValue can change potentially, multiple times per second.

For the player, it is relatively simple, they have a FactionList which contains the FactionName and FactionReputation for each Faction. Clientside, they can attack anything as long as it's 5999 or below.

But for the Enemy, Serverside. they need to check the players FactionList and not only for a single player, but for potentially hundreds of players.

For ANY entity to KNOW if they can or can't attack, they first NEED to know the SPECIFIC player's FactionList ReputationValue for their Faction.

the FactionList ReputationValue is a constantly changing value which must be obtained potentially every few seconds from Each Player.

How does this check work?

When is it performed?

How often is it performed?

I'm assuming Each Faction performs this check whenever a player logs in. Adding this players value to a list.

Performing this check as part of an Aggro-radius would be insanely inefficient.

\$\endgroup\$
1
  • \$\begingroup\$ The enemy would not perform this check every time the player enters an aggro radius. that would mean every time the player engages a mob, then the check is performed, the check only needs to be performed once per player per faction. Not once per mob per player. \$\endgroup\$ – jaym Oct 19 '20 at 8:31
1
\$\begingroup\$

A typical mmo has even more checks compared to just the reputation. Some take your level into consideration (low level mobs ignore high lvl players). Retaliation guards if you have killed some players some time ago. Reputation. Buff effects/ Transformations.

Typically it would check on each frame (or close to it). Checks order is something along the line of

  • Check if something is in my range
  • Determinate what I found in my range
  • Determinate if I should attack it or not

The third step would take your reputation into account. And the value is requested each time he detects him in his range - else if you farm some reputation and it is only evaluated on login, a change in reputation would not be noticed. The server simply is requesting the player data (which he has already) and compares all values for each mob that determinate if a mob is hostile. There is some optimization going on, once we found something in our range, we don't need to reevaluate it all the time or for certain encounters you might have aggro trigger zones that are fixed.

The most expensive operation is the aggro distance of the mob. Even if you just take the distance as you and the mob as criteria (on a 2D plane), you have √((xB−xA)(xB−xA)+(yB−yA)(yB−yA)) which is a lot more expensive than a simple value if condition check.

\$\endgroup\$
6
  • \$\begingroup\$ The enemy would not realistically perform this check every time the player enters an aggro radius. that would mean every single time the player engages any mob, then the check is performed which is wildly inefficient, the check only actually needs to be performed once per player per faction. Not once per mob per player. \$\endgroup\$ – jaym Oct 19 '20 at 8:32
  • \$\begingroup\$ If you have 1000 people in a zone, you would need to cache 1000 people that may or may not engage in a fight. You would still need to check per mob if he is in range of a player, if a player is visible etc. One extra check for reputation is neglectable \$\endgroup\$ – Zibelas Oct 19 '20 at 8:40
  • \$\begingroup\$ @jaym Calculating the distance between the mob and the player to see if they are in aggro range is usually a far more expensive operation than checking the reputation score for the mob's faction. \$\endgroup\$ – Philipp Oct 19 '20 at 8:50
  • \$\begingroup\$ Aggro is entirely unrelated and irrelevant to this discussion. the Reputation Check is required to happen prior. As it is the faction which dictates if Aggro should even be considered. \$\endgroup\$ – jaym Oct 19 '20 at 8:57
  • \$\begingroup\$ @jaym aggro is the only point that matters. You don't check reputation prior. The enemy does not care about you before you are in his aggro range. Only if you are in his range he will consider whether to attack you or not - not before \$\endgroup\$ – Zibelas Oct 19 '20 at 9:03
0
\$\begingroup\$

Performing this check can easily be implemented as a very fast and efficient operation.

  • Give every player an array of integers with one entry for each faction in the game. This array represents their reputation with each faction.
  • Give each mob a faction ID which is equal to the index in the reputation array of the player

Now when you have a player and a mob, finding if the mob is friendly or hostile is just two very simple operations:

  1. an array index lookup
  2. an integer comparison to see if the reputation for that faction is below the attack-on-sight threshold

if (player.factionReputation[mob.factionId] < 2000)

There are a lot of things an MMO server needs to perform every tick which are far more CPU-intense than that. And you don't even need to do this every tick, only when the mob is in the state of their behavior tree where they look for a new target to attack. And when considering potential targets to attack, then there are a lot of operations which are far more CPU-intense than just checking the faction reputation:

  • Is the player in attack range?
  • Is there a clear line of sight to the player?
  • Is there an unobstructed path to the player?

These are the things you might want to worry about optimizing in your game.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.