I guess this is the thread for research? If so, I think I found something that doesn't seem to be mentioned anywhere else. Is the connection between the Recuperation attribute and dwarf obesity widely known?
I was trying to figure out why most of my starting dwarves had gotten severely obese by a couple years into the game, and had assumed it had something to do with all the lavish meals I was feeding them, so I looked around to see if there was any information on how weight gain works in Dwarf Fortress, and couldn't find anything.
I did a bit of research myself with dfhack, and found that the answer is that most of my starting dwarves have poor Recuperation. While mining on a full stomach, a particular dwarf with 800 Recuperation will actually gain around 300 stored_fat every 150 ticks; the exact same dwarf with their Recuperation changed to 2200 will lose 1000 stored_fat every 150 ticks. I strongly suspect that Recuperation determines a Dwarf's target stored_fat, and their weight loss/gain is modified to keep them near that target value.
A dwarf's job doesn't seem to impact this at all. Miners who work flat out for years will still be fat if they have low Recuperation, while completely sedentary nobles will still be thin if they have high Recuperation. And the game doesn't seem to differentiate types of food, either.
In case anyone finds it useful for testing, here's the script I used to monitor changes to dwarves' weight:
local utils = require 'utils'
validArgs = validArgs or utils.invert({ 'unit' })
local args = utils.processArgs({...}, validArgs)
local unit = nil
if args.unit and tonumber(args.unit) then
unit = df.unit.find(tonumber(args.unit))
else
print('No unit selected')
return
end
if unit == nil then print('Bad unit ID') return end
lastWeights = lastWeights or {}
local previousWeight = lastWeights[tonumber(args.unit)] or nil
local currentWeight = unit.counters2.stored_fat
lastWeights[tonumber(args.unit)] = currentWeight
local output = dfhack.TranslateName(dfhack.units.getVisibleName(unit)) .. ': weight=' .. currentWeight
if previousWeight ~= nil then output = output .. ' (' .. (currentWeight - previousWeight) .. ')' end
output = output .. ' job='
if unit.job.current_job == nil then
output = output .. 'No Job'
else
output = output .. dfhack.job.getName(unit.job.current_job)
end
output = output .. ' content=' .. unit.counters2.stomach_content .. ' food=' .. unit.counters2.stomach_food
print(output)
Takes a unit ID and prints their weight, stomach_content, and stomach_food, as well as the weight change since the script was last called for that unit. Works well with the repeat script set to a tick interval.