我的世界MOD制作(2)|| 你的第一个MOD

article/2025/3/10 19:29:02

正文:
I. 开发环境配置
我们需要一个带mixin的forge开发环境,这一步相当折磨人,网络不好的话半天时间都得砸这上面,但是不要灰心,过了这个坎接下来基本是顺风顺水。

1. 下载资源 & 修改build.gradle

首先去forge官网https://www.mcbbs.net/plugin.php?id=link_redirect&target=https%3A%2F%2Ffiles.minecraftforge.net%2Fnet%2Fminecraftforge%2Fforge%2F下载一个1.12.2的mdk,将其解压


我选择解压到D:\LocalCodes\Minecraft\Example中,注意到解压出来的内容中有build.gradle和gradlew.bat两个文件,其他文件我们暂且忽略不管。先用记事本打开build.gradle

  1. buildscript {
  2.     repositories {
  3.         maven { url = 'https://maven.minecraftforge.net/' }
  4.         mavenCentral()
  5.     }
  6.     dependencies {
  7.         classpath 'net.minecraftforge.gradle:ForgeGradle:3.+'
  8.     }
  9. }
  10.         
  11. apply plugin: 'net.minecraftforge.gradle'
  12. // Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
  13. apply plugin: 'eclipse'
  14. apply plugin: 'maven-publish'
  15. ...
复制代码

很长一串文本(Groovy语言,不去管他),接下来我们要对build.gradle文件进行一系列修改


按照上图进行修改,一共6处修改,务必确保每处修改都已完成。教程不对gradle进行深入阐述,但了解一些gradle相关的内容(不必完全掌握)会对你mod的项目管理有很大帮助,也能让你在部署开发环境的时候少走些弯路。

2. 运行gradle

接下来启动cmd,进入build.gradle所在的文件夹(我的话就是D:\LocalCodes\Minecraft\Example),调用命令

  1. gradlew build

初次运行会跑相当长一段时间,其间会下载各种游戏资源,并进行反编译。如果运行失败,并在log中显示了timeout字样,网络问题,多试几次说不定就好了。
 


运行成功后会出现BUILD SUCCESSFUL字样。上图是我运行gradlew build时的情况,因为之前已经下载过相关资源并反编译,所以速度很快。

注:你可能阅读过很多forge环境配置的教程,而每一篇都叫你调用gradlew eclipse之类的命令,然后说mod发布的时候调用gradlew build。一上来就build是在干什么?众所周知gradlew build是将src里的源码编译成能在生产环境(玩家的运行环境)下运行的jar,但运行gradlew build时还会在没配置过环境的电脑上“下载各种游戏资源,并进行反编”,教程正是利用了这个特点来配置无IDE的开发环境。

II. 编写你的第一个Mixin+Forge Mod

1. 写什么好呢?

我打算写个把地狱门边框从黑曜石改为木头的模组,大体效果是这样的


原先是搭黑曜石框点火启动,现在是搭木头框点火启动。

为了写出这个mod,我们得先知道mc里地狱门是怎么一回事,玩过mc的都知道怎么建地狱门,用黑曜石搭一个框,中间留出2x3的空白,然后用打火石点火即可,有经验的玩家还知道打雷引发的火,或者火焰弹引发的火也可以启动地狱门。事实上,用黑曜石搭一个合适的框,只要是火方块就能启动地狱门(在框内的空白中填充传送门方块)。教程专注于如何编写mixin+forge模组,在这里不对机制的代码基础进行阐述,相关内容参阅BlockFire.java、BlockPortal.java及Teleporter.java。

2. 第一个mixin

你会发现mixin指代了很多东西,有时候它指spongepowered开发的mixin library,同时它又指mixin library定义的一类文件mixin,所谓的mixin文件可以被理解为一种特殊的class文件,一定被@Mixin修饰,且在运行时被mixin library特殊处理。

我们先写个mixin对BlockPortal$Size.class进行修改,在src/main/java/com/example/examplemod下新建文件夹mixin,其下新建文件MixinBlockPortal$Size.java,用记事本打开,复制以下内容

package com.example.examplemod.mixin;import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;import org.objectweb.asm.Opcodes;import net.minecraft.block.BlockPortal;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;@Mixin(BlockPortal.Size.class)
public abstract class MixinBlockPortal$Size {@Redirect(method = "getDistanceUntilEdge", at = @At(value = "FIELD", target = "net.minecraft.init.Blocks.OBSIDIAN:Lnet/minecraft/block/Block;", opcode = Opcodes.GETSTATIC))private Block proxy_getDistanceUntilEdge_getStatic_OBSIDIAN() {return Blocks.LOG;}@Redirect(method = "calculatePortalHeight", at = @At(value = "FIELD", target = "net.minecraft.init.Blocks.OBSIDIAN:Lnet/minecraft/block/Block;", opcode = Opcodes.GETSTATIC))private Block proxy_calculatePortalHeight_getStatic_OBSIDIAN() {return Blocks.LOG;}
}

 这样我们的第一个mixin就写好了,教程不会详细讲述mixin如何写,如果对这块内容有需求,参见文末的拓展阅读。

