Writing a script
Now that you have set up your environment, you can proceed onto writing transformer scripts.
Koremods DSL
Defining transformers
Transformers can be added inside the transformers
scoped function that provides a TransformerBuilder
.
From there, you can use the provided methods to define transformers for classes, methods and fields.
Each of them takes in a number of strings necessary to locate the target,
and a consumer function that acceptsthe respective ASM node type.
Example usage:
transformers {
// Transform ClassNode
`class`("com.example.Example", ::transformExample)
// Transform MethodNode
method(
"com.example.Example", // Class name
"sayHello", // Method name
constructMethodDescriptor(void, "java/lang/String"), // Method descriptor
::transformSayHello // Transformer function
)
// Transform FieldNode
field(
"com.example.Example", // Class name
"foo", // Field name
"java/lang/String", // Field type
::transformFoo // Transformer function
)
}
Bytecode API
Koremods bundles Koffee, an ASM wrapper written in Kotlin.
Koffee provides a bytecode assembly DSL where
instructions are represented by Kotlin properties, as well as syntax sugar for common code,
such as init
, clinit
, object construction etc.
Koremods extends Koffee's API to provide functions for transforming nodes, injecting instructions and locating bytecode sequences.
See the Koremods Script KDocs for parameters and details.
Remapping API
Koremods Modlauncher extends the Koremods DSL with a remapping API that can be used to map class, method and field names to the running environment's mappings.
In a MinecraftForge environment, the supplied arguments should be in mojang_srg
format.
Remapping classes isn't needed as they're already mapped to SRG during setup.
You can easily get the desired mojang_srg
names to use with the remapping api from
Linkie or other available tools.
Example usage:
mapClassName("net.minecraft.server.level.ServerLevel")
mapMethodName("m_109089_") // renderLevel
mapFieldName("f_8329_") // level
Script Features
Sandbox
Koremods scripts are executed in an isolated environment to ensure they can only access necessary classes and resources. This helps improve security and makes them less prone to bugs.
The following classes and packages are available for use in koremods scripts:
- Java standard library
java.lang
java.util
- Kotlin
kotlin
- ASM
org.objectweb.asm
- Log4J
org.apache.logging.log4j
- Koffee
codes.som.koffee
- Koremods
wtf.gofancy.koremods.Identifier
wtf.gofancy.koremods.script.KoremodsKtsScript
wtf.gofancy.script.ImportScript
wtf.gofancy.koremods.dsl
Attempting to load unavailable classes will result in a ClassNotAvailableInSandboxException
.
Importing Scrips
You can import members of other scripts into your script using the @ImportScript
annotation on the file,
and supplying it with paths relative to the current directory.
An IDE restart may be required after modifying imported scrips to fully enable autocompletion features.
For example:
Importing a script called bar.core.kts
, which is in the same directory and contains the function greet
:
@file:ImportScript("bar.core.kts")
greet("World")
Live Debugging
Thanks to IntelliJ Idea's Kotlin Script integration, you can place breakpoints into scripts directly and debug them during runtime. No additional setup is required. This applies to pre-compiled scripts and remote debugging as well.
FML mod dependency
Starting with version 0.4.7, Koremods Modlauncher registers a FML mod with the modid koremods
.
You can make your mod depend on it to ensure users have the right Koremods version installed and help reduce errors.
Example usage:
[[dependencies.examplemod]]
# the modid of the dependency
modId="koremods"
# Does this dependency have to exist - if not, ordering below must be specified
mandatory=true
# The version range of the dependency
versionRange="[0.4.8,)"
# # An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatatory
ordering="NONE"
# Side this dependency is applied on - BOTH, CLIENT or SERVER
side="BOTH"