Author Topic: Morale.txt  (Read 4067 times)

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4954
Morale.txt
« on: November 05, 2005, 03:34:36 AM »
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.
Code: [Select]
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:
Code: [Select]
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.
« Last Edit: November 05, 2005, 06:52:00 PM by Hooman »

Offline Eddy-B

  • Hero Member
  • *****
  • Posts: 1186
    • http://www.eddy-b.com
Morale.txt
« Reply #1 on: November 05, 2005, 03:25:39 PM »
Good work hooman (thumbsup)
Rule #1:  Eddy is always right
Rule #2: If you think he's wrong, see rule #1
--------------------

Outpost : Renegades - Eddy-B.com - Electronics Pit[/siz

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4954
Morale.txt
« Reply #2 on: November 05, 2005, 09:08:39 PM »
Colony Effects

The first section of Morale.txt contains the bonuses/penalties for each of the 5 morale levels.
UTOPIA (morale level Excellent/Great)
GROOVY (morale level Good)
OKAYFINE (morale level Fair/OK)
UPSET (morale level Poor)
WAYBAD (morale level Terrible/Rotten)

It is important to keep these morale levels in decreasing order, and also to not exceed 5 morale levels. If more than 5 morale levels are specified, the game won't load. If fewer than 5 levels are specified, odd behavior will result. Also, the strings and recorded voice messages about your current morale (Excellent, Good, Fair, Poor, Terrible) are hardcoded into the exe to match the default ordering in this file. If you were to reorder the file like so:
Quote
WAYBAD   0   0   -15   20   -10   10   107   180
UTOPIA   90   0   15   -25   20   0   35   620
GROOVY   70   0   8   -10   8   0   46   500
OKAYFINE   45   0   0   0   0   0   64   390
UPSET   25   0   -8   10   -5   5   82   280
Then morale will always read as "excellent" and you'll get the production penalties of having "WAYBAD" morale. (See M_PTS_TOT below for why this level is selected).


For each of these morale levels, you have 8 entries.

The first entry, M_PTS_TOT, determines which value for morale constitutes being at this morale level. For UTOPIA, we see the value of M_PTS_TOT is 90. This means that when morale >= 90 (M_PTS_TOT), we are at morale level UTOPIA. The game chooses the first morale level that your current morale satisfies. This is why you should place the morale levels in decreasing order. If WAYBAD were placed first, with M_PTS_TOT set to 0, then this is always satisfied, and so your morale will always be set to "WAYBAD". (No further checks against other morale levels will be done). The game will only check a maximum of 5 morale levels (0-4). If no morale level was satisfied (morale >= MoraleLevel.M_PTS_TOT) then a morale level of 4 (the worst) is assumed.

The second entry, M_POW_BONUS, determines how much of a power bonus you will get at this morale level. By default, all these values are set to 0, so you will receive no bonus/penalty based on your morale level. However, if you were to change this value to 100, then your CC will now produce 100 power instead of 50 (100% increase), and your tokamaks (unupgraded) will produce 500 power instead of 250. (This value is stored internally out of 256).

The third entry, M_RSCH_BONUS, determines how much of a research bonus you will get at this morale level. This just affects the rate at which your scientists produce "research points", and so a higher value will make them research faster. (This value is stored internally out of 256).

The fourth entry, M_FACT_BONUS, determines how long it takes for factories to produce stuff. A negative value will decrease the time needed to produce things, thus increasing the production rate. (This value is stored internally out of 256).

The fifth entry, M_FOOD_BONUS, determines how much food is produced by your agridomes. (This value is stored internally out of 256).

The sixth entry, M_DEFECT_RATE, appears to be an unreferenced value. It would seem this entry has no effect on the game. (This value is stored internally out of 256).

The seventh entry, M_FERT_RATE, determines the rate at which new children are born. A higher value will decrease the rate at which kids are born. This is only effective if you have an active nursery, and (numWorkers + numScientists) > numKids. (Setting this value to 1 will quickly make your kids reach the (numWorkers + numScientists) limit). A value of 0 will cause a division by 0 error and crash Outpost2. Setting this value negative will cause your number of kids to plummet really fast. (A negative number of kids will be born. This can do wonders for your residence demand however.  :heh: )

The eighth entry, M_DIE_RATE, determines how long it takes for colonists to die. A higher value will decrease the death rate. Set this value too low, and your colonists will drop like flies.  :heh: (Quite amusing to watch: "30 children, 26 workers, 13 scientists have died". "Mission failed"). Do NOT use a value of 0 or 1 for this setting as this will cause a division by 0 error and crash Outpost2. Setting this value negative will cause your population to grow like mad. (A negative number of people will die). You will likely starve to death within short order. (With a value of -1 for M_DIE_RATE, I starved by about mark 20. All my scientists, about 123 not yet starved to death by that point, starved to death causing mission failure).



As a final note on this section, I'd like to state that the calculated morale level is determined before clipping morale to the range (0-99). However, since morale levels do not change past those extremes, there is no difference between clipping the morale range before determining the morale level from clipping the morale range after determining the morale level. However, if you were to change M_PTS_TOT for UPSET to 0 and M_PTS_TOT for WAYBAD to -1, then your morale will be at "Poor" all the way down to 0, including 0, but if you have further morale effects that would make this negative (before clipping) then your morale will drop to "Terrible", even though your morale is still shown as 0. Thus, you can have either "Poor" or "Terrible" morale when you morale is at 0, depending on whether or not it was naturally 0, or was clipped to 0.
« Last Edit: November 06, 2005, 08:40:06 PM by Hooman »

Offline Leviathan

  • Hero Member
  • *****
  • Posts: 4055
Morale.txt
« Reply #3 on: November 06, 2005, 05:28:08 AM »
A big thanks for this :D

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4954
Morale.txt
« Reply #4 on: November 06, 2005, 08:37:53 PM »
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:
Code: [Select]
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:
Code: [Select]
Player[i].eventMorale += numNewKids * KID_BORN
If totalPopulation >= 125 then eventMorale is updated as follows:
Code: [Select]
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:
Code: [Select]
Player[i].eventMorale += numNewWorkers * TECH_SCHOOL
If totalPopulation >= 125 then eventMorale is updated as follows:
Code: [Select]
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:
Code: [Select]
Player[i].eventMorale += numNewScientists * PHD_TRAINED
If numScientists >= 40 then eventMorale is updated as follows:
Code: [Select]
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:
Code: [Select]
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:
Code: [Select]
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:
Code: [Select]
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:
Code: [Select]
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:
Code: [Select]
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:
Code: [Select]
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:
Code: [Select]
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:
Code: [Select]
Player[i].eventMorale += DISASTER_WARNED
Otherwise, the effect on eventMorale is as follows:
Code: [Select]
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:
Code: [Select]
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.
« Last Edit: May 26, 2007, 11:45:12 PM by Hooman »

Offline BlackBox

  • Administrator
  • Hero Member
  • *****
  • Posts: 3093
Morale.txt
« Reply #5 on: March 27, 2006, 08:28:17 AM »
When will we see the next 'installment' of this information?

I remember you said you would get back to it someday.

Offline Vexhare

  • Full Member
  • ***
  • Posts: 120
Morale.txt
« Reply #6 on: March 27, 2006, 10:36:48 AM »
Yeah I myself just read over it, very informative.

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4954
Morale.txt
« Reply #7 on: April 13, 2006, 12:42:10 PM »
Yeah, I never got around to writing up the next part, but I did start on it once. It ended up with me just commenting a bunch more code so I could be sure all my details were correct. There was a fair bit of code though, so I ended up spending all my time commenting the assembly, and no time writing it up here. It was fairly repetitive though, so not too hard to understand once you have one part down.

Anyways, nothing too earth shattering that I can remember at the moment. Stuff like if you have no buildings (but have researched the tech) then internal demand is 10000%, or something like that. I was also gonna post details on the exact percentage ranges at which the different modifiers take effect. Like when CROWDED_LOW is used instead of CROWDED_HIGH, that sort of thing.

Don't have time now, maybe in two weeks, probably not. If not, then probably late June. It'll be pretty amazing if I find the time to drop by during May or early June.  :unsure:
 
« Last Edit: April 13, 2006, 12:47:17 PM by Hooman »

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4954
Morale.txt
« Reply #8 on: May 26, 2007, 11:52:41 PM »
Just fixed a mistake in an earlier post. It seems I had something backwards.

The Advanced Lab is the only "Enemy Bad" building. You get a morale bonus for killing someone else's Advanced Lab. There is no morale change for killing someone else's building that is not "Good" or "Bad". Before, it was stated that the Advanced Lab was the only "Regular" building (not "Good", or "Bad"). Basically the "Bad" and "Regular" lists where reversed for killing enemy buildings.

The result of the error was because a jump was misread. When checking for "Good" buildings, the JE assembly instruction was used for each of the Good buildings, but a JNE was used for the Advanced Lab.