Skip to content

Contamination

petrolpark edited this page Jan 19, 2026 · 24 revisions

This Library introduces an API for Contamination. This allows various objects (most prevalently Items, but also Fluids, Entities and some Block Entities) to have things called Contaminants. These are simple flags that these contaminable things either do or do not possess. A key feature of these Contaminants is that they are preserved when crafting with Items.

Definitions as used in the API

  • Contaminant - A property a contaminable object can have. These are of the class Contaminant.
  • Contamination - The set of all Contaminants possessed by an Item (or other object). Every Item Stack has a unique Contamination, but they can share Contaminants. These implement the interface IContamination.
  • Contaminable - The whole class of objects that can have Contaminations. This library supplies two main Contaminables: Items and Fluids.

Contaminated Items

The primary use of Contamination is with Item Stacks, as these are the things Players craft with the most. By default, BlockItems (Items which can be placed as Blocks) cannot be Contaminated as Contamination is stored in Item Stacks' Components and these are not preserved when Blocks are placed.

You can make a BlockItem contaminable by adding it to the Item Tag (not Block Tag) petrolpark:contaminable_blocks. But getting it to actually remember its Contamination when placed must be done in code, usually by storing the Contamination in a Block Entity associated with the Block. You can use a GenericContamination for this.

If you are a Create add-on, add a ContaminationBehaviour to the Block Entity Behaviours. This is done automatically for any Blocks implementing Create's KineticBlock and whose Block Entity Types are in the Tag petrolpark:contaminable_kinetic, if you are looking for a code example.

You can also make a non-BlockItem not able to have Contamination by adding it to the Tag petrolpark:uncontaminable.

Recipes

By default, Contaminants are propagated according to each Contaminant's preservationProportion for a variety of vanilla and Create processes like Crafting, Smelting, Brewing, Milling and Mixing (to name a few). These can be configured more or less individually in the Library's per-world configs.

It is strongly recommended that if you are developing a mod with this Library as a strict dependent that you propagate Contaminants in your mod's Recipes whenever they are crafted. This can be as simple as calling the following:

ItemContamination.propagate(streamOfMyInputStacks, outputStack);

This exact thing is done numerous times in the Library's code. See CraftingMenuMixin and AbstractCookingRecipeMixin for examples. You should also trigger Item Decay at these points.

Using Contamination in Code

You can obtain the Contamination of an object with the static method:

IContamination.get(Object)

However, there are faster methods for if you know the type of the object:

ItemContamination.get(ItemStack)

FluidContamination.get(FluidStack)

Once you have a Contamination, the methods to add and remove Contaminants are fairly obvious:

IContamination<?, ?> contamination = ItemContamination.get(stack); // Get the Contamination of some ItemStack

contamination.contaminate(myContaminant)

contamination.decontaminate(myContaminant)

Using Contamination in Datapacks

Contamination can also be accessed in data-driven resources like Loot Tables, Advancements and Recipes.

TODO

Defining Contaminants

Contaminants (as defined above) are data-driven objects, meaning they can be added by datapacks (and any datapack-modifying programs like KubeJS). Contaminables are not.

Contaminants belong to the petrolpark:contaminant Registry and can be registered in the usual way by adding a file data/yourmodid/petrolpark/contaminant/your_contaminant.json with the following structure:

{
 "preservationProportion": 0.5,
 "color": 5635925,
 "absentColor": 16733525,
 "children": [
  "yourmodid:other_contaminant"
 ]
}
  • preservationProportion is the required proportion of total input Items (or total millibuckets of input Fluid etc.) which must have this Contaminant in order for the result to also be given the Contaminant. It must be a number between 0.0 and 1.0 inclusive.

    For example, if the preservation proportion is 0.5, then crafting an Iron Ingot out of 4 contaminated and 5 uncontaminated Iron Nuggets will produce an uncontaminated Ingot, but 5 contaminated Nuggets (or greater) will produce a contaminated Ingot. This count only includes contaminable Items (e.g. not BlockItems or Items tagged with petrolpark:uncontaminable), and does not care about the individual input Items, only the total number.

    preservationProportion: 0.0 will mean any contaminated inputs at all will produce a contaminated output.

  • color is the color (as a 6-digit hexadecimal color code converted to denary) of the tooltip that renders when an Item Stack has the Contaminant.

  • absentColor is the color of the tooltip that renders when an Item Stack does not have a Contaminant. Note you will only see this tooltip if the Item belongs to the Tag yourmodid:contaminant/your_contaminant/show_if_absent.

  • children is a list of Child Contaminants IDs. It can be empty.

You must also add the following entries to your language files (unless your Contaminant is Tagged petrolpark:hidden):

 "contaminant.yourmodid.your_contaminant": "Has my Contaminant",
 "contaminant.yourmodid.your_contaminant.absent": "Doesn't have my Contaminant"

You can add Items to two Tags relating to your Contaminant:

  • yourmodid:contaminant/your_contaminant/intrinsic will cause all Item Stacks of that Item to always have the Contaminant no matter how they are created. They can be propagated as usual.
  • yourmodid:contaminant/your_contaminant/show_if_absent will cause the tooltip not to render if an Item Stack has the Contaminant, but to render the .absent tooltip to render if it does not have it.

If you add the Contaminant itself to the Tag petrolpark:hidden, the tooltip will not show in either case.

API Reference

Flags than can be applied to Item Stacks and other objects and will propagate through crafting

Timers that can be attached to Item Stacks to modify them after a given time, no matter what Inventory they are in

A way for mods to detect groupings of Players and store information on these groupings

Manipulation of Loot Table randomness and other RNG to give desired Items

Additional inventory and hotbar slots for the Player

Blocks and Items that have variants craftable from any mod's wood

Loot and Data

Data-driven modifications to existing Loot Tables with greater versatility than NeoForge Global Loot Modifiers

Data-driven changes to the world (give Items, XP, unlock Villager Trades)

Levelable "Shops" shared between Teams giving Rewards for randomly-generated Item requests

Additional implementations of vanilla's Number Providers used in Loot Tables and Advancements

Recipes

Extension of NeoForge Ingredients to include descriptions and Loot Table forcing

Work with automatically-detected "compression" Recipes (e.g. Nuggets <-> Ingots <-> Blocks)

Recycling (page under construction)

Balanced and versatile "uncrafting" API

Gating Recipes for vanilla and modded Items behind Item unlocks

Changelogs

1.3.1, 1.3.2, 1.3.3, 1.3.4
1.4.0, 1.4.1, 1.4.2, 1.4.3, 1.4.4, 1.4.5, 1.4.6, 1.4.7, 1.4.8, 1.4.9, 1.4.10, 1.4.11, 1.4.12, 1.4.13, 1.4.14, 1.4.15, 1.4.16, 1.4.17, 1.4.18, 1.4.19, 1.4.20, 1.4.21, 1.4.22, 1.4.23, 1.4.24, 1.4.25, 1.4.26

Clone this wiki locally