3. mixins.example.json

有了mixin文件,我们还需要告诉mixin library该mixin的存在,这样它才能应用你的mixin。首先在src/main/resources下新建文件mixins.example.json,复制以下内容

{"required": true,"compatibilityLevel": "JAVA_8","package": "com.example.examplemod.mixin","mixins": ["MixinBlockPortal$Size"],"client": [],"server": [],"injectors": {"defaultRequire": 1},"refmap": "mixins.example.refmap.json"
}

 接着在build.gradle的最后加上代码

mixin {
    add sourceSets.main, 'mixins.example.refmap.json'
    config 'mixins.example.json'
}

我们先暂且不管mixins.example.json以及这次对build.gradle的修改作用是什么,这块内容将在Part III 2.1(modid-1.0.jar结构分析)时提及。

4. 第二个mixin

现在写第二个mixin,在MixinBlockPortal$Size.java所处的文件夹下(即文件夹mixin)新建文件MixinTeleporter.java,复制以下内容

package com.example.examplemod.mixin;import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;import org.objectweb.asm.Opcodes;import net.minecraft.world.Teleporter;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;@Mixin(Teleporter.class)
public abstract class MixinTeleporter {@Redirect(method = "makePortal", at = @At(value = "FIELD", target = "net.minecraft.init.Blocks.OBSIDIAN:Lnet/minecraft/block/Block;", opcode = Opcodes.GETSTATIC))private Block proxy_makePortal_getStatic_OBSIDIAN() {return Blocks.LOG;}@Redirect(method = "placeInPortal", at = @At(value = "FIELD", target = "net.minecraft.init.Blocks.OBSIDIAN:Lnet/minecraft/block/Block;", opcode = Opcodes.GETSTATIC))private Block proxy_placeInPortal_getStatic_OBSIDIAN() {return Blocks.LOG;}
}

接着修改mixins.example.json,在"MixinBlockPortal$Size"后加入, "MixinTeleporter",使之变为"MixinBlockPortal$Size", "MixinTeleporter"。

III. 发布!
别着急,mc模组从开发环境到生产环境(玩家的运行环境)之间还有一段路要走,视情况可能比开发环境配置还棘手。不过,在一般情况下就是一句gradlew build的事。

1. Build看看

cmd中执行

  1. gradlew build


成功build,到build/libs中拿结果(modid-1.0.jar文件)。


http://chatgpt.dhexx.cn/article/TiIdR4YN.shtml

相关文章

Ts 简单随机迷宫迷宫地图

直接上代码 //随机地图const { ccclass, property } cc._decorator;ccclass export default class NewClass extends cc.Component {property(cc.Node)mapItem: cc.Node null;property(cc.Node)mapContent: cc.Node null;private mapArr: any [];onLoad() {}start() {}ran…

C++游戏编程--实现鼠标编辑迷宫地图界面

