The EaglerForge ModAPI is housed in a global JavaScript object stored on globalThis
, called ModAPI
or PluginAPI
. (both are identical)
From people used to the doc prior to EaglerForgeInjector, now, when you see something like ModAPI.world
’s type is World
, that literally means it is identical to an instance of net.minecraft.world.World
from java. For easier modding, here are some online javadocs, that explain properties from each individual method and proerty of every 1.8 class:
https://nurmarvin.github.io/Minecraft-1.8-JavaDocs/overview-summary.html - Javadoc for vanilla 1.8 https://eaglerreborn.github.io/javadoc/ - EaglerReborn (EF precursor) javadoc, for EaglercraftX u17 (missing serverside classes, this version didn’t have singleplayer) An up-to-date javadoc for EaglercraftX is coming soon, in the meanwhile, I recommend modding with a local EaglercraftX workspace, so you can inspect the contents of each class.
Additionally, when you se that something like ModAPI.mcinstance
is Raw<Minecraft>
this means that it has a lot of TeaVM nonsense like ‘$’ prefixes before everything, as well has making it difficult to call the objects methods.
The global object has the following properties:
ModAPI.player: EntityPlayerSP
ModAPI.require("player")
is called, this is the local player entity. It is regenerated every time the update
event is called.ModAPI.world: WorldClient
ModAPI.require("world")
is called, this is the client-side world. It is regenerated every time the update
event is called.ModAPI.network: NetHandlerPlayClient
ModAPI.require("network")
is called, this is the client’s networking handler. It is regenerated every time the update
event is called.ModAPI.settings: GameSettings
ModAPI.items: Map<String, Item>
Items
class.acacia_door
, you can use ModAPI.items["acacia_door"]
ModAPI.blocks: Map<String, Block>
Blocks
class.bedrock
, you can use ModAPI.blocks["bedrock"]
ModAPI.materials: Map<String, Material>
Material
class.portal
, you can use ModAPI.materials["portal"]
ModAPI.enchantments: Map<String, Enchantment|Object>
Enchantment
class.knockback
, you can use ModAPI.enchantments["knockback"]
Object.keys
will also return non-enchantment keys such as enchantmentsBookList
.ModAPI.minecraft: Minecraft
ModAPI.mc
ModAPI.mcinstance: Raw<Minecraft>
ModAPI.javaClient
ModAPI.minecraft.getRef()
Minecraft
ModAPI.server: MinecraftServer
serverstart
.ModAPI.dedicatedServer
)ModAPI.serverInstance
ModAPI.rawServer: MinecraftServer
serverstart
event is fired.ModAPI.dedicatedServer
)ModAPI.server.getRef()
ModAPI.hooks
ModAPI.util
ModAPI.hooks
, ModAPI.reflect
, and more.ModAPI.reflect
ModAPI.hooks
, ModAPI.hooks._teavm
and ModAPI.hooks._classMap
that makes accessing and using internal java classes in mods much easier.ModAPI.dedicatedServer
ModAPI.meta
ModAPI.array
ModAPI.keygen
ModAPI.resolution
frame
event is fired.ModAPI.ScaledResolution
ModAPI.version: String
ModAPI.flavour: String
"injector"
.The ModAPI object has the following methods:
addEventListener(eventName: String, callback: Function) : void
require(componentName: String) : void
player
and network
.ModAPI.require("module")
displayToChat(message: String) : void
ModAPI.displayToChat("Hello World.")
clickMouse() : void
rightClickMouse() : void
getFPS() : int
promisify(asyncJavaMethod: Method | Constructor) : PromisifiedJavaRunner
Java strings and JavaScript strings are not the same. Calling a method like this: ModAPI.player.sendChatMessage("hello world")
, will not work, as you are running a Java method with a JavaScript string. To convert a JS string to a Java string, use ModAPI.util.str(yourString)
. For example, the correct version of the above example is ModAPI.player.sendChatMessage(ModAPI.util.str("hello world"))
. This problem is automatically mitigated on a few functions, namely ModAPI.displayToChat()
.
Java numbers and JavaScript numbers are stored the same way, with no problems with having to cast, like with strings. This is why you can simply do something like ModAPI.player.motionY = 99999
, without having to do any conversion.
Booleans in Java are stored as a number, where 1
means true
and 0
means false
. There are no functions for converting inbetween these, because it is very easy to do so (unlike strings). To convert a javascript boolean into a java boolean simply multiply you boolean by 1.
Eg:
var myBool = true;
console.log(myBool * 1);
// logs '1'
var myBool = false;
console.log(myBool * 1);
// logs '0'
Better yet, if you need to use booleans very often, just store them as numbers directly in javascript. JavaScript if statements already recognise 0
as false, so something like:
var condition = 0;
if (condition) {
console.log("yes");
} else {
console.log("no");
}
// outputs 'no'
will work out of the box.
In ModAPI’s architecture, when you request an object like ModAPI.player
, instead of giving you ModAPI.mcinstance.$thePlayer
, it will return a TeaVM_to_Recursive_BaseData_ProxyConf
proxy. These automatically remove the $
prefixes, make instance methods run with the actaul object, and a variety other features.
However, when calling methods via ModAPI.hooks
, ModAPI.reflect
, or even just running a method that takes in object arguments on something like ModAPI.player
, passing in these ModAPI proxies will cause an error.
To pass in raw java data simply call getRef()
on the proxy which will return the raw, unmodified version of it.
For example, take the method setRenderViewEntity()
on ModAPI.mcinstance
. Instead of passing an entity from ModAPI.world.loadedEntityList.get(index)
directly, you need to use ModAPI.world.loadedEntityList.get(index).getRef()
. Demo code:
var entityIndex = 1; //Index of the entity to look for. 0 means first, which is usually the player, so 1 is usually a natural entity.
ModAPI.mc.setRenderViewEntity(ModAPI.world.loadedEntityList.get(entityIndex).getRef());
By default, accessing a global like ModAPI.player
will return a proxy to the original player that removes $ prefixes, as well as making instance methods callable. TeaVM has a quirk where it adds numerical suffixes to some properties. For example ModAPI.player.inGround0
instead of ModAPI.player.inGround
. As this is a large issue due to these suffixes changing for every eaglercraft update, you can now bypass this by obtaining a corrective version of ModAPI.player
, using ModAPI.player.getCorrective()
.
For example:
ModAPI.player.inGround //returns undefined
ModAPI.player.inGround0 //returns 1 or 0, the correct value
ModAPI.player.isCorrective() //returns false
var correctedPlayer = ModAPI.player.getCorrective();
correctedPlayer.inGround //returns 1 or 0, the correct value
correctedPlayer.inGround0 //returns 1 or 0, the correct value
correctedPlayer.isCorrective() //returns true
You can check if an object is corrective using <object>.isCorrective()
;
Accessing children of a corrective object will also make them corrective. correctedPlayer.fishEntity.isCorrective(); //true