Minecraft 1.21.5 + Fabric 0.16.10で座標・方角・明るさ・バイオーム名・スニーク状態を画面左上に表示するだけのModを作る

マインクラフト Java版のクライアントサイドのみで動作するModの最小構成。

■VSCode (Visual Studio Code)を使う場合 1)JDKをインストール  Eclipse Adoptium (旧AdoptOpenJDK)  https://adoptium.net/temurin/releases/?os=windows&arch=x64&package=jdk   ※21 (LTS: Long Term Support = 長期サポート版)を選ぶ   ※環境変数「JAVA_HOME」は設定しない 2)拡張機能「Extension for Java」をインストール 3)設定(settings.json)に記述を追加してJDKが使えるようにする
    "java.jdt.ls.java.home": "C:\\Users\\[User Name]\\AppData\\Local\\Programs\\Eclipse Adoptium\\jdk-21.0.6.7-hotspot\\",
    "java.configuration.runtimes": [
        {
            "name": "JavaSE-21",
            "path": "C:\\Users\\[User Name]\\AppData\\Local\\Programs\\Eclipse Adoptium\\jdk-21.0.6.7-hotspot\\",
            "default": true
          },
    ],
    "java.import.gradle.java.home": "C:\\Users\\[User Name]\\AppData\\Local\\Programs\\Eclipse Adoptium\\jdk-21.0.6.7-hotspot\\"
4)Fabricのテンプレートをダウンロード  https://fabricmc.net/develop/ の「Online Template Mod Generator」を使い自分専用のプロジェクトファイルを作成する。 5)ダウンロードしたzipファイルを展開しプロジェクトのディレクトリをVSCodeで開く 6)テンプレートの書き換え  下記2つのファイル内のMinecraftとFabricのバージョンを実行対象のものに書き換える。  .\gradle.properties  .\src\main\resources\fabric.mod.json 7)コードを書き加えた後「Gradle」からbuildする  .\libs にjarファイルが生成される。 ■Javaのコード  Mod Name: simpleinfo  Package Name: fuzzypain.minecraft.simpleinfo の場合  ※MinecraftとFabricはバージョンによって実装方法が変わる場合があるので対象バージョン毎にコードの書き方を調べたり実験したりする必要がある。
package fuzzypain.minecraft.simpleinfo;

import java.util.ArrayList;
import java.util.Optional;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.rendering.v1.HudLayerRegistrationCallback;
import net.fabricmc.fabric.api.client.rendering.v1.IdentifiedLayer;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.render.RenderTickCounter;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.registry.RegistryKey;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.LightType;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;

public class SimpleInfoClient implements ClientModInitializer {
    public static final String MOD_ID = "simpleinfo";

    private static final Identifier SIMPLE_INFO_LAYER =
        Identifier.of(SimpleInfoClient.MOD_ID, "simple-info-layer");
    
    @Override
    public void onInitializeClient() {
        HudLayerRegistrationCallback.EVENT.register(
            layeredDrawer -> layeredDrawer.attachLayerBefore(
                IdentifiedLayer.DEBUG,
                SIMPLE_INFO_LAYER,
                SimpleInfoClient::render));
    }

    private static void render(
        DrawContext context,
        RenderTickCounter tickCounter
    ) {
        MinecraftClient client = MinecraftClient.getInstance();
        if(client.getDebugHud().shouldShowDebugHud() || client.options.hudHidden)
            return;

        PlayerEntity player = client.player;
        if(player == null) return;

        World world = player.getWorld();
        if(world == null) return;


        ArrayList<String> textlines = new ArrayList<>();
        textlines.add(getCoordinateText(client, player));
        textlines.add(getLightLevelText(world, player));
        textlines.add(getBiomeText(world, player));
        textlines.add(player.isSneaking() ? "<< Sneaking >>" : "");

        drawData(context, client, textlines);
    }

    private static String getCoordinateText(
        MinecraftClient client,
        PlayerEntity player
    ) {
        Vec3d player_pos = player.getPos();
        Direction direcion = player.getHorizontalFacing();

        return String.format(
            "XYZ: %.2f / %.2f / %.2f  %s",
            player_pos.x, player_pos.y, player_pos.z,
            direcion);
    }

    private static String getLightLevelText(
        World world,
        PlayerEntity player
    ) {
        BlockPos block_pos = player.getBlockPos();
        int block_light = world.getLightLevel(LightType.BLOCK, block_pos);

        return String.format(
            "Block Light: %d",
            block_light);
    }

    private static String getBiomeText(
        World world,
        PlayerEntity player
    ) {
        Optional<RegistryKey<Biome>> biome =
            world.getBiome(player.getBlockPos()).getKey();
        Identifier biome_id = biome.get().getValue();
        String biome_name = Text.translatable(String.format(
            "biome.%s.%s",
            biome_id.getNamespace(), biome_id.getPath())).getString();

        return String.format(
            "%s %s : %s",
            biome_id.getNamespace(), biome_id.getPath(), biome_name);
    }

    private static void drawData(
        DrawContext context,
        MinecraftClient client,
        ArrayList<String> textlines
    ) {
        TextRenderer textRenderer = client.textRenderer;
        int textHeight = textRenderer.fontHeight;

        int x = 2;
        int y = 2;
        for(int i=0; i<textlines.size(); i++) {
            context.drawText(
                client.textRenderer,
                textlines.get(i),
                x, y + i * (textHeight + 2),
                0xFFFFFFFF,
                true);
        }
    }
}
■Modファイル
simpleinfo-0.1.1-fabric-0.16.10+mc1.21.5.jar