Unit loyalty is dynamic scoring of a Unit, representing the strength the Unit will stay with the owning nation. It is calculated by the game based on environment factors that are projected onto the Unit. Loyalty of a Unit is different than loyalty of a town, as a town's loyalty is a scoring of a town race group, which is merely a number of people, and they have no individual characteristics (if employed, it will be in their firm). Units may be in firms as well, but the loyalty effects may be different (TODO determine if they are of Unit class). This describes only a Unit class's loyalty calculation.
There are two components of the loyalty mechanism. One is the current loyalty, and the other is the target loyalty (target_loyalty in code). Both can change at any time, but the current loyalty can have a direct effect at betrayal.
Of importance is the betrayal loyalty.
Loyalty and target loyalty is updated in update_loyalty(), which is called when the unit is generated, on the monthly cycle, and when the unit changes flags. Target loyalty is calculated, and loyalty is simple adjusted (exception are spies). Here are some aspects of the update procedure to target loyalty:
- Units that are constructing buildings do not change their loyalty or target loyalty.
- Spies are unique as they calculate their loyalty -- a random number between 70-90 -- and set their target loyalty to the same number. This has an effect of a constant high loyalty. This was removed in 7k2, and spies there act the same as their assigned occupation type for loyalty and target loyalty.
- General units have a higher target loyal based on their command power, his relationship to the king (if same race +20, and bonus based on king's leadership), and nation's reputation. Generals must be rewarded if they have a contribution rating, or it will be a negative loyalty factor.
- Soldier units cannot usually be rebellious when led by a general. Their target loyalty is based on the general's leadership + 30. There is also a +20 bonus of being the same race and a +20 bonus led directly by a king. However, that is simply is a buffer, since the target_loyalty is negatively impacted based on combat skill, and based on leadership skill.
- All other cases, the target loyalty is 0. This means any worker or peasant will eventually betray you if you leave them mobile for too long. This makes sense because they aren't doing a job.
When the current loyalty is updated, it trends towards the target loyalty by small increments or decrements.
There are events that can immediately change the current loyalty of a unit. Examples of this are when the unit does not receive its salary pay or food, granting a reward, or demoting.
When hired, spies can no longer randomly betray the nation they are cloaked despite the loyalty level (see think_betray()). They can still betray based on unique events.
The betray() function is used to switch units between nations formally (with announce or not). Spies use this for both an announce type and non-announce type betrayal. Independent units can also do this (TODO define better). Below are the conditions in which the betray action is handled.
- Units that are constructing or on a ship cannot betray.
- Kings cannot betray.
- Loyalty calculated when betraying to UNIT_BETRAY_LOYALTY + random(5). Bonuses are +reputation and +30 if the same race as the king. Then update_loyalty() is called to update the target_loyalty. This is generally where loyalty is first assigned, but spies end up being recalculated. (Note in 7k2, the base loyalty calculation changed)
- Generals will bring their mobile followers.
- The unit will decide a structure of the new nation to move to, which makes their presence clearly visible.
Define how bonus units (freebie units with random skills) are generated in case there is a potential behavior issue that can identify spies based on the random stats.