鼠标左键放砖,右键取消。 void Change() {Show();while (true) {ExMessage m;//定义一个消息变量m getmessage(EM_MOUSE);//获取鼠标消息switch (m.message){case WM_MOUSEMOVE:// 鼠标移动的时候画红色的小点putpixel(m.x, m.y, RED);break;case WM_LBUTTONDOWN:/…

台州oj 5061 迷宫地图

5061: 迷宫地图 时间限制(普通/Java):1000MS/3000MS 内存限制:65536KByte 总提交: 114 测试通过:28 描述 在一些迷宫游戏中,往往有多个关卡,每个关卡有不同的地图,地图往往是由n行m列的方格组成,每个格子上可能是通道、墙壁、道具、玩家等。在设计时,…

关于矩形迷宫地图的数组化处理和相应寻路算法的思考

目录 矩形地图的数组化 思路 提取实现 实现过程 (1)特征 (2)取点问题 (3)需要确定的变量值 (4)另外的 (5)适用的迷宫类型 寻路算法 数组迷宫的特点 数组迷宫的缺点 算法…

C#迷宫Winform小游戏,生成可连通的迷宫地图

上一篇本人已经写了一个控制台小游戏,这次使用Winform来生成可连通的地图,并测试运行游戏 迷宫小游戏控制台 一、先更改控制台游戏的一点点代码,用于测试迷宫是否连通的【即:从起点可以到达终点】。只用更改 MazeUtil.cs的查找路…

迷宫游戏|自动寻径|随机生成迷宫地图|UI|闯关|地图反转

MazeGame 遵循开源协议 MIT 开发工具及运行环境 开发IDE环境 : Visual Studio 2019 代码管理工具: Git 开发语言:C 程序运行环境(开发环境为(Windows10)其他兼容性未知) 依赖库 EasyX 图形界面库 EasyX官网:EasyX Git仓库地址 Gitee:Gitee 仓库 Github:h…

Java程序:迷宫地图生成器

Java程序:迷宫地图生成器 1、运行效果 可以在【0,50】之间随意设置行数和列数,比如设置为25行25列的迷宫地图数组。 迷宫地图的每一个方格,如果是白色,单击就变成黑色,如果是黑色,单击就变成白色。黑色对应数组里的1,白色对应数组里的0。 因为没有采用路径搜索算法来设…

Java 开发实例(第3篇),绘制迷宫1 生成迷宫地图

开发环境: 操作系统Win10。 1.下载Java 15,提取码:soft 2.下载软件 Eclipse 2020-12,提取码:soft 下载本博客的实例工程代码,提取码:soft 前天2月9日在逛B站App时,意外看到一个很…

Python 打印迷宫地图小游戏

在实现玩转小迷宫这个游戏时,分别使用了input()输入函数、print()输出函数、if…elif…else语句、二维列表、while循环、for循环 下面对这些用法再一次重温 1.input()输入函数 在 Python 中,使用内置函数 input() 可以接收用户的键盘输入。input() 函数…

html5的canvas绘制迷宫地图

canvas标签一直是html5的亮点,用它可以实现很多东西。我想用它来绘画像迷宫那样的地图。借助到的工具有瓦片地图编辑器tiled(点击跳转到下载链接)。 如图:如果你想要画像这样的迷宫地图,如果不用canvas,可以通过dom操作拼接一个一个div,以达成这个效果。那样是不是很不合…

深度优先,Kruskal,Prim几种方式生成迷宫地图

小时候玩过一款3D版迷宫,那时还是功能机时代,黑白界面拼凑的伪3D效果还是给我带来了很多快乐。后来出现了智能机,却再也没找到过那样纯粹的迷宫游戏。总算自己找时间做一个出来。 本文主要介绍一下深度优先,Kruskal,Prim几种方式生…

二维数组随机生成地图迷宫_经验分享:三套简单的迷宫地图生成方案

文/兔四 概述:文章基于一种基础的地图,来讨论三套不同的地图生成方案。 文章不会出现跟代码相关的内容,会以较为通俗的语句和不少简单的示意图来表示迷宫的生成方案。其中不少方法来自于游戏界前辈,我根据自己的基础地图做了不少修正(毕竟迷宫和地图的形式多种多样,适合自…

算法自动生成迷宫地图

文章目录 前言一、什么是(DFS)深度优先算法?深度优先算法实现步骤1.引入库2.初始化参数3.Turtle画方格函数4.开始生成数组并调用Turtle画图 二、什么是(BFS)广度优先算法?广度优先算法实现步骤1.引入库2.初…

【工具篇】Unity迷宫地图生成器MazeSpawner随机迷宫信手拈来

目录 一.迷宫生成效果 二.使用流程 三.使用场景 四.源码地址 一.迷宫生成效果 二.使用流程 1.导入后结构目录如下,打开prefab文件夹找到MazeSpawner放进场景里面

C++实现随机生成迷宫地图自动完成寻径

#include<iostream> #include<stack> #include<vector> using namespace std;template<class T> class Maze { public:Maze( //默认参数值pair<int, int> initSize make_pair(15, 17),pair<string, string> initStyle m…

Python 制作迷宫游戏(一)——地图

Python 制作迷宫游戏&#xff08;一&#xff09;——地图 序 作为一个迷宫类的游戏&#xff0c;其最重要的是什么&#xff1f;当然是它的地图啦♪(∇*) 那么我们又该如何制作一张迷宫地图呢⊙(・◇・)&#xff1f; 很显然&#xff0c;我们不可能一张张自己画吧 网络上常见的迷…

三套简单的迷宫地图生成方案

地图基础 地图的形式很多&#xff0c;这里我使用的地图是以tile块为单位分割的地图&#xff0c;地图上的tile块形式很多&#xff0c;但主要分成三种&#xff1a; A&#xff1a;陆地&#xff0c;可以在上面分布一些角色啦物件啦&#xff1b; B&#xff1a;过渡&#xff0c;根据物…

SenticNet情感词典介绍

在进行情感分析时&#xff0c;一个好的情感词典能够让我们的工作事半功倍&#xff0c;较为出名的情感词典有SentiWordNet&#xff0c;General Inquirer等&#xff0c;这篇博客将介绍另外一个出色情感词典&#xff0c;SenticNet。 简介 当谈论SenticNet时&#xff0c;我们正在…

中文金融领域情感词典构建

2019年10月4日-6日 Python爬虫与文本分析工作坊 & 课题申报高级研修班 这篇文章是公众号关注者郝童鞋今早发给我的&#xff0c;在此谢谢郝童鞋。 文章基于简单算法和人工判断&#xff0c;使用多阶段剔除法&#xff0c;构建了 中文金融情感词典CFSD&#xff08;ChineseFinan…

《学术小白的学习之路 02》情感分析02 之基于大连理工情感词典的情感分析和情绪计算

本文主要是学习参考杨秀璋老师的博客,笔记总结。 原文链接 文章目录 书山有路勤为径&#xff0c;学海无涯苦作舟原文链接一.大连理工情感词典二、七种情绪的计算2.1 pandas读取数据2.2 导入大连理工大学中文情感词典2.3 统计七种情绪的分布情况2.4 增加中文分词词典和自定义的停…