How a craft stores its inputs and outputs
A craft definition keeps its inputs in needItems and its outputs inside chanceOutputItems, which is why one recipe can yield several items and why an output can be probabilistic.
- Guide
- Release 1.0
- Verified
- Checked 2026-09-25
Facts
- Craft definitions
- 827
- With at least one input
- 584
- With at least one output
- 468
- Input shape
- item id plus a count expression
- Output shape
- chanceOutputItems array, so a craft may have several outputs
Where the numbers come from
The game ships a single GameBalance object inside resources.assets. It holds a craftDefs array of 827 entries. Each entry carries needItems for what it consumes and outputItems for what it produces. Nothing on this page is estimated: the counts are read straight out of that object.
The input list is flat
needItems is a flat list of entries, each pairing an item id with a count. 584 of the 827 crafts have at least one entry. A recipe that takes two different materials therefore appears as two entries rather than one entry with two counts.
Outputs are nested, which is the part that surprises people
outputItems is not a list. It is an object whose chanceOutputItems field holds the produced items. Because the field is named for chance, a craft can carry several possible outputs, and a planner that reads outputItems as a flat array will report zero outputs for all 827 crafts. Reading chanceOutputItems instead finds 468 crafts that produce something.
Working out the base materials
Expand a target item by repeatedly replacing each entry with the inputs of a craft that produces it, accumulating counts. Stop when an item has no producing craft: that item is a base material. The recursion has to remember the items already on the current path, because a production chain can loop back on itself. Without that guard the expansion does not terminate.
What this page does not claim
The counts above are read from the shipped data, but which workstation a craft is offered at, and whether an output is guaranteed or probabilistic, still need review before they are published as facts. Those fields are recorded and deliberately left out of the claims here.
Related entries
- Graveyard Keeper 2related to
Sources
Read directly from the GameBalance object in the shipped build through scripts/gb_reader.py, cross-checked against the handover snapshot.