Getting Started¶
Setup¶
In your build.gradle
:
repositories {
maven {
url "https://www.cursemaven.com"
content {
includeGroup "curse.maven"
}
}
}
dependencies {
// Visit https://www.curseforge.com/minecraft/mc-mods/jade/files/all?filter-status=1&filter-game-version=2020709689%3A7498
// to get the latest version's jade_id
implementation fg.deobf("curse.maven:jade-324717:${jade_id}")
}
Visit CurseMaven to find more information about how to set up your workspace.
Registering¶
package mcp.mobius.waila.test;
import mcp.mobius.waila.api.IWailaClientRegistration;
import mcp.mobius.waila.api.IWailaCommonRegistration;
import mcp.mobius.waila.api.IWailaPlugin;
import mcp.mobius.waila.api.WailaPlugin;
@WailaPlugin
public class ExamplePlugin implements IWailaPlugin {
@Override
public void register(IWailaCommonRegistration registration) {
//TODO register data providers and config options here
}
@Override
public void registerClient(IWailaClientRegistration registration) {
//TODO register component providers and icon providers here
}
}
Component Provider¶
Component providers can append information (texts or images) to the tooltip.
Let's create a simple block component provider that adds an extra line to all the furnaces:
package mcp.mobius.waila.test;
import mcp.mobius.waila.api.BlockAccessor;
import mcp.mobius.waila.api.IComponentProvider;
import mcp.mobius.waila.api.ITooltip;
import mcp.mobius.waila.api.config.IPluginConfig;
import net.minecraft.network.chat.TranslatableComponent;
public enum ExampleComponentProvider implements IComponentProvider {
INSTANCE;
@Override
public void appendTooltip(ITooltip tooltip, BlockAccessor accessor, IPluginConfig config) {
tooltip.add(new TranslatableComponent("mymod.fuel"));
}
}
Here you have the tooltip
that you can do many various operations to the tooltip. You can take the tooltip
as a list of Component
. But here our elements are IElement
s, to support displaying images, not just texts. In this case we only added a single line.
You also have the accessor
, which you can get access to the context. We will use it later.
Then register our ExampleComponentProvider
:
package mcp.mobius.waila.test;
import mcp.mobius.waila.api.IWailaClientRegistration;
import mcp.mobius.waila.api.IWailaCommonRegistration;
import mcp.mobius.waila.api.IWailaPlugin;
import mcp.mobius.waila.api.TooltipPosition;
import mcp.mobius.waila.api.WailaPlugin;
import net.minecraft.world.level.block.AbstractFurnaceBlock;
@WailaPlugin
public class ExamplePlugin implements IWailaPlugin {
@Override
public void register(IWailaCommonRegistration registration) {
//TODO register data providers and config options here
}
@Override
public void registerClient(IWailaClientRegistration registration) {
registration.registerComponentProvider(ExampleComponentProvider.INSTANCE, TooltipPosition.BODY, AbstractFurnaceBlock.class);
}
}
Here the TooltipPosition.BODY
means we will append our text between the block name and the mod name.
AbstractFurnaceBlock.class
means we will append our text only when the block is extended from AbstractFurnaceBlock
.
Now launch the game:
Congrats you have implemented your first Jade plugin!
Server Data Provider¶
IServerDataProvider
can help you sync data that is not on client side. In this tutorial it is the remaining burn time of the furnace. It will sync to the client every 250 milliseconds.
This is a chart shows the basic lifecycle:
Now it's time to implement our IServerDataProvider
:
package mcp.mobius.waila.test;
import mcp.mobius.waila.api.BlockAccessor;
import mcp.mobius.waila.api.IComponentProvider;
import mcp.mobius.waila.api.IServerDataProvider;
import mcp.mobius.waila.api.ITooltip;
import mcp.mobius.waila.api.config.IPluginConfig;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity;
import net.minecraft.world.level.block.entity.BlockEntity;
public enum ExampleComponentProvider implements IComponentProvider, IServerDataProvider<BlockEntity> {
INSTANCE;
@Override
public void appendTooltip(ITooltip tooltip, BlockAccessor accessor, IPluginConfig config) {
if (accessor.getServerData().contains("Fuel")) {
tooltip.add(new TranslatableComponent("mymod.fuel", accessor.getServerData().getInt("Fuel")));
}
}
@Override
public void appendServerData(CompoundTag data, ServerPlayer player, Level world, BlockEntity t, boolean showDetails) {
AbstractFurnaceBlockEntity furnace = (AbstractFurnaceBlockEntity) t;
data.putInt("Fuel", furnace.litTime);
}
}
Here we used Access Transformer or Access Wideners to get access to the protected field.
Register IServerDataProvider
:
package mcp.mobius.waila.test;
import mcp.mobius.waila.api.IWailaClientRegistration;
import mcp.mobius.waila.api.IWailaCommonRegistration;
import mcp.mobius.waila.api.IWailaPlugin;
import mcp.mobius.waila.api.TooltipPosition;
import mcp.mobius.waila.api.WailaPlugin;
import net.minecraft.world.level.block.AbstractFurnaceBlock;
import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity;
@WailaPlugin
public class ExamplePlugin implements IWailaPlugin {
@Override
public void register(IWailaCommonRegistration registration) {
registration.registerBlockDataProvider(ExampleComponentProvider.INSTANCE, AbstractFurnaceBlockEntity.class);
}
@Override
public void registerClient(IWailaClientRegistration registration) {
registration.registerComponentProvider(ExampleComponentProvider.INSTANCE, TooltipPosition.BODY, AbstractFurnaceBlock.class);
}
}
Don't forget to add translation:
{
"mymod.fuel": "Fuel: %d ticks"
}
Great!
Showing an Item¶
Now let's show a clock as a small icon:
@Override
public void appendTooltip(ITooltip tooltip, BlockAccessor accessor, IPluginConfig config) {
if (accessor.getServerData().contains("Fuel")) {
IElementHelper elements = tooltip.getElementHelper();
IElement icon = elements.item(new ItemStack(Items.CLOCK), 0.5f);
tooltip.add(icon);
tooltip.append(new TranslatableComponent("mymod.fuel", accessor.getServerData().getInt("Fuel")));
}
}
Result:
Hmmm, would be better if we do some fine-tuning:
@Override
public void appendTooltip(ITooltip tooltip, BlockAccessor accessor, IPluginConfig config) {
if (accessor.getServerData().contains("Fuel")) {
IElementHelper elements = tooltip.getElementHelper();
IElement icon = elements.item(new ItemStack(Items.CLOCK), 0.5f).size(new Vec2(10, 10)).translate(new Vec2(0, -1));
tooltip.add(icon);
tooltip.append(new TranslatableComponent("mymod.fuel", accessor.getServerData().getInt("Fuel")));
}
}
Result:
Much better now!