-
Notifications
You must be signed in to change notification settings - Fork 1
Creating a Tweaker Add On
Tweakers are designed to be extensible, so other mods can add support for their own recipes and systems. Starting with LibCD 2.0, tweakers are added inside the initTweakers
block of a LibCDInitializer
set as a libcd
entrypoint in Fabric. The initTweakers
block is passed an instance of the TweakerManager
which is used for registration of tweakers, assistants, and stack factories.
All tweakers and assistants are given string names using package notation, e.g. LibCD's built-in "libcd.recipe.RecipeTweaker"
. If you need to register multiple copies of the same tweaker, such as with Artis tables, you should specify a standard package notation name, then append an @
symbol and the discriminating ID for the instance of the assistant. Using Artis as an example, a tweaker for a table named artis:test_table
would be named "artis.ArtisTweaker@artis:test_table"
.
The tweaker manager contains the following methods for extending tweakers:
-
public void addTweaker(String name, Tweaker tweaker)
- Registers a tweaker instance to the given name. The name should have package notation (see above). -
public void addAssistant(String name, Object assistant)
- Registers an assistant class to the given name. The name should have package notation (see above). -
public void addAssistantFactory(String name, Function<ScriptBridge, Object> factory)
- Registers a factory for an assistant class to the given name. The name should have package notation (see above). -
public void addStackFactory(Identifier id, TweakerStackFactory factory)
- Registers a factory for getting specific stacks based on an identifier. Accessed from a script asfactory:id->factory:stack
.
The Tweaker
interface defines a class which can be used to perform transformations to game data in a more auditable and structured way than just using assistants. The interface contains five methods:
-
void prepareReload(ResourceManager manager)
- Run before any tweaker scripts are run. Used to prepare the tweaker so it can be used on the current resource reload. Passed the resource manager being used to reload data packs. -
void applyReload(ResourceManager manager, Executor executor)
- Run after all tweaker scripts are run. Used to apply any changes made by tweakers during tweaker execution. Passed the resource manager and executor being used to reload data packs. -
String getApplyMessage()
- Used to print what changes tweakers have applied to the server console. Should have a number of things applied, similar to vanilla's count of recipes loaded. -
void prepareFor(ScriptBridge bridge)
- Used to prepare the tweaker for each individual script being run. Can be used to set namespaces for content added, or similar behavior. Defaulted to no-op. -
JsonObject getDebugInfo()
- Used to append debug information, such as the IDs of registered recipes or modified loot tables, to the debug file when/libcd debug export
is run.
There should only ever be one instance of a given tweaker registered at a time.
Assistants can be any object used to make writing scripts easier. There are two ways to register assistants: as a simple object or as a factory for objects. Factories are passed a ScriptBridge
, which contains metadata about the script requesting the assistant.
LibCD already contains and registers a tweaker class for adding recipes. Because of that, you don't need to register your own tweaker class if you just want to support adding recipes. All you need is an assistant class which can construct recipes and pass them to the RecipeTweaker.INSTANCE.addRecipe(Recipe<?> recipe)
method.
Tweaker scripts don't have full access to Mojang classes due to game obfuscation, so recipe-adding methods should only use strings, collections, primitives, and Object
s as parameters. LibCD provides methods to construct both vanilla Ingredient
s and ItemStack
s from Object
s, so they should be used for parsing inputs and outputs. As all recipes need unique identifiers, LibCD provides a method for generating the ID of the recipe based on the currently-running script, how many recipes have already been created, and the output stack of the recipe. It should be called as such.
RecipeParser
also contains utilities for processing 2D arrays and key/value dictionaries for shaped crafting recipes. Be aware that due to the use of Object
s, the method signatures for 2D arrays and key/value dictionaries may overload each other from a scripting environment, so they should have different names, like the built-in RecipeTweaker#addShaped
and RecipeTweaker#addDictShaped
methods.
There are some items, like potions, that work off a separate system for available items. Because of that, specifying that a minecraft:potion
item in a recipe means that someone can use any potion in it, not just a bottle of water. Because of that, the tweaker system adds a system for creating ingredients (or output stacks) of special stacks called TweakerStackFactory
s. New getters are registered through the TweakerManager#addStackFactory
method mentioned earlier, passing an Identifier for the getter and a lambda taking in another Identifier for the entry to return. To call the factoru, a user will use a string [getter id]->[entry id]
. To see an example of this, check LibCD's call of the method for registering a getter for potions. If a factory can't find an entry, it should return ItemStack.EMPTY
.