これまで Minecraft / Fabric のバージョンは 1.21.xx みたいな表記でしたが、今年になって突然26.xx.xx のような表記になりました。
昨年までは 1.xx だったので、2~25までを短期間に続々リリースしたとは考え難く、調べてみたところ1.21の次を26にするということのようです。
あの悪名高いWindowsでも8の次に9ではなく10にする程度でしたが、まさか Minecraft で1の次が26になるとは思わなかったです。百歩譲って1.21の次を1.26にするならまだ(Windowsよりもひどいとはいえ)まだ分からなくはなかったですが。
さて、そのMinecraft / Fabric 26ですが、誰でも分かる大きな違いとしてはJavaのバージョンが26以上を必須としていることです。Java 25はLTS,長期安定版と呼ばれていますが、これが全く安定しておらず、26を要求される点に注意です。
さらに、clientで以前使えたはずの命令が使えなくなっており、エラーが出る場合と、エラーこそ出ないが無効で何も起こらない場合があります。Forgeよりはましかもしれません。
具体的にはこのようなコード書き換えが必要です。
以前できたこと…マウスが押されたらこの命令を実行する
今後書き換える内容…直前までマウスが押されていなかった場合かつ現在押されている場合にこの命令を実行する
ただし、これだとコードが長くなるので、いっそのこと、マウスが押されたかどうかより、ブロックが壊されたかどうかで判定すればmainが使えるので楽です。
package funaoka;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
public class HekigaSeisei implements PlayerBlockBreakEvents.After {
private static final String SUUJI_MOJI = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
// テキストファイルを読み込んで文字列配列を返す
public String[] gazouYomitori(String pNamae) {
List<String> gyouzentai = new ArrayList<>();
try (BufferedReader yomitori = new BufferedReader(
new java.io.InputStreamReader(new FileInputStream(pNamae), StandardCharsets.UTF_8))) {
String ichigyou;
while ((ichigyou = yomitori.readLine()) != null) {
gyouzentai.add(ichigyou.trim());
}
} catch (FileNotFoundException e) {
System.out.println("file not found: " + pNamae);
} catch (Exception e) {
e.printStackTrace();
}
return gyouzentai.toArray(new String[0]);
}
// ブロックを壊したときに呼ばれる
@Override
public void afterBlockBreak(Level pSekai, Player pJibun, BlockPos pBasho, BlockState pJoutai, BlockEntity pNyuuryoku) {
ItemStack temochi = pJibun.getMainHandItem();
System.out.println("手に持っているアイテム:" + temochi);
// 手に何も持っていないときだけ壁画生成
if (temochi.isEmpty()) {
hekigaSakusei(pSekai, pJibun);
}
}
// 壁画を生成する
public void hekigaSakusei(Level pSekai, Player pJibun) {
// サーバーワールドでなければ終了
if (!(pSekai instanceof ServerLevel hiroba)) return;
final String[] GAZOU_NAMAE = {
"hekigaMinami.txt",
"hekigaNishi.txt",
"hekigaKita.txt",
"hekigaHigashi.txt"
};
final int[][] GAZOU_ICHI = {
{ 1, 1, -1, 0 },
{ -1, 1, 0, -1 },
{ -1, -1, 1, 0 },
{ 1, -1, 0, 1 }
};
// プレイヤーの向きから方角を決定
int kakudo = ((int) pJibun.getYRot() + 360 + 45) % 360;
int hougaku = kakudo / 90;
System.out.println("degree (角度):" + kakudo);
// 壁画ファイルを読み込む
String[] gyouzentai = gazouYomitori(GAZOU_NAMAE[hougaku]);
if (gyouzentai.length == 0) return;
int kaishiX = GAZOU_ICHI[hougaku][0];
int kaishiZ = GAZOU_ICHI[hougaku][1];
int zougenX = GAZOU_ICHI[hougaku][2];
int zougenZ = GAZOU_ICHI[hougaku][3];
BlockPos genzaichi = pJibun.blockPosition();
BlockPos kaishi = genzaichi.offset(
gyouzentai[0].length() / 2 * kaishiX,
gyouzentai.length,
gyouzentai[0].length() / 2 * kaishiZ);
// ブロックを1つずつ設置
for (int tate = 0; tate < gyouzentai.length; tate++) {
String ichigyou = gyouzentai[tate];
for (int yoko = 0; yoko < ichigyou.length(); yoko++) {
char moji = ichigyou.charAt(yoko);
int narabijun = SUUJI_MOJI.indexOf(moji);
if (narabijun >= 0 && narabijun < Iro62Shurui.IRO_62_SHURUI.length) {
Block masume = Iro62Shurui.IRO_62_SHURUI[narabijun];
BlockPos basho = kaishi.offset(yoko * zougenX, -tate, yoko * zougenZ);
hiroba.setBlock(basho, masume.defaultBlockState(), 3);
}
}
}
}
}
試しに、昨日2026年6月7日(日)に行われた第33回みやぎ川崎支倉常長まつりで撮った写真を取り込んでみました。
右上に Minecraft 26.1.2 Fabric の表記があり、間違いなく現時点で最新版であることが確認できます。

船岡プログラミング教室では、このように近隣地域でのイベントとMinecraftを結び付けて面白おかしくプログラミングをするようにしています。