v50 Steam/Premium information for editors
  • v50 information can now be added to pages in the main namespace. v0.47 information can still be found in the DF2014 namespace. See here for more details on the new versioning policy.
  • Use this page to report any issues related to the migration.
This notice may be cached—the current version can be found here.

Category talk:DF2012:Incomplete butchering returns

From Dwarf Fortress Wiki
Jump to navigation Jump to search

Calculation[edit]

I think it's possible to calculate butchering returns from the raws, rather than observing it empirically.

Here's how the calculation works, as far as I can tell:

First, go through each body part the creature has. Using the BODY_DETAIL_PLAN, figure out how much of that body part is muscle, fat, etc. For instance, a sperm whale's flipper is 50/56 muscle, 5/56 fat, and 1/56 skin.

Second, multiply that number by a constant depending on the material concerned. For fat, the constant is 2; for every edible product except fat (meat, brain, etc.), it's 1. I'm not sure of the constant for other materials.

Third, figure out what portion of the creature is in that body part -- this is just the relsize of that body part divided by the sum of the relsizes of all body parts. Scale the result from step 2 by this number.

Sum this up for all body parts. For example, in the case of a sperm whale, we get 200 for brain, 2384 for meat, 518 for fat, etc. (for simplicity's sake and to make calculation easier, I multiplied all of them by the sum of relsizes). You can see that the ratios here are very close to the observed ratios. The absolute number is proportional to the size of the animal when alive (you can see this by comparing the returns from giant and normal varieties of a given animal -- the yield is always directly multiplied by the same amount that body size is). I haven't worked out the constant of proportionality, though -- if it's done by volume rather than mass, it'll be different for different body plans. --Zzedar (talk) 22:11, 15 April 2013 (UTC)

Such a calculation has been on my list of things to consider implementing for quite a while. If you can generalize this for any creature then it would certainly prove beneficial. However, the complexity could grow quite quickly if different body structures introduce different constants, etc. Still, it doesn't really matter if the code is ugly, as long as the results are accurate. Give it a shot if you want the challenge; if not, I might get to it eventually. --Loci (talk) 19:41, 17 April 2013 (UTC)
I've been trying to do it, but not with much luck. There seems to be some weird sort of rounding per body part that throws off the calculations for moderately-sized creatures -- for very large creatures I think I've got it worked out, but there are only a few creatures in the game large enough that they eliminate the rounding effects. I'll keep working on it, but... tell me, do you know of any tool that'll automatically process the raws and deliver the full body plan by substituting in the values from the body tokens and body detail plan tokens? Right now I'm doing it by hand, which is slowing me down enormously. (I don't think it's possible to do this with just DFRawFunctions, because of the way the body tokens can be nested)--Zzedar (talk) 19:54, 17 April 2013 (UTC)
Doing any kind of complex processing using wiki-code is very difficult. For Dwarf-Fortress-specific raws processing, it may be best to create a new #dfrawfunction. Quietust created the functions; he's probably the best person to speak to about adding new functionality. --Loci (talk) 20:04, 18 April 2013 (UTC)
Ha, figured it out! The problem was twofold: first, the relative thicknesses are rounded beforehand to the nearest tenth of a percent, and they don't always add up to 100 percent. In addition, I was neglecting to take into account the fact that not all returns are the same size; e.g., fat globs are smaller than sweetbreads, so you can get more from a given amount of fat. I've worked up a Lua script for DFHack that will figure this all out, but as to whether it'd be practical to implement such a function on the wiki... hard to say. (There's also another problem: the figures in the raws are for the animal's "default" state. Exercise bulks up the muscle, eating a lot bulks up the fat... it may well be that there's some systemic bias away from the default state for a given animal).--Zzedar (talk) 02:32, 27 April 2013 (UTC)

Oh, and here's a crude (very crude, this is just a proof of concept) script to do add it up for a single creature:

local input = ...
local indexNum = tonumber(input)
local unit = df.global.world.units.active[indexNum]

local parts = unit.body.body_plan.body_parts

local layerHold = {}

for k, part in pairs (parts) do
	for k2, layer in pairs (part.layers) do
		layerHold[layer.layer_name] = (layerHold[layer.layer_name] or 0) + (layer.unk2*part.relsize*part.number/part.unk2)
	end
end

printall(layerHold)

And to do it by raws:

local input = ...
local raceNum = tonumber(input)

local raws = df.creature_raw.find(raceNum)
local raceName = raws.creature_id

print(raceName)

local parts = raws.caste[0].body_info.body_parts

local layerHold = {}

for k, part in pairs (parts) do
	for k2, layer in pairs (part.layers) do
		layerHold[layer.layer_name] = (layerHold[layer.layer_name] or 0) + (layer.unk2*part.relsize*part.number/part.unk2)
	end
end

printall(layerHold)

(This assumes no variation in body plan between the different castes of a species, which will not be true for, e.g., moose).--Zzedar (talk) 07:48, 29 April 2013 (UTC)

Dammit, still not working, larger creatures don't fit the same pattern as smaller ones. I wonder if it's implemented as a hollow cylinder, so the ordering of the layers would matter -- amount of tissue would depend on circumference as well as thickness then.--Zzedar (talk) 17:35, 29 April 2013 (UTC)
Just curious, what language is that?
Also, I think there's probably a minimum and maximum size for creatures (well, adult creatures - children are obviously small). Focusing on calculating those might solve the problem with varying sizes (then again, it could make it more confusing). Memory hacking might be an alternative – I don't know much about that either, but Quietust might be able to help. --Lethosor (talk) 20:04, 29 April 2013 (UTC)
Whoops, there was a major bug in these (now corrected)! (Also, I was wrong about something else, but I haven't corrected it because it isn't important). The language is Lua; these are intended as Lua scripts to be run by DfHack. There is a minimum and maximum size, as you say. That's a good point. Here's what I've learned: for very large creatures, and for most tissues, you can just take the value yielded by this and multiply it by a constant to get the expected yield. That constant will be the same for most organs and for muscle (which yields meat); if the tissue in question is fat, you multiply it by a further factor of 2 afterwards, and if the tissue is bone, you divide it by 2. There are also certain materials that have "butcher_special_type" set, which seems to influence the return in some way I haven't quite figured out yet.

For instance, these scripts will yield the following values for a sperm whale: Muscle 2297.357, Fat 249.699, Bone 1123.447, Intestine 600. That works out very well with the ranges given on the sperm whale's page. I haven't yet figured out how it works for smaller creatures -- whether each body part is counted separately or whether they're summed or what.--Zzedar (talk) 03:19, 8 May 2013 (UTC)