API Test Plugins
These are the test plugins used to validate the plugin API across supported Minecraft versions:
f19c7c7d-a-testing1-8-9bd1c3176-d-testing1-18-2d67dc19f-6-testing1-20-4a85f0152-0-testing1-21
Each plugin registers a render listener and an event listener. The render
listener exercises every RenderManager world and overlay drawing overload. The
event listener exercises packet callbacks and cancellable SyncEvent handling.
1.8.9 Forge
package com.example;
import com.originmint.managers.LoggingManager;import com.originmint.managers.PluginManager;import com.originmint.managers.RenderManager;import com.originmint.plugin.IPlugin;import com.originmint.plugin.settings.Boolean;import com.originmint.plugin.settings.Coords;import com.originmint.plugin.settings.FloatSlider;import net.minecraft.client.Minecraft;import net.minecraft.entity.Entity;import net.minecraft.entity.EntityLivingBase;
import java.util.ArrayList;import java.util.List;
public class Example implements IPlugin { final Boolean enabled = new Boolean("testing189.enabled", "Enabled", "Enable all plugin API tests", true); final Boolean drawWorld = new Boolean("testing189.draw_world", "Draw world", "Exercise all world render methods", true); final Boolean drawOverlay = new Boolean("testing189.draw_overlay", "Draw overlay", "Exercise all overlay render methods", true); final Boolean throughWalls = new Boolean("testing189.through_walls", "Through walls", "Draw world tests through walls", true); final Boolean cancelSyncEvents = new Boolean("testing189.cancel_sync", "Cancel sync PRE", "Cancel every SyncEvent during its PRE phase", false); final Coords anchor = new Coords("testing189.anchor", "Render anchor", "World coordinates used for render tests", 0, 64, 0); final FloatSlider lineWidth = new FloatSlider("testing189.line_width", "Line width", "Width used by line-based render tests", 0.5F, 8.0F, 2.0F);
private final RenderTestListener renderListener = new RenderTestListener(this); private final EventTestListener eventListener = new EventTestListener(this); private boolean registered;
@Override public void onEnable() { if (registered) { return; } eventListener.reset(); PluginManager.getInstance().PLUGIN_EVENT_BUS.register(renderListener); PluginManager.getInstance().PLUGIN_EVENT_BUS.register(eventListener); registered = true; log("enabled; waiting to log the first packet", LoggingManager.LOG_LEVEL.SUCCESS); }
@Override public void onDisable() { if (!registered) { return; } PluginManager.getInstance().PLUGIN_EVENT_BUS.unregister(eventListener); PluginManager.getInstance().PLUGIN_EVENT_BUS.unregister(renderListener); registered = false; log("disabled", LoggingManager.LOG_LEVEL.INFO); }
RenderManager render() { return RenderManager.getInstance(); }
List<Entity> livingEntities() { Minecraft minecraft = Minecraft.getMinecraft(); List<Entity> entities = new ArrayList<>(); if (minecraft == null || minecraft.theWorld == null) { return entities; } for (Entity entity : minecraft.theWorld.loadedEntityList) { if (entity != minecraft.thePlayer && entity instanceof EntityLivingBase) { entities.add(entity); } } return entities; }
void log(String message, LoggingManager.LOG_LEVEL level) { LoggingManager.getInstance().log("[Testing 1.8.9] " + message, level); }}1.18.2 Fabric
package com.example;
import com.originmint.managers.LoggingManager;import com.originmint.managers.PluginManager;import com.originmint.managers.RenderManager;import com.originmint.plugin.IPlugin;import com.originmint.plugin.settings.Boolean;import com.originmint.plugin.settings.Coords;import com.originmint.plugin.settings.FloatSlider;import net.minecraft.client.MinecraftClient;import net.minecraft.entity.Entity;import net.minecraft.entity.LivingEntity;
import java.util.ArrayList;import java.util.List;
public class Example implements IPlugin { final Boolean enabled = new Boolean("testing1182.enabled", "Enabled", "Enable all plugin API tests", true); final Boolean drawWorld = new Boolean("testing1182.draw_world", "Draw world", "Exercise all world render methods", true); final Boolean drawOverlay = new Boolean("testing1182.draw_overlay", "Draw overlay", "Exercise all overlay render methods", true); final Boolean throughWalls = new Boolean("testing1182.through_walls", "Through walls", "Draw world tests through walls", true); final Boolean cancelSyncEvents = new Boolean("testing1182.cancel_sync", "Cancel sync PRE", "Cancel every SyncEvent during its PRE phase", false); final Coords anchor = new Coords("testing1182.anchor", "Render anchor", "World coordinates used for render tests", 0, 64, 0); final FloatSlider lineWidth = new FloatSlider("testing1182.line_width", "Line width", "Width used by line-based render tests", 0.5F, 8.0F, 2.0F);
private final RenderTestListener renderListener = new RenderTestListener(this); private final EventTestListener eventListener = new EventTestListener(this); private boolean registered;
@Override public void onEnable() { if (registered) return; eventListener.reset(); PluginManager.getInstance().PLUGIN_EVENT_BUS.register(renderListener); PluginManager.getInstance().PLUGIN_EVENT_BUS.register(eventListener); registered = true; log("enabled; waiting to log the first packet", LoggingManager.LOG_LEVEL.SUCCESS); }
@Override public void onDisable() { if (!registered) return; PluginManager.getInstance().PLUGIN_EVENT_BUS.unregister(eventListener); PluginManager.getInstance().PLUGIN_EVENT_BUS.unregister(renderListener); registered = false; log("disabled", LoggingManager.LOG_LEVEL.INFO); }
RenderManager render() { return RenderManager.getInstance(); }
List<Entity> livingEntities() { MinecraftClient minecraft = MinecraftClient.getInstance(); List<Entity> entities = new ArrayList<>(); if (minecraft == null || minecraft.world == null) return entities; for (Entity entity : minecraft.world.getEntities()) { if (entity != minecraft.player && entity instanceof LivingEntity) { entities.add(entity); } } return entities; }
void log(String message, LoggingManager.LOG_LEVEL level) { LoggingManager.getInstance().log("[Testing 1.18.2] " + message, level); }}1.20.4 Fabric
package com.example;
import com.originmint.managers.LoggingManager;import com.originmint.managers.PluginManager;import com.originmint.managers.RenderManager;import com.originmint.plugin.IPlugin;import com.originmint.plugin.settings.Boolean;import com.originmint.plugin.settings.Coords;import com.originmint.plugin.settings.FloatSlider;import net.minecraft.client.MinecraftClient;import net.minecraft.entity.Entity;import net.minecraft.entity.LivingEntity;
import java.util.ArrayList;import java.util.List;
public class Example implements IPlugin { final Boolean enabled = new Boolean("testing1204.enabled", "Enabled", "Enable all plugin API tests", true); final Boolean drawWorld = new Boolean("testing1204.draw_world", "Draw world", "Exercise all world render methods", true); final Boolean drawOverlay = new Boolean("testing1204.draw_overlay", "Draw overlay", "Exercise all overlay render methods", true); final Boolean throughWalls = new Boolean("testing1204.through_walls", "Through walls", "Draw world tests through walls", true); final Boolean cancelSyncEvents = new Boolean("testing1204.cancel_sync", "Cancel sync PRE", "Cancel every SyncEvent during its PRE phase", false); final Coords anchor = new Coords("testing1204.anchor", "Render anchor", "World coordinates used for render tests", 0, 64, 0); final FloatSlider lineWidth = new FloatSlider("testing1204.line_width", "Line width", "Width used by line-based render tests", 0.5F, 8.0F, 2.0F);
private final RenderTestListener renderListener = new RenderTestListener(this); private final EventTestListener eventListener = new EventTestListener(this); private boolean registered;
@Override public void onEnable() { if (registered) return; eventListener.reset(); PluginManager.getInstance().PLUGIN_EVENT_BUS.register(renderListener); PluginManager.getInstance().PLUGIN_EVENT_BUS.register(eventListener); registered = true; log("enabled; waiting to log the first packet", LoggingManager.LOG_LEVEL.SUCCESS); }
@Override public void onDisable() { if (!registered) return; PluginManager.getInstance().PLUGIN_EVENT_BUS.unregister(eventListener); PluginManager.getInstance().PLUGIN_EVENT_BUS.unregister(renderListener); registered = false; log("disabled", LoggingManager.LOG_LEVEL.INFO); }
RenderManager render() { return RenderManager.getInstance(); }
List<Entity> livingEntities() { MinecraftClient minecraft = MinecraftClient.getInstance(); List<Entity> entities = new ArrayList<>(); if (minecraft == null || minecraft.world == null) return entities; for (Entity entity : minecraft.world.getEntities()) { if (entity != minecraft.player && entity instanceof LivingEntity) { entities.add(entity); } } return entities; }
void log(String message, LoggingManager.LOG_LEVEL level) { LoggingManager.getInstance().log("[Testing 1.20.4] " + message, level); }}1.21 Fabric
package com.example;
import com.originmint.managers.LoggingManager;import com.originmint.managers.PluginManager;import com.originmint.managers.RenderManager;import com.originmint.plugin.IPlugin;import com.originmint.plugin.settings.Boolean;import com.originmint.plugin.settings.Coords;import com.originmint.plugin.settings.FloatSlider;import net.minecraft.client.MinecraftClient;import net.minecraft.entity.Entity;import net.minecraft.entity.LivingEntity;
import java.util.ArrayList;import java.util.List;
public class Example implements IPlugin { final Boolean enabled = new Boolean("testing121.enabled", "Enabled", "Enable all plugin API tests", true); final Boolean drawWorld = new Boolean("testing121.draw_world", "Draw world", "Exercise all world render methods", true); final Boolean drawOverlay = new Boolean("testing121.draw_overlay", "Draw overlay", "Exercise all overlay render methods", true); final Boolean throughWalls = new Boolean("testing121.through_walls", "Through walls", "Draw world tests through walls", true); final Boolean cancelSyncEvents = new Boolean("testing121.cancel_sync", "Cancel sync PRE", "Cancel every SyncEvent during its PRE phase", false); final Coords anchor = new Coords("testing121.anchor", "Render anchor", "World coordinates used for render tests", 0, 64, 0); final FloatSlider lineWidth = new FloatSlider("testing121.line_width", "Line width", "Width used by line-based render tests", 0.5F, 8.0F, 2.0F);
private final RenderTestListener renderListener = new RenderTestListener(this); private final EventTestListener eventListener = new EventTestListener(this); private boolean registered;
@Override public void onEnable() { if (registered) return; eventListener.reset(); PluginManager.getInstance().PLUGIN_EVENT_BUS.register(renderListener); PluginManager.getInstance().PLUGIN_EVENT_BUS.register(eventListener); registered = true; log("enabled; waiting to log the first packet", LoggingManager.LOG_LEVEL.SUCCESS); }
@Override public void onDisable() { if (!registered) return; PluginManager.getInstance().PLUGIN_EVENT_BUS.unregister(eventListener); PluginManager.getInstance().PLUGIN_EVENT_BUS.unregister(renderListener); registered = false; log("disabled", LoggingManager.LOG_LEVEL.INFO); }
RenderManager render() { return RenderManager.getInstance(); }
List<Entity> livingEntities() { MinecraftClient minecraft = MinecraftClient.getInstance(); List<Entity> entities = new ArrayList<>(); if (minecraft == null || minecraft.world == null) return entities; for (Entity entity : minecraft.world.getEntities()) { if (entity != minecraft.player && entity instanceof LivingEntity) { entities.add(entity); } } return entities; }
void log(String message, LoggingManager.LOG_LEVEL level) { LoggingManager.getInstance().log("[Testing 1.21] " + message, level); }}26.2 Fabric
Identical in behaviour to the 1.21 plugin above; only the Minecraft-side names
differ. 26.2 ships unobfuscated, so it uses Mojang’s own names rather than
Yarn’s: MinecraftClient is Minecraft, world is level, and Entity moved
from net.minecraft.entity to net.minecraft.world.entity. ClientLevel also
has no public “every entity” accessor, so entitiesForRendering() stands in for
Yarn’s world.getEntities() — it walks the same set the renderer does.
package com.example;
import com.originmint.managers.LoggingManager;import com.originmint.managers.PluginManager;import com.originmint.managers.RenderManager;import com.originmint.plugin.IPlugin;import com.originmint.plugin.settings.Boolean;import com.originmint.plugin.settings.Coords;import com.originmint.plugin.settings.FloatSlider;import net.minecraft.client.Minecraft;import net.minecraft.world.entity.Entity;import net.minecraft.world.entity.LivingEntity;
import java.util.ArrayList;import java.util.List;
public class Example implements IPlugin { final Boolean enabled = new Boolean("testing262.enabled", "Enabled", "Enable all plugin API tests", true); final Boolean drawWorld = new Boolean("testing262.draw_world", "Draw world", "Exercise all world render methods", true); final Boolean drawOverlay = new Boolean("testing262.draw_overlay", "Draw overlay", "Exercise all overlay render methods", true); final Boolean throughWalls = new Boolean("testing262.through_walls", "Through walls", "Draw world tests through walls", true); final Boolean cancelSyncEvents = new Boolean("testing262.cancel_sync", "Cancel sync PRE", "Cancel every SyncEvent during its PRE phase", false); final Coords anchor = new Coords("testing262.anchor", "Render anchor", "World coordinates used for render tests", 0, 64, 0); final FloatSlider lineWidth = new FloatSlider("testing262.line_width", "Line width", "Width used by line-based render tests", 0.5F, 8.0F, 2.0F);
private final RenderTestListener renderListener = new RenderTestListener(this); private final EventTestListener eventListener = new EventTestListener(this); private boolean registered;
@Override public void onEnable() { if (registered) return; eventListener.reset(); PluginManager.getInstance().PLUGIN_EVENT_BUS.register(renderListener); PluginManager.getInstance().PLUGIN_EVENT_BUS.register(eventListener); registered = true; log("enabled; waiting to log the first packet", LoggingManager.LOG_LEVEL.SUCCESS); }
@Override public void onDisable() { if (!registered) return; PluginManager.getInstance().PLUGIN_EVENT_BUS.unregister(eventListener); PluginManager.getInstance().PLUGIN_EVENT_BUS.unregister(renderListener); registered = false; log("disabled", LoggingManager.LOG_LEVEL.INFO); }
RenderManager render() { return RenderManager.getInstance(); }
List<Entity> livingEntities() { Minecraft minecraft = Minecraft.getInstance(); List<Entity> entities = new ArrayList<>(); if (minecraft == null || minecraft.level == null) return entities; for (Entity entity : minecraft.level.entitiesForRendering()) { if (entity != minecraft.player && entity instanceof LivingEntity) { entities.add(entity); } } return entities; }
void log(String message, LoggingManager.LOG_LEVEL level) { LoggingManager.getInstance().log("[Testing 26.2] " + message, level); }}Render listener
Use the same RenderTestListener.java in every version folder. The entity import is
net.minecraft.entity.Entity on 1.8.9, 1.18.2, 1.20.4 and 1.21, and
net.minecraft.world.entity.Entity on 26.2.
package com.example;
import com.originmint.managers.RenderManager;import com.originmint.plugin.eventbus.Subscribe;import com.originmint.plugin.events.RenderTickEvent;import net.minecraft.entity.Entity;
final class RenderTestListener { private final Example owner;
RenderTestListener(Example owner) { this.owner = owner; }
@Subscribe public void onRender(RenderTickEvent event) { if (!owner.enabled.value) return; if (event.type == RenderTickEvent.Type.WORLD && owner.drawWorld.value) { drawWorld(); } else if (event.type == RenderTickEvent.Type.OVERLAY && owner.drawOverlay.value) { drawOverlay(event); } }
private void drawWorld() { RenderManager render = owner.render(); double x = owner.anchor.x; double y = owner.anchor.y; double z = owner.anchor.z; float width = owner.lineWidth.value; boolean walls = owner.throughWalls.value;
render.drawBlockBox(x, y, z, 0xFFFF4040); render.drawBlockBox(x + 2, y, z, 0xFF40FF40, width, walls); render.drawBlockBox(x + 4, y, z, 0.2F, 0.5F, 1.0F, 1.0F); render.drawBlockBox(x + 6, y, z, 1.0F, 0.3F, 1.0F, 1.0F, width, walls);
render.drawWorldBox(x, y + 2, z, x + 2, y + 3, z + 2, 1.0F, 0.8F, 0.1F, 1.0F, width, walls); render.drawWorldLine(x, y + 1, z, x + 8, y + 4, z, 0.1F, 1.0F, 1.0F, 1.0F, width, walls);
render.drawWorldNameTag(x, y + 5, z, "RGBA name tag", "default size", 1.0F, 1.0F, 1.0F, 1.0F, walls, true); render.drawWorldNameTag(x + 2, y + 5, z, "RGBA name tag", "custom size", 1.0F, 0.6F, 0.2F, 1.0F, walls, false, 1.5F); render.drawWorldNameTag(x + 4, y + 5, z, "ARGB name tag", "default size", 0xFF66CCFF, walls, true); render.drawWorldNameTag(x + 6, y + 5, z, "ARGB name tag", "custom size", 0xFFFF66CC, walls, false, 1.5F);
for (Entity entity : owner.livingEntities()) { drawEntityEsp(entity, render, width, walls); } }
private void drawEntityEsp(Entity entity, RenderManager render, float width, boolean walls) { if (entity == null) return; render.drawEntityBox(entity, 0x80FF0000, width, walls); render.drawTracerLine(entity, 0x80FF00FF, width, walls); }
private void drawOverlay(RenderTickEvent event) { RenderManager render = owner.render(); float width = owner.lineWidth.value; int screenWidth = render.getOverlayWidth(); int screenHeight = render.getOverlayHeight();
render.drawOverlayFilledRect(12, 12, 280, 82, 0.0F, 0.0F, 0.0F, 0.65F); render.drawOverlayRect(12, 12, 280, 82, 0.2F, 1.0F, 0.4F, 1.0F, width); render.drawOverlayLine(12, 94, 292, 12, 1.0F, 0.25F, 0.25F, 1.0F, width); render.drawOverlayText(20, 20, "Render API " + screenWidth + "x" + screenHeight, 1.0F, 1.0F, 1.0F, 1.0F, 16); render.drawOverlayText(20, 44, matrixState(event), 0.75F, 0.85F, 1.0F, 1.0F, 14); render.drawOverlayText(20, 66, "Every RenderManager overload is active", 0.7F, 1.0F, 0.7F, 1.0F, 14); }
private String matrixState(RenderTickEvent event) { return "modelView=" + (event.modelViewMatrix != null) + " projection=" + (event.projectionMatrix != null); }}Event listener
Use the same event listener body for every version. The packet import is:
net.minecraft.network.Packetfor1.8.9and1.18.2net.minecraft.network.packet.Packetfor1.20.4and1.21net.minecraft.network.protocol.Packetfor26.2(Mojang names, not Yarn)
package com.example;
import com.originmint.managers.LoggingManager;import com.originmint.plugin.eventbus.Subscribe;import com.originmint.plugin.events.PacketCallback;import com.originmint.plugin.events.SyncEvent;import net.minecraft.network.Packet;
final class EventTestListener { private final Example owner; private boolean packetLogged;
EventTestListener(Example owner) { this.owner = owner; }
void reset() { packetLogged = false; }
@Subscribe public void onPacket(Packet<?> packet, PacketCallback callback) { if (!owner.enabled.value || packetLogged) return; packetLogged = true; owner.log("first packet=" + packet.getClass().getName() + "; packet logging is now stopped", LoggingManager.LOG_LEVEL.INFO); }
@Subscribe public void onSync(SyncEvent event) { if (!owner.enabled.value) return; if (owner.cancelSyncEvents.value && event.phase == SyncEvent.Phase.PRE) { event.cancelEvent(); } int dataCount = event.data == null ? 0 : event.data.length; owner.log( "sync phase=" + event.phase + " type=" + event.type + " dataCount=" + dataCount + " cancelled=" + event.isCancelled(), event.isCancelled() ? LoggingManager.LOG_LEVEL.WARNING : LoggingManager.LOG_LEVEL.INFO ); }}