Mixin Library
The following functions are provided to scripts via the mixin global.
DANGER
Mixins are a very complicated topic that's very hard to grasp without a decent understanding of the JVM. If you would like to learn more about them, check out:
DOUBLE DANGER
Due to a limitation in how mixins are applied, if another mod chooses to apply mixins during the preLaunch phase, all Allium script mixins will NOT apply. If a script mixin appears to not be applying properly, this might be why.
WARNING
This page is under construction
Functions
mixin.to(targetClass, interfaces, targetEnvironment, duck)
Mix into a specified class.
Parameters
targetClass-string: The target class name, like what would be passed torequire().interfaces-table<string>?: Optional interfaces to apply to the target class, using therequire()format.targetEnvironment-string?: The target environment, one of"client"or"server". Leavenilto apply to common code.duck-boolean?: Whether to make this mixin a duck interface builder.
WARNING
Unlike standard class building, class names are passed as strings. This is because:
- mixins must not load the class they're mixing into, otherwise the application of the mixin will fail.
- mixins are registered before the game properly launches (
mixinAllium entrypoint,preLaunchFabric entrypoint). In this pre-launch environment it is best practice to not load any game classes.
Returns
userdata [instance]- Ifduckis false, a Mixin Class Builder. Ifduckis true, a Mixin Interface Builder.
Usage
See Class Building - Mixin Class Builder & Class Building - Mixin Interface Builder.
mixin.get(mixinId)
Get a reference to a mixin class with the given mixinId. This function can (and should) be used in the main script entrypoint.
Parameters
mixinId-string: The mixin ID of the class created in themixinentrypoint.
Returns
userdata [instance]: A hook definition for the class. See Hook Definition
Usage
Assuming there exists an injection with the ID "increase_cactus_height":
local methodHook = mixin.get("increase_cactus_height")mixin.quack(mixinId)
Provides the duck interface associated to a given ID. Used to access the accessors and invokers on objects belonging to the duck interface's target class.
Parameters
mixinId-string: The ID of a duck interface mixin.
Returns
userdata [class]: The mixin interface.
Usage
Provided the class:
package com.example;
import java.lang.String;
public class Dummy {
private final String foobar;
public Dummy(String foobar) {
this.foobar = foobar + (int)(Math.random()*100);
}
private void bat(boolean baz) {
// ...
}
}and the following mixin to access the private field foobar:
local builder = mixin.to("com.example.Dummy")
builder:getAccessor({ "foobar" })
builder:invoker({ "bat(Z)V" })
builder:build("foobar_interface")we use mixin.quack() to access the duck interface:
local Dummy = require("com.example.Dummy")
local AccessExample = mixin.quack("foobar_interface")
local dummy = Dummy("asd")
local accessibleDummy = java.cast(dummy, AccessExample)
local foobar = accessibleDummy:getFoobar()
accessibleDummy:invokeBat(false)Hook Definition
Because of the restrictions of the mixin entrypoint, the Lua functions that are to be put into the injectors on a mixin class have to be hooked in from the main entrypoint. The hook definition is how this is done. It has a single function:
hookDefinition:define(definition, destroyOnUnload)
Hooks the given methods into the injectors with matching indexes on the represented mixin class.
Parameters
definition-table<function>: A table with methods whose names match the indexes provided when creating the method builder. Parameters passed into these functions depend on the injector. If the injection does not target a static method, the first parameter passed to the function isthis, followed by the remaining parameters specified by the injection annotation and sugar parameter annotations.destroyOnUnload-boolean?: Whether or not to remove the hook definition from the mixin class on unload (or reload.)
TIP
It can be hard to visualize where a mixin should be made and what parameters it will provide. Scaffolding out the mixin in java first, where linting and auto-fill can help guide to the correct results, is a good idea.
HELP WANTED
It would be nice to be able to auto-fill in the parameters using the mixin annotation information right in the Lua file itself. If you have extension development experience in any IDE, and have an interest in contributing to an IDE extension for Allium, join the Discord linked in the top right!
Usage
TODO: A better example
local definition = {}
function definition:anInjectorMethod()
print(self:meaningOfLife())
end
methodHook:define(definition)