Datapacks
Preservation is fully data driven. Datapacks can define spoilage stages, add modifier categories and modifiers, add smoker and campfire recipes that apply a modifier, and overlay the mod's food tags. The same files work on every supported version and loader. Use /reload after changing a datapack.
Spoilage stages
Path: data/<namespace>/fffoodspoilageandpreservation/stage/<id>.json (a synced registry). Stages are sorted by order (lowest is freshest, ties by id). The first stage is fresh and the last is final: food that fills it is fully spoiled. If a datapack leaves no stages, the built-in defaults are used. This is the built-in Rotten stage:
{
"order": 4,
"name": {"translate": "stage.fffoodspoilageandpreservation.rotten"},
"color": "RED",
"duration_ticks": 2400,
"debuff_chance": 0.35
}
| Field | Meaning |
|---|---|
order | Integer sort position, lowest first (default 0) |
name | Text component shown in tooltips (required) |
color | Tooltip color: hex like #55FF55 or a color name like GOLD (default WHITE) |
duration_ticks | Ticks needed to fill the stage at the normal rate, at least 1 (required) |
buff_chance / debuff_chance | 0 to 1 chance of a random buff or debuff when eating food in this stage (default 0). Needs freshBuffs.enabled / nearSpoiledDebuffs.enabled in the server config |
buffs / debuffs | Optional lists of {effect, duration_ticks (default 100), amplifier (default 0), weight (default 1)}. When empty, the freshBuffs.buffs / nearSpoiledDebuffs.debuffs config tables are used |
nutrition_multiplier / saturation_multiplier | Optional 0 to 1 absolute multiplier for this stage. When absent, the compounding nutritionPerStage / saturationPerStage config values apply |
noise_intensity / noise_color | Optional 0 to 1 intensity and hex color overriding the client spoilage noise ramp for this stage |
Built-in stages: fresh (order 0, #55FF55, 1200 ticks, buff_chance 0.15), good (1, #9BE03A, 2400), stale (2, YELLOW, 3600), rotting (3, GOLD, 2400) and rotten (4, RED, 2400, debuff_chance 0.35).
Modifier categories
Path: data/<namespace>/fffoodspoilageandpreservation/modifier_category/<id>.json (a synced registry).
{
"priority": 0,
"exclusive": true,
"display_name": {"translate": "tooltip.fffoodspoilageandpreservation.category.preservation"}
}
| Field | Meaning |
|---|---|
priority |
Higher categories rank first in tooltips and draw their tint in front |
exclusive |
Only one modifier from this category can be on a food at once |
display_name |
Text component shown in tooltips |
Modifiers
Path: data/<namespace>/fffoodspoilageandpreservation/modifier/<id>.json (a synced registry). This is the built-in Candied modifier:
{
"category": "fffoodspoilageandpreservation:preservation",
"rate_multiplier": 0.40,
"prevent_eating": false,
"display_name": {"translate": "tooltip.fffoodspoilageandpreservation.modifier.candied"},
"tooltip_color": "GOLD",
"item_tint": "#F2A21B",
"item_visuals": [
{"type": "gradient", "color": "#F2A21B", "opacity": 30, "end_color": "#7A3F00", "end_opacity": 65, "angle": 0}
],
"apply_items": ["minecraft:honey_bottle"],
"remove_items": [],
"food_whitelist": [],
"food_blacklist": ["#fffoodspoilageandpreservation:soups"],
"auto_apply_when_cold": false,
"auto_remove_when_warm": false
}
| Field | Meaning |
|---|---|
category |
The modifier category this belongs to |
rate_multiplier |
Multiplies the spoilage rate. Lower slows spoilage more |
prevent_eating |
Food with this modifier can't be eaten (Frozen uses this) |
display_name / tooltip_color |
Tooltip text and its color |
item_visuals (0.12.0) |
List of visual layers drawn on the food in inventories and hands, in order (last in front); see below. Needs FFUtilities 0.2.17 |
item_highlight |
Legacy, still works when item_visuals is empty or missing: none (default), tint, outline or both, drawn in item_tint. Older files with tint_item: true and no item_highlight count as tint |
item_tint |
#RRGGBB default color for layers that give no color (and for the legacy highlight) |
apply_items / remove_items |
Items that apply or remove the modifier when crafted with food. Each entry may be an item, a #tag, or minecraft:potion#minecraft:awkward for a potion type |
food_whitelist / food_blacklist |
A non-empty whitelist restricts which foods qualify; otherwise every spoilable food qualifies except the blacklist |
auto_apply_when_cold / auto_remove_when_warm |
Temperature-driven modifiers like Frozen |
Item visuals
Each entry of item_visuals is one layer. Layers draw in list order, so the last is in front, and modifiers on the same food stack with the lowest-ranked first.
| Field | Meaning |
|---|---|
type |
Required. tint (flat color), gradient (color fading to end_color along angle), radial (color at the center to end_color at the edges), noise (sparse flecks like salt or frost), desaturate (drains the food's own color; opacity is the amount) or outline (1-pixel border, inventories only; the highest-ranked modifier's outline wins) |
color / end_color |
Hex color. color defaults to the modifier's item_tint |
opacity / end_opacity |
0 to 100 percent. opacity defaults to 35 and is the start opacity of a gradient; end_opacity defaults to the same value, so a gradient can fade in from nothing |
blend |
normal (default), multiply, screen or overlay: how the color mixes with the food's own pixels |
angle |
Gradient direction in degrees (default 0): 0 runs top to bottom, 90 left to right, 180 bottom to top, 270 right to left |
intensity |
noise only: 0 to 100 (default 30), how many flecks |
For example, the built-in Frozen modifier uses a 35 percent tint layer plus an outline layer, and Cured uses a faint white tint plus white noise. The player's client option modifierVisualOpacity scales every layer's opacity.
Within a category, the modifier with the lowest rate_multiplier ranks highest. It wins when two modifiers share an apply item, and only a higher-ranked modifier replaces an existing one in an exclusive category. Modifiers no longer have their own priority; old files that still set it load fine and the value is ignored.
Built-in IDs: preservation, temperature (categories) and cured, brined, candied, smoked, frozen (modifiers). Old saves with "cured" resolve to fffoodspoilageandpreservation:cured.
Cooking recipes
Smoker and campfire recipes keep the same food and apply a modifier:
{
"type": "fffoodspoilageandpreservation:modifier_smoking",
"modifier": "fffoodspoilageandpreservation:smoked",
"cookingtime": 100,
"experience": 0.1
}
Use "type": "fffoodspoilageandpreservation:modifier_smoking" for smokers and "type": "fffoodspoilageandpreservation:modifier_campfire" for campfires.
Item tags
You can overlay these item tags:
| Tag | Meaning |
|---|---|
#fffoodspoilageandpreservation:never_spoil |
Foods that never spoil |
#fffoodspoilageandpreservation:soups |
Soups (Candied skips them) |
#fffoodspoilageandpreservation:smokable |
Cooked meat and fish the built-in Smoked modifier accepts (its food whitelist) |