Adds one block — the Sandwich Station — where any base plus up to nine edible items becomes a sandwich. Hunger, saturation, and status effects come from what you actually put in. Every rule behind that is a datapack tag or a config key, so a modpack can add ingredients, ban an effect, or rebalance the whole thing without rebuilding the jar.
Install on both the client and the server. Works in singleplayer.
Dependencies: Fabric & NeoForge require Architectury API. Forge requires no additional dependencies.
Free to use in any modpack — public or private, no permission needed.
S K S S = Smooth Stone Slab
P B P K = Shears
P = #minecraft:planks
B = Barrel
Unlocks in the recipe book when a barrel reaches your inventory.
Hunger and saturation are the sum of the base and every ingredient, scaled by config multipliers and waste. The total is split into servings (never one oversized sandwich). Effects are merged from ingredients, then filtered, scaled, split across servings, and capped — nothing is rolled at random. Diversity scores distinct flavour categories (datapack tags) and can add saturation / longer effects; quality labels: Plain → Mixed → Varied → Gourmet.
File: config/sandwichstation.json (created on first launch, with a // comment above every key). Re-read whenever a player opens a station — edit, open the block again, no restart.
Main switches
stationEnabled (true) — master switch; false keeps items registered but composes nothingdebugLogging (false) — log every compositionNutrition (nutrition.*)
humbleMaxNutrition (3) / regularMaxNutrition (6) — tier thresholdsmaxServings (16) — max sandwiches from one lot of ingredientsmaxIngredientSlots (9) — usable grid slots; the rest locknutritionMultiplier / saturationMultiplier (1.0) — scale totalswasteFactor (0.0) — fraction thrown awaymaxNutritionPerServing (10) / maxSaturationPerServing (12.0) — per-sandwich capspaperBaseNutrition (0) — food value for a base with none of its ownallowSandwichAsBase (true) / allowNonFoodBases (true)Effects (effects.*)
enabled (true) · budgetScale (1.0) · maxEffects (3) · maxAmplifier (1)minDurationTicks (20) · maxDurationTicks (6000)divideDurationAcrossServings (true)conflictPolicy (KEEP_STRONGER | DROP_BOTH | KEEP_BOTH)blockedEffectIds ([]) — effects that never transferDiversity (diversity.*)
enabled (true) · weightPerCategory (1) · weightPerUniqueIngredient (0)saturationBonusPerPoint (0.25) · effectDurationBonusPercentPerPoint (5)Content (content.*)
requireEdibleIngredients (true)extraBaseIds / blockedBaseIds / extraBaseTagsextraIngredientIds / blockedIngredientIds / extraIngredientTags / blockedIngredientTagsIntegration (integration.*)
showQualityTooltip, showIngredientTooltip, maxTooltipIngredients, autoNameResults, playCraftSound)Ids are normalized (Bread, minecraft:bread, minecraft:bread all match; missing namespace → minecraft).
| Layer | Where | Reload | Use for |
|---|---|---|---|
| Datapack tags | data/sandwichstation/tags/... |
/reload |
bases, ingredients, flavour categories |
| Config | config/sandwichstation.json |
next station open | every number, switch, ban list |
| Java API | your mod | — | food whose value is only known at runtime |
Tags: bases, ingredients, blocked_ingredients, and categories/{meat,fish,vegetable,fruit,grain,sweet,fungus,exotic}.
Paths — 1.19.2 / 1.20.1 use plural folders (tags/items, recipes, advancements, loot_tables); 1.21.1+ use singular (tags/item, recipe, advancement, loot_table).
Override the station recipe at the same path / id sandwichstation:sandwich_station. If your recipe no longer uses a barrel, also override the unlock advancement (it watches for a barrel by default).
Cannot change without a jar: fixed item/block ids; composition is a pure function of the sorted ingredient list; the station has no block entity (cannot hold items between sessions).
Please report any bugs, errors, or feature suggestions on Discord: https://discord.gg/HTkn94BXmA
My other mods that I recommend.