Origin-Gated Recipes
Added in 2.2.0.
Pack authors can gate crafting recipes on a player’s current origin / power state. Gated recipes still load and still appear in the recipe book; they simply refuse to match while the crafting player fails any gate, so the result slot stays empty.
This is a runtime per-player gate — there is no datapack reload required when a player switches origin via the Orb of Origin, the picker, or admin commands. The gate is re-evaluated every time the crafting grid changes.
Scope. Only crafting-table / 2x2 inventory recipes are supported by the wrapper today. Cooking variants (smelting, blasting, smoking, campfire) use different menus and call paths and are not yet wrapped — see “Future work” below.
Recipe form
Wrap any vanilla crafting recipe (shaped, shapeless, or a third-party crafting serializer) by placing it under the inner key and listing one or more gates:
{
"type": "neoorigins:origin_gated_crafting",
"gates": [ /* OriginGate, OriginGate, ... */ ],
"inner": { /* any RecipeType.CRAFTING recipe */ }
}
Gates are evaluated with AND semantics — every gate in the list must pass. For OR semantics, ship multiple recipes with the same output and one gate each.
Gate shapes
neoorigins:has_origin
Passes if the player has the given origin in any layer.
{ "type": "neoorigins:has_origin", "origin": "neoorigins:human" }
neoorigins:has_power
Passes if the player currently has the given power (origin-granted, layer-granted, dimension-permitted, or dynamically granted via the grant_power action).
{ "type": "neoorigins:has_power", "power": "neoorigins:merling_water_breathing" }
neoorigins:in_layer
Passes if the player’s selection for the given layer matches origin. Use this when you want the gate to be specific to one layer (e.g. a class layer that overlays an origin layer).
{
"type": "neoorigins:in_layer",
"layer": "neoorigins:origin",
"origin": "neoorigins:avian"
}
Examples
See data/neoorigins/recipe_examples/ in the mod jar for one example per gate shape. The recipe_examples/ folder is intentionally outside the vanilla recipe/ scan path, so the examples ship as in-tree documentation only — copy any of them into your own data/<ns>/recipe/ to activate.
Behavior notes
- Recipe book: gated recipes are marked
isSpecial(), which suppresses the autofill “completable” highlight. The recipe is still visible in the book; clicking it just won’t populate a result. This avoids teasing players with results they can’t actually take. - JEI / REI: gated recipes show up like any other crafting recipe. Players that try to craft them without the right origin will see an empty result slot.
- Servers: the gate is evaluated on the server side during the
slotChangedCraftingGridcall. The recipe serializer is registered on both sides viaBuiltInRegistries.RECIPE_SERIALIZER, so dedicated servers and integrated servers both load gated recipes correctly, and clients deserialize the recipe-book sync payload without warnings. - Hopper / automation: hoppers feeding a crafter block do not provide a player context. Gated recipes will not craft via the Crafter block; the gate falls back to “deny” when no player is present. This is by design — gated recipes are a player capability check, not a recipe recipe-book filter.
Future work
- Cooking variants. Wrapping
AbstractCookingRecipewould require a similar context mixin onAbstractFurnaceBlockEntity#serverTickand a policy decision about “which player owns the furnace?” (last user? area owner?). Open for backlog discussion in 2.2. NOT/ORcomposite gate. Today multi-gate is AND only.