Annotations
The compiler supports a number of annotations. Their main purpose is to add/modify functionality in existing game functions and classes.

@wrapMethod(class)

This annotation needs to be followed by a function definition with a signature matching some existing in-game method. Your function will effectively 'wrap' the existing method on the specified class, i.e. whenever the original method is invoked your function will be executed instead - but it's your function's responsibility to invoke the method being wrapped and you can do it by using the special wrappedMethod identifier. You can invoke it by forwarding the original arguments or change them however you wish. On top of that, this annotation allows chaining of these wrappers and incrementally adding functionality to existing methods. This makes it pretty easy to keep mods compatible even when they modify the same methods.
1
@wrapMethod(SingleplayerMenuGameController)
2
private func PopulateMenuItemList() {
3
wrappedMethod(); // this will call the original PopulateMenuItemList
4
this.AddMenuItem("BUTTON 1", n"OnDebug");
5
}
6
​
7
// you can chain them - this function will wrap around the previous wrapper
8
@wrapMethod(SingleplayerMenuGameController)
9
private func PopulateMenuItemList() {
10
wrappedMethod(); // this will call the previous wrapper
11
this.AddMenuItem("BUTTON 2", n"OnDebug");
12
}
13
​
14
// we'll end up with BUTTON 1 and BUTTON 2 added to the main menu
Copied!

@addMethod(class)

This annotation will add your newly defined method to the specified class.
1
@addMethod(BackpackMainGameController)
2
private final func DisassembleAllJunkItems() {
3
...
Copied!

@replaceMethod(class)

This annotation needs to be followed by a function definition with a signature matching some existing in-game method. Your function will effectively replace the existing method.
1
@replaceMethod(CraftingSystem)
2
private final func ProcessCraftSkill(xpAmount: Int32, craftedItem: StatsObjectID) {
3
...
Copied!
If there is more than one @replaceMethod defined for a single method it will lead to only one of them taking effect. If you want to be able to combine multiple modifications you should check the @wrapMethod annotation.
This annotation is compatible with @wrapMethod. It will always replace the original method and it does not affect the wrappers.

@replaceGlobal()

This annotation needs to be followed by a function definition with a signature matching some existing in-game global function. The matching function will be replaced with yours.
1
@replaceGlobal()
2
public static func CreateExpEvent(amount: Int32, type: gamedataProficiencyType) -> ref<ExperiencePointsEvent>
3
...
Copied!
This is known not to work for some native functions.

@addField(class)

This annotation needs to be followed by a field definition that will be added to the target class.
1
@addField(PlayerPuppet)
2
let dummy: Int32;
Copied!
Last modified 1mo ago