Repository navigation
Recipes and Ingredients
Everything on this page goes under <productionPoint> and extends vanilla's own <productions>. No special placeable type is needed for it.
Vanilla requires all ingredients of a production line at the same time. A mix group turns that into "one of these": per cycle exactly one ingredient of the group is consumed, and the line runs as long as any of them is in stock. This is how you write "any kind of grain" into a recipe.
The group is set on the <input> in the mix attribute:
mix |
Meaning |
|---|---|
0 (default) |
Normal required ingredient, as in vanilla |
1 to 97
|
Group number. All ingredients with the same number are alternatives to each other |
boost |
Optional booster, see below |
master |
Optional master booster, see below |
<production id="anyGrainFlour" name="Mehl aus Getreide" cyclesPerHour="60" costsPerActiveHour="1">
<inputs>
<input fillType="WHEAT" amount="6" mix="1"/>
<input fillType="BARLEY" amount="6" mix="1"/>
<input fillType="OAT" amount="6" mix="1"/>
<input fillType="WATER" amount="2"/>
</inputs>
<outputs>
<output fillType="FLOUR" amount="5"/>
</outputs>
</production>This line always needs water plus one of the three grain types. The amounts may differ per alternative: a type with a lower yield simply gets a higher amount.
Several groups in one line are allowed and independent of each other — group 1 "any grain" and group 2 "any oil" side by side give both choices at the same time.
An empty mix group blocks the line. If not a single ingredient of the group is available, the line waits, exactly as with a missing required ingredient.
If more than one type of the group is in storage, the selection mode decides. It is a starting value: the player changes it per line in the Manage dialog, and from then on the player's value applies.
| Attribute | Location | Default | Meaning |
|---|---|---|---|
mixMode |
<productions> and <production>
|
ASC |
Starting value of the ingredient choice |
boostMode |
<productions> and <production>
|
ASC |
Starting value of the booster choice |
| Value | Selection | Shown to the player |
|---|---|---|
ASC |
the first ingredient of the group that is sufficient | First in recipe |
DESC |
the last ingredient of the group that is sufficient | Last in recipe |
MOST |
the type with the largest stock | Largest amount |
LEAST |
the type with the smallest stock | Smallest amount |
The order for ASC/DESC is the order in which the <input> lines appear one below the other in the XML. Set on the <productions> element, the value applies to all lines of the production point; set on a single <production> element, it overrides that for this one line.
The switch appears in the game automatically as soon as at least one mix group of the line has more than one ingredient. Changed values belong to the individual production point, not to the placeable template: they are stored in the savegame and synchronized to everyone in multiplayer.
Without any setting, the recipe shows "Mix group N" as the heading. title on one of the ingredients of the group replaces that:
<input fillType="WHEAT" amount="6" mix="1" title="$l10n_meinMod_getreide"/>
<input fillType="BARLEY" amount="6" mix="1"/>If several ingredients of the same group bring a title, the first one wins. Boosters and master boosters have their own headings and ignore title.
The text is resolved with the placeable's language scope, not with Revamp's. A $l10n_ key must therefore be in the own l10n file of the mod the placeable belongs to; Revamp's own texts are not visible there.
Boosters are optional ingredients that increase the yield. Missing stock never blocks production — it only drops the bonus. That is the essential difference to a mix group.
| Attribute | Location | Default | Meaning |
|---|---|---|---|
boostFactor |
<input> |
– | Multiplier. Required for mix="boost" and mix="master", must be greater than 0 and must not be exactly 1 |
boost |
<output> |
true |
Whether this product is affected by the booster |
boostFactor is a multiplier, not a surcharge: 1.5 means half as much again. The value 1 is reported as an XML error, because it would have no effect and is therefore almost always a mistake (for example a value from an FS22 recipe that was meant additively).
Boosters (mix="boost") act on the products: every booster with sufficient stock contributes its factor, and several active at the same time multiply. Two boosters with 1.5 and 2 therefore give a factor of 3. If you want exactly one to take effect instead, use the limitBoosters mode (see Weather and Time) — then only a single one counts and is consumed, selected according to boostMode.
Master boosters (mix="master") act on the entire throughput of the line, i.e. also on the consumption of all other ingredients — just not on their own consumption, which would be a feedback loop. Of several master boosters, exactly one wins with boostMode="MOST"/"LEAST"; with ASC/DESC all active ones multiply, as with a regular booster.
The recipe shows on the booster group which factor is actually in effect at the moment, plus a total boost display.
<production id="boostedFlour" name="Mehl mit Zusätzen" cyclesPerHour="60" costsPerActiveHour="1">
<inputs>
<input fillType="WHEAT" amount="6"/>
<!-- Optional: increases the flour yield by half -->
<input fillType="WATER" amount="1" mix="boost" boostFactor="1.5"/>
<!-- Optional: doubles the throughput of the whole line -->
<input fillType="ELECTRICCHARGE" amount="2" mix="master" boostFactor="2"/>
</inputs>
<outputs>
<output fillType="FLOUR" amount="5"/>
<!-- By-product that the booster should not multiply as well -->
<output fillType="STRAW" amount="2" boost="false"/>
</outputs>
</production>Instead of listing every type individually, an ingredient takes a whole category. The benefit shows when a map or another mod later brings a new type: if it belongs to the category, the production accepts it right away, without anyone having to touch the recipe.
| Attribute | Location | Meaning |
|---|---|---|
fillTypeCategory |
<input> |
Category (or categories) instead of a single fillType, several separated by spaces |
mix is required here. If it is missing or set to 0, the ingredient is discarded with an XML error: without a group, the category would turn into lots of individually required ingredients — "all types at the same time" — and that is never what is meant. An unknown or empty category is also discarded with an error.
All other ingredient attributes (amount, boostFactor, rngAffected, hideFromMenu) are copied to every resolved type. All types of a category therefore necessarily have the same amount — if you need different amounts per type, list them individually.
The category is resolved once at load time into individual ingredients of the same mix group. At runtime there is no longer any difference to a recipe in which all types are written out by hand. The following applies:
- The types are inserted sorted by fill type index, so that
mixMode="ASC"/"DESC"have a predictable order. - A type that is already an ingredient in the same production line is skipped. Two overlapping categories in one line therefore do not produce a duplicate ingredient; the type ends up in the group named first.
This is the most important point: using a category only in the recipe is not enough. It belongs on the storage and on the unload trigger just the same, and in none of these places as a written-out list of individual types. Only then does a type that someone later adds to the category automatically follow everywhere — otherwise it gets into the recipe, but cannot be unloaded or cannot be stored.
<input fillTypeCategory="REVAMP_GRAIN" amount="4" mix="1" title="$l10n_meinMod_getreide"/>
<storage capacity="60000" fillTypeCategories="REVAMP_GRAIN"/>
<unloadTrigger fillTypeCategories="REVAMP_GRAIN" fillTypes="WATER"/>The two vanilla elements behave differently here:
-
<storage>:fillTypeCategoriesandfillTypesare mutually exclusive, only one of the two may be set. Individual<capacity fillType="…"/>lines are added in both cases and give the respective type a different capacity. -
<unloadTrigger>:fillTypeCategoriesandfillTypesare combined, both side by side are allowed. In addition there isfillTypesExcludeto take individual types out again.
Types that do not have their own <capacity fillType="…"/> line share the value from <storage>#capacity — and nothing else. A 60,000 liter grain storage therefore holds 60,000 liters, no matter across how many types they are spread. Types with their own line are separate, independent tanks.
In the game, the amounts of these types are marked with a *, and the capacity shown is what can currently still be reached for the respective type. Vanilla calculates inconsistently at this point and reports the full pool for every type; Revamp corrects that. For your own XML this only means: <storage>#capacity is the shared pool, not an amount per type.
Revamp ships a set of ready-made categories in revamp_fillTypes.xml that every recipe author can use. Categories may overlap, so a carrot is listed under root crops and under vegetables at the same time.
| Category | Contents |
|---|---|
REVAMP_GRAIN |
Wheat, barley, oat, rice, long grain rice |
REVAMP_BASEFOOD |
Sorghum, corn |
REVAMP_OILFRUITS |
Sunflowers, canola, olives |
REVAMP_OIL |
Sunflower, canola, olive, rice oil |
REVAMP_PROTEINS |
Soybeans, canola, sunflowers, peas, green beans |
REVAMP_ROOTCROPS |
Potatoes, sugar beet, sugar beet cut, carrots, parsnips, red beet |
REVAMP_SUGARFRUITS |
Sugar beet, sugar beet cut, sugarcane |
REVAMP_FRUITS |
Grapes, strawberries |
REVAMP_VEGETABLES |
Tomatoes, lettuce, carrots, parsnips, red beet, spinach, green beans, peas, napa cabbage, spring onion, chili peppers, garlic |
REVAMP_MUSHROOMS |
Enoki, oyster mushroom |
REVAMP_GREENFEED |
Grass, hay |
REVAMP_BURNABLE |
Wood chips, straw, poplar |
REVAMP_FERTILIZER |
Solid fertilizer, manure |
REVAMP_LIQUIDFERTILIZER |
Liquid fertilizer, slurry, digestate |
REVAMP_MILK |
Cow, goat, buffalo milk |
REVAMP_ANIMALPRODUCTS |
Eggs, wool, all three types of milk, honey |
REVAMP_ORGANIC |
everything usable of plant origin, intended for compost, biogas and similar recycling recipes |
You create your own categories as usual in a fillTypes.xml. Using your own prefix is recommended: a plain name like ORGANICS extends a category of the same name on the map instead of creating a separate one. Conversely, extending an existing category is exactly the way to get your own crop into other mods' recipes, see Connecting Other Mods.
| Attribute | Location | Default | Meaning |
|---|---|---|---|
autoStart |
<productions> and <production>
|
false |
The line runs without any action by the player and cannot be switched off |
hideFromMenu |
<productions>, <production>, <input>, <output>
|
false |
The line, or the ingredient or product, does not appear in the production menu |
sharedThroughputCapacity |
<production> |
true |
Whether the line takes part in the capacity sharing across the production point |
rngAffected |
<input> and <output>
|
false |
Consumption or yield varies randomly instead of being exactly fixed |
primaryProductFillType |
<output> |
false |
Forces this product as the primary one of the line |
A line with autoStart is switched on immediately after building, stays on across saving, and the "Deactivate" button is not offered at all. This is intended for production points where switching off makes no sense — for example when the line only processes what is delivered anyway.
It can no longer be switched off anywhere, not even by an old savegame in which it was still saved as switched off. That is intentional: if autoStart is only added with a new version of the production, the line would otherwise stay off forever, because the button to switch it on is missing.
hideFromMenu on a line implies autoStart — otherwise nobody could ever switch on a hidden line.
Also worth knowing: when a production point is built during a running game, the game switches off every line on its own. Without Revamp, autoStart would therefore only take effect after the savegame is loaded the next time.
<!-- Default for all lines of this production point -->
<productions autoStart="true">
<production id="cheese" cyclesPerHour="60" costsPerActiveHour="1">
...
</production>
<!-- The player may control this one line after all -->
<production id="butter" autoStart="false" cyclesPerHour="30" costsPerActiveHour="1">
...
</production>
</productions>Vanilla's sharedThroughputCapacity on <productionPoint> splits the throughput across all lines running at the same time — the production point then does not work on everything in parallel, but distributes its capacity. On an individual <production>, sharedThroughputCapacity="false" excludes a line from this; it then always runs at full speed, regardless of how many other lines are currently active.
A line that is currently standing still because of weather or opening hours gives its share to the others instead of slowing them down as well.
In the production menu, an icon next to the line shows whether the production point works in parallel or split.
- The logical categories all still exist, with the same names. They have been extended with the new FS25 crops;
REVAMP_MUSHROOMSandREVAMP_MILKare new. -
mixis now required for a category. In FS22 a missing value was silently0, which turned the category into lots of required ingredients. -
boostFactoris multiplicative. An FS22 value that was meant as a surcharge means something different here and has to be recalculated. The neutral value 1 is reported as an error, so that a directly carried-over value stands out instead of silently working wrong. - For the player,
ASCandDESCare no longer called "ascending"/"descending", but "First in recipe"/"Last in recipe". The XML value stays the same, only the display is clearer. - In FS22 the ingredient and booster choice was a menu button that only appeared while the recipe list had keyboard focus. Now it has a fixed place in the Manage dialog and shows all lines at once. The XML attributes are the same, but are now only a starting value — from the moment a player changes something, the player's value applies.
- The categories of the price filters (
REVAMP_FILTER_*) and of the storage extension (ADDITIONAL_STORAGE_*) belong to their own modules and have not been ported yet.
See also: Weather and Time for limitBoosters and the conditions of a line, Buying and Selling for the locks on the storage.