Population

Consumption

The do_population_consumption function is at 0x00527D40.

At 0x00672860 there is a table that contains the daily consumptions for 100 citizens of every population type:

WareRichWealthyPoorBeggars
Grain90120150120
Meat11087125
Fish4080100110
Beer651306575
Salt1111
Honey502552
Spices4220
Wine1503800
Cloth5035151
Skins603000
WhaleOil5035100
Timber80804020
IronGoods10075250
Leather443550
Wool1040205
Pitch0000
PigIron0000
Hemp5323
Pottery3018121
Bricks1100
Sword0000
Bow0000
Crossbow0000
Carbine0000

If a town is not under siege and a ware is in oversupply, more of it is consumed. TODO clarify TODO pitch consumption (sieged and unsieged), winter/famine/plague modifiers

Satisfaction

P3's setting "Needs of the citizens" changes how easy it is to increase the satisfaction, and how fast it changes. The satisfaction classes are displayed in-game: Very happy, happy, very satisfied, satisfied, dissatisfied, and annoyed. The satisfaction for each population type is stored in the town's satisfactions array at offset 0x300, holding an i16 for every population type except Beggars. The function prepare_citizens_menu_ui at 0x0040B570 calculates the satisfaction classes by converting the i16 into an f32, and picking the highest applicable class:

Satisfaction >Satisfaction Class
29.5Very Happy
19.5Happy
9.5Very Satisfied
0.5Satisfied
-10.5Dissatisfied
-InfinityAnnoyed

The function update_citizen_satisfaction at 0x0051C830 calculates the current satisfaction each population type would have. The satisfaction is then increased or decreaseed by the respective step size, depending on whether it was bigger or smaller than the current satisfaction, but it won't go beneath -40 or above 80. At 0x006736AC there is a table that contains for every difficulty the step sizes for increments and decrements to the satisfaction:

Needs SettingIncrementDecrement
Low31
Normal21
High12
Unused11

At 0x006736A0 there is a table that contains for every difficulty the base satisfaction for every population type:

Needs SettingRichWealthyPoor
Low-7-12-20
Normal-13-18-27
High-20-25-32

Within update_citizen_satisfaction 6 situational modifiers are implemented:

SituationImpact
Siege-10
Pirate Attack-8
Plague-10
Blocked-6
Boycotted-4
Famine-10

At 0x00672938 there is a table that defines ware satisfaction weights for every population type:

WareRichWealthyPoor
Grain248
Meat544
Fish266
Beer266
Salt224
Honey320
Spices300
Wine520
Cloth540
Skins320
WhaleOil344
Timber346
IronGoods220
Leather224
Wool264
Pitch000
PigIron000
Hemp000
Pottery324
Bricks000
Sword000
Bow000
Crossbow000
Carbine000

The current satisfaction is calculated as follows:

def get_ware_satisfaction(ware_id, population_type):
    if wares[ware_id] >= 2 * weekly_consumption[ware_id]:
        return satisfaction_weights[population_type][ware_id]
    else:
        return (wares[ware_id] - weekly_consumption[ware_id])
            * satisfaction_weights[population_type][ware_id]
            // weekly_consumption[ware_id]

current_satisfaction = 2 * (
    base_satisfaction
    + situational_modifiers
    + unknown_modifiers # 9 total, 8 capped at 4
    + ware_satisfactions
)