So I've been doing some digging on how the morale systems works in Outpost2, and how Morale.txt controls this system.
First of all, there are two types of morale. There is Base Conditions, and there are Events. These are handled seperately. Every so often (every 256 ticks), these values are looked at and combined to form you current morale. This calculation is only performed for human players. For AI players, the morale level is set to 2 (OKAYFINE in morale.txt).
Note: Some values referred to below are stored in morale.txt as a percentage (out of 100). Internally however, these values are stored as a "percent" out of 256. To make the conversion to the internal format, use perByte := ((percent * 256) + 50) / 100. Also note that the division will always round down to the nearest integer. All such percentage/perByte values used below will be assumed to be already converted to this internal format, and so formulas will be given as used internally to Outpost2. That is, assuming these values are out of 256.
The base conditions are calculated (from scratch every so many game cycles) and determines how current colony conditions affect morale. This gives a base number from which to start your morale calculations from. In the absence of events, this will become your current morale. This value can swing wildly if base conditions change significantly during the period between successive base condition calculations.
The events adds a sense of memory to morale. There is a running events morale value, which is updated every time an event which affects morale happens. This would include things like a child being born, new workers or scientists trained, colonist deaths, research being completed, disaster occurances, etc. Good events will increase this value, and bad events will decrease this value. The effect of events decays over time, but will provide a lasting effect over a few morale calculation cycles.
Event morale decays at a rate given by EVENT_DEC_RATE in morale.txt. This value is a percentage of the current eventMorale value which carries over to the next cycle. (Internally, it is represented as a "percent" out of 256). Every calculation cycle, the event morale is updated as follows.
eventMorale := (eventMorale * EVENT_DEC_RATE) / 256
Note that in the case of a negative eventMorale value, it rounds up (ensuring it can get back to 0 over time and not get stuck at -1) by using the following formula instead:
eventMorale := (eventMorale * EVENT_DEC_RATE + 255) / 256
The value used during the current cycle calculation, is the eventMorale value as it was before the update. (i.e. The value is used first, and THEN updated.)
The file morale.txt is broken up into 4 main sections. I will refer to these 4 sections as Colony Effects, Events, Colony Conditions, and Difficulty Modifiers.
The first section, Colony Effects, describes the effect that morale has on your colony. This is where you get production bonuses or penalties. This would include bonuses/penalties for research points, factory production, food growth, fertility rates, and death rates.
The second section, Events, describes the effect that various events will have on the events portion of your morale. These are the values that are added (or subtracted if negative) from your eventMorale value as they occur.
The third section, Colony Conditions, describes how your current colony conditions affect the colony conditions portion of your morale. This includes things like overcrowding (residence demand), adequate food supply, disabled building ratio, rec/forum demand, medical center demand, DIRT demand, nursery operational, university operational, disaster early warning techs available, unoccupied colonist percent, and scientists as workers percent. Values are given for each level of satisfaction that your colonists may have in these areas.
The fourth section, Difficulty Modifiers, describes how the current difficulty setting will affect your current morale based on the morale calculation for colony conditions and events. These values are given in the file as percents (and stored internally out of 256). These modifiers depend both on difficulty setting, and on whether you are Eden or Plymouth. (As you can see from the default values in the file, Plymouth gets a morale advantage here). The idea being that: morale := ((colonyConditionsMorale + eventMorale) * difficultyModifierPercent) / 100.
The value that gets calculated in that last part is the value your morale will tend to. However, further clipping is done to ensure that morale doesn't change by more than 5 (either positive or negative) from it's current value. This adds a second "memory" effect, where your morale will take a little while to change from one steady state to another.
I think I'll stop here for the moment while people digest how the system works so far. I'll jump into the nitty gritty details on how each value is used over the next few days. I'll be sure to include exact formulas used, and precise conditions on when each value is used.
Events
I'll continue on with the second section of the file. This section describes how events affect the event portion of your morale. This section is mostly a list of how certain events affect morale, followed by the eventMorale decay rate EVENT_DEC_RATE (described in my first post).
KID_DIES
ADULT_DIES
These two are used whenever colonists die. This can be from natural death rates, starvation, or building explosions. The eventMorale is updated as follows:
Player[i].eventMorale += numDeadKids * KID_DIES + (numDeadWorkers+numDeadScientists) * ADULT_DIES
Note that KID_DIES and ADULT_DIES are meant to be negative, and so this will decrease your morale when these events happen. Setting these values positive will cause you to gain eventMorale when someone dies. (I set both to 800, and morale started sky rocketing when a child died. :blink: Maybe it was Dennis the Menace or something?)
KID_BORN
This is used when children are born AND totalPopulation (numKids + numWorkesr + numScientists) < 125. If this is the case, then eventMorale is updated as follows:
Player[i].eventMorale += numNewKids * KID_BORN
If totalPopulation >= 125 then eventMorale is updated as follows:
Player[i].eventMorale += numNewKids
TECH_SCHOOL
This is used when workers are trained AND totalPopulation < 125. If this is the case, then eventMorale is updated as follows:
Player[i].eventMorale += numNewWorkers * TECH_SCHOOL
If totalPopulation >= 125 then eventMorale is updated as follows:
Player[i].eventMorale += numNewWorkers
PHD_TRAINED
This is used when scientists are trained AND numScientists < 40. If this is the case, then eventMorale is updated as follows:
Player[i].eventMorale += numNewScientists * PHD_TRAINED
If numScientists >= 40 then eventMorale is updated as follows:
Player[i].eventMorale += numNewScientists
NEW_TECH_BORN
This is used when research of a technology is completed. When research is completed, eventMorale is updated as follows:
Player[i].eventMorale += NEW_TECH_BORN
CC_BORN
This is used when construction of a new Command Center finishes. When construction finishes, eventMorale is updated as follows:
Player[i].eventMorale += CC_BORN
GOOD_BUILD_DIES
REG_BUILD_DIES
These values are used when a building is lost. The value that is used depends on which type of building is lost. The following are "Good" buildings:- Nursery
- Medical Center
- Residence
- Advanced Residence
- Reinforced Residence
If one of the above buildings dies, eventMorale is updated as follows:
Player[i].eventMorale += GOOD_BUILD_DIES
If the building that was lost was not one of the above buildings, then eventMorale is updated as follows:
Player[i].eventMorale += REG_BUILD_DIES
ENEMY_GOOD_DIES
ENEMY_BAD_DIES
These values are used when you kill an enemy building. The value that is used depends on which type of building was destroyed. The following are "Good buildings:- Nursery
- Medical Center
- Residence
- Advanced Residence
- Reinforced Residence
If one of the above buildings is killed, eventMorale is updated as follows:
Player[i].eventMorale += ENEMY_GOOD_DIES
Note that ENEMY_GOOD_DIES is set by default to -800. So killing one of these "Good" buildings will severly hurt your morale.
If the building that is killed is an Advanced Lab then eventMorale is updated as follows:
Player[i].eventMorale += ENEMY_BAD_DIES
By default, killing a "Bad" enemy building will help you morale. Note that the Advanced Lab is the only building in the "Bad" category. There is no morale effect for killing other building types. (Only for having one lost).
Note: The above lists for "Good" buildings are the same. However the "Regular" and the "Bad" lists differ by the Advanced Lab. If you kill a regular building, it will not affect your morale, but killing a bad building (an Advanced Lab) will, and by default, killing a bad enemy building will help your morale.
ENEMY_VEH_DIES
This value is used when you kill an enemy vehicle. If you kill your own unit, there will be no effect here. The eventMorale is updated as follows:
Player[i].eventMorale += ENEMY_VEH_DIES
Note: When a unit dies, it checks which unit killed it, and performs the above eventMorale update on the owner of that unit. At this time, it is not known how the index of the attacking unit is updated. (In particular, the affect of explosions, or chain reactions of explosions, is unknown).
DISASTER_NO_WARN
DISASTER_WARNED
These values are used when a certain disasters appear. It does not matter if the disaster hits you directly, or if it appears all the way on the other side of the map. The appearance of a disaster will affect all players equally in this respect. (If the disaster kills a building, then there are additional eventMorale implications of buildings being lost). Only 4 disaster affect eventMorale in this way.- Quakes
- Storms
- Meteors
- Vortexes
The other disasters have no affect on eventMorale when they appear. If you have the tech to warn against the disaster, the effect on eventMorale is as follows:
Player[i].eventMorale += DISASTER_WARNED
Otherwise, the effect on eventMorale is as follows:
Player[i].eventMorale += DISASTER_NO_WARN
Note that early warning of disasters from an EDWARD satellite does not count as an early warning in the morale calculation.
CONSUMER_GOODS_1
CONSUMER_GOODS_2
CONSUMER_GOODS_3
These values are used when goods at a consumer goods factory are completed. If Impulse Items are completed, CONSUMER_GOODS_1 is used. If Wares are completed, CONSUMER_GOODS_2 is used. If Luxury Wares are completed, CONSUMER_GOODS_3 is used. The resulting effect on eventMorale is of the form:
Player[i].eventMorale += CONSUMER_GOODS_X
I would like to point out that the only truly "random" event which affects morale is disasters. But since the appearance of disasters affects all players equally (in terms of eventMorale), no matter where the disaster appears, the effects are essentially fair. The only unfair aspect, is if the disaster appears over your base/units and causes some real damage. In this case, you could take an eventMorale hit if a building is destroyed.