Crafted food is supposed to inherit properties from the specific components that comprise it. For example, boiled eggs should have different calories if they are made of generic bird eggs (80 cal.) vs turkey eggs (135 cal.) vs duck eggs (130 cal.)
In the inventory, this inheritance seems to be working properly - boiled eggs made from turkey vs duck display correct calorie values, and list the correct components.
However, immediately after eating either boiled duck eggs (130 cal.) or boiled turkey eggs (135 cal.), the stomach contents show as 80 calories.
This bug extends to nutrition-centered traits and CBMS - see Additional Context.
Steps to reproduce the behavior:
Stomach contents should match inventory descriptions of food.

_Boiled duck egg, inventory, with correct inherited values_

_Before and after eating boiled duck egg. Stomach registers 80 extra calories instead of expected 130._
No mutations or CBMs on this character.
I think I found the responsible code, but am too amateur in C++ to actually fix it.
Here is the first half of the function that handles food property inheritance. It's in consumption.cpp.
// TODO: Move pizza scraping here.
// Same for other kinds of nutrition alterations
// This is used by item display, making actual nutrition available to player.
int player::kcal_for( const item &comest ) const
{
static const trait_id trait_CARNIVORE( "CARNIVORE" );
static const trait_id trait_GIZZARD( "GIZZARD" );
static const trait_id trait_SAPROPHAGE( "SAPROPHAGE" );
static const std::string flag_CARNIVORE_OK( "CARNIVORE_OK" );
if( !comest.is_comestible() ) {
return 0;
}
// As float to avoid rounding too many times
float kcal = 0;
// if item has components, will derive calories from that instead.
if( !comest.components.empty() && !comest.has_flag( "NUTRIENT_OVERRIDE" ) ) {
int byproduct_multiplier;
for( const item &component : comest.components ) {
component.has_flag( "BYPRODUCT" ) ? byproduct_multiplier = -1 : byproduct_multiplier = 1;
kcal += this->kcal_for( component ) * component.charges * byproduct_multiplier;
}
kcal /= comest.recipe_charges;
} else {
kcal = comest.get_comestible()->get_calories();
}
if( has_trait( trait_GIZZARD ) ) {
kcal *= 0.6f;
}
Note that kcal_for() either calculates inherited food values OR instead allows get_calories() to retrieve default values.
However, the stomach code seems to directly call get_calories() in several places. I assume the stomach code should be modified to call kcal_for() instead, so it doesn't bypass the important rest of this function.
P.S.
This bug also extends to the Expanded Digestion bionic, the GIZZARD trait, etc., all of which are handled in kcal_for(). Adjusted calorie values do display properly in inventory, but are not reflected in stomach contents. (I tested this with other characters with relevant traits.)
The boiled egg entry in eggs.json does copy-from "egg_bird" which has 80 calories - but this is supposed to be only a default and be overridden by inheritance.
Duplicate of #30705
Yep, appears to be the same bug -- but this post adds more info and a potential solution :)
@KorGgenT I think this is stomach-relevant