我决定以一个开发实例作为教程,我们要使用Forge来创建一个叫做Diracon的mod,它将具有如下功能.
(1)一个新的矿物(砖块):Diracium
(2)一个新的矿锭(物品):Diracium Ingot
(3)一个新的物品:Dirac Wand
(4)一种新的Mob:Dirac Pig
(5)添加新的功能,使Dirac Wand具有瞬间转移箱子内的物品的能力
(6)修改地形生成器,使新矿物可以生成
(7)一个以土块为燃料的新炉子Unthinkable Furnace
(8)支持多人游戏!
这8个功能基本涵盖了基础mod开发的全部,我计划分为三个部分,(1)(2)(3)作为第一部分,(4)(5)作为第二部分,(6)(7)和mod的编译发布作为第三部分.而(8)会作为贯穿全篇的一个目标,自始至终都在进行.
这里说明一下本教程中不同颜色的字体所代表的含义.
蓝色:一个章节
红色:知识点,相当于一个章节所讲内容的概括
灰色:原理,想深入学习MCP和Forge的人可以读读,普通MODer可以无视了.
再统一一下今后教程中将使用的术语.
从上往下看.
红1:这个类所处的包(Package).
蓝1:导入的包.
绿1:类,类的概念我实在难以解释,熟悉Java的人应该都知道吧...
紫1:继承,派生.正规的说法是一个基类派生出子类,子类继承自基类.然后我们并不在乎这上面的文字游戏,汉语本来就是个不规范的语言呢...我们说子类从基类派生而来,或子类继承自基类不也一样吗...所以本文不会太注重派生/继承的用词.但我保证会留下足够的逻辑线索让你一眼看出我所表达的意思.
青1:基于XXX接口创建类.
红2:类的空位,即方法与方法间的空位,如果我说"在XX类中添加这些代码"就是指在这些位置添加代码.
蓝2:构造函数.如果一个方法的名字和类相同,那么它就是构造函数.它会在类实例化时执行.
绿2:方法/函数,我习惯叫它方法.这个是最准确最规范的叫法.
紫2:返回值.
青2:参数.
最后再向新手程序员解释一下何为重写,重写(Override)是让子类的方法覆盖父类的方法,重写的办法是让子类方法的名字和父类方法一致.唯一特例是构造函数,它的名字依然和子类名字保持一致,但必须调用父类的构造函数(使用super).
创建一个Package(包)
Java以Package的形式来管理代码,它的作用类似于C++和C#的命名空间,优点是便于将代码分类管理,使程序更加直观;方便控制代码的作用范围;解决类的重名现象(比如下一章要用到的Block类,有6个类都叫Block,但只有net.minecraft.block包中的Block才是真正需要的).MDK自带的范例里已经自带了一个包和一段程序,不过这里我们还是新建一个.
Package的命名很随意,Forge建议的命名规范是"作者名.mod名",Java建议的Package命名规范是Package的制作公司的网站的域名的倒写,例如"com.sun","com.google"等...
比如:
fanhua.minelogin
szszss.eracraft
net.mcbbs.multicraft
net.areazero.tohoskyarena
总之不必在这个的命名上费太多脑筋,但是不要有太奇怪的命名,比如:
pan.1c0xr8Hy.h0yx.SSTM
就是不行的,首先包中的每一段必须是字母或下划线开头,不能是数字,其次不建议包名使用大写.
首先你要为服务器端与客户端的公用代码创建一个package,右键项目中的src/main/java,选择New->Package
(关于目录结构,这个跟Gradle的设计有关,Gradle将目录分为两个部分:源代码(我们使用Java来编程,因此自然叫java)和资源文件(resource),因此我们以后将程序放在src/main/java里,资源文件放在src/main/resource里)
然后输入Package的名字.
创建完毕后,这个Package今后将用于放置你的代码.
创建一个Mod主类
Mod主类是负责进行Mod的初始化,并且可以被Forge所识别的一个类(Class).
关于Mod主类的命名,在ModLoader时代,它的名字必须以"mod_"开头,但在Forge中它叫什么都可以.所以我将其命名为Diracon.
在你的package中创建一个类.(右键你的package,选择New->Class)
点击Finish开始创建,创建完后我们便有了一个空荡荡的文件,我们要让它能被Forge找到,方法是为类添加一段Annotation.
Annotation是Java的一种增强型注释,它和普通注释(双斜杠)的区别是,普通注释在编译阶段就会被删除,而Annotation会保留下,Annotation能储存数据,能在程序运行阶段通过某些方法(如反射)被读取.
在public class Diracon的上一行添加:
@Mod(modid="diracon", name="Diracon", version="1.0.0")
知识点:@Mod
///////////////////////////////////////////////////////////////////////////////////////////////////////////
@Mod必须标注在类的上方,它的含义是告诉Forge"这是一个Mod主类".
它有1个必要参数是字符串类型的modid,代表Mod的id号,它将用于内部识别,请确保它不包含特殊字符,并且不会经常变动,还有一个忠告,确保它是全小写.此外还有一系列可选参数,比如name是显示给玩家看的Mod名;version是版本号,对于联机Mod来说不要乱填,保守的话A.B.C这样的格式肯定是没问题的,其中ABC均为数字,A代表主版本号,B代表次版本号,C是没有功能性更新,纯粹是Bug紧急修复时递增的版本号.如果想更简单的话可以只留A.B两位,再懒一些的话哪怕单独一个数也行,主要能用于区分开新旧版本就行.关于version格式的具体要求可以见扩展阅读"@Mod的各个参数".
在过去,还有一个叫@NetworkMod的注解,但它在1.7中被去除了.想了解它的替代品可以看这里.
关于@Mod的其他参数,可以见本篇的扩展阅读.
///////////////////////////////////////////////////////////////////////////////////////////////////////////
之后静等两秒,你的Eclipse就开始报错了...因为你没有导入相关的package,将鼠标移到红波浪线上,等提示框出来后选择"Import ..."来自动导入相关package.
之后我们要添加用于初始化Mod的方法(Method,不理解的自行补Java...)在ModLoader时代,我们通过重写(Override)基类的方法来实现,现在没有基类了,所以我们使用Annotation来实现.
在你的类中添加这些代码.
@EventHandler public void preLoad(FMLPreInitializationEvent event) { } @EventHandler public void load(FMLInitializationEvent event) { } @EventHandler public void postLoad(FMLPostInitializationEvent event) { }
知识点:@EventHandler与历史的伤痕
///////////////////////////////////////////////////////////////////////////////////////////////////////////
看上去这个标题很严肃...事实上是我为了搞笑故意起的...
如果你是个老Modder(MC1.6版以前就开始做Mod)那么你应该记得那时Forge没有@EventHandler这个注解,取而代之的是@Init,@PreInit和@PostInit这三个分工详细的注解.
在最初的ModLoader时代,所有的Mod主类都通过重写load方法来实现初始化,到了ForgeModLoader后,Forge(最初)通过带有@Init的方法来实现初始化,同时它还提供了@PreInit(初始化前)和@PostInit(初始化后)两个方法来为初始化扫清障碍或收尾.
然而现在FML使用@EventHandler来泛指所有参与Mod初始化工作的方法,区分这些方法的唯一方式是它们的参数,根据他们的参数的类型,FML会利用事件系统在不同的时段调用他们.
FMLPreInitializationEvent 预初始化
CPW建议开发者在预初始化时进行读取配置,创建物品砖块,以及注册相关信息等操作,另外你还能在这时候获得FML给你传来的配置文件.(Configuration,但是我并不太愿意在基础篇讲这个东西...)
从1.7开始,砖块和物品的初始化必须在这个阶段进行!
FMLInitializationEvent 初始化
配置Mod设置,添加合成表...另外CPW建议Mod间通讯(通过FMLInterModComms类完成)应当在此时进行.
FMLPostInitializationEvent 初始化后
CPW认为初始化后是供Mod间相互交互的时候,此时该载入的Mod都已经载入了,因此开发者们可以在此时为实现Mod间联动的操作做准备.顺便一提,FMLPostInitializationEvent事件的buildSoftDependProxy方法可以获取一个类的实例,它会先判断你要求的mod是否存在,如果存在则返还给你你要求的类的实例.
IMCEvent 接收Mod间通讯
这个事件会排在FMLInitializationEvent之后,它会附带一个保存着其他Mod发来的信息的列表.
此外,还有几个服务器事件,但这个就不在基础篇的范围内了...(其实是我急着去玩Civ5懒得继续码字了)以后我会单开一个篇幅讲.
///////////////////////////////////////////////////////////////////////////////////////////////////////////
然后导入相关的包,你的第一个Mod就已经能运行了...保存,选择Run - Client开始运行吧!
于是就是这样...你的第一个Mod已经能被载入了,虽然它还什么都没有,但千里之行始于足下,你已经走出了第一步,不是吗?
(好奇为什么我的Minecraft Forge旁边有个绿点?因为我现在用的是测试版的Forge...当你开发Mod时应该已经有稳定版了)
扩展阅读
最初我计划将一些更深入的东西写在单独的章节里,但总是感觉有些突兀,而且有些东西往往不足以写成一篇单独的文章,再考虑到很多好♂学的人希望能立刻读到这些内容,因此便有了扩展阅读,扩展阅读的内容往往高于甚至远高于基础篇的内容,属于选读部分.
@Mod的各个参数
@Mod注解除了modid这个必选参数以外,还有很多可选参数,这些参数包括:
参数 | 类型 | 描述 | 默认值 |
---|---|---|---|
modid | String | 用于FML内部识别的ID,ID绝不能和其他Mod重复. | 无,此为必要参数 |
name | String | 人类可读的Mod名. | modid |
version | String | 用于内部识别的版本号,别被文档骗了,它可不是为人类可读而设计的,它的格式有严格要求,具体见附文-version的格式. | 见附文-version的默认值 |
dependencies | String | 描述Mod依赖和加载顺序,其格式是"[顺序]:[Mod名]<[版本]>",如果有多个的话使用";"分割. [顺序]可以是"required-before","required-after","before"或"after".前两者代表硬性依赖,如果不存在被依赖Mod(或版本不正确)的话此Mod不会被加载,其后缀表示此Mod是在被依赖的Mod之前还是之后加载.后两者代表可选依赖,仅用于表示加载顺序. [Mod名]为被依赖Mod的modid,如果[顺序]是"before"或"after"的话,这里可以填"*"(星号),代表在所有Mod的最后或最初加载.(当然,我们都知道如果有一堆Mod争当第一的话,总会有个先后顺序,所以别太依赖这个.) <[版本]>是可选值,格式为"@[值域]",比如"@[1.0, 2.0)"为版本大于等于1.0,小于2.0的版本;"@[2.3.3,)"代表版本大于等于2.3.3的版本. 实例:"required-after:parentmod@[1.5,)"依赖parentmod1.5或更高的版本,且在它之后加载. |
空字符串 |
useMetadata | boolean | 字面上是指"是否允许mcmod.info中的设定覆盖@Mod中的设定".这是因为Mod的信息可以来自于两处:@Mod注解和mcmod.info文件,毫无疑问mcmod.info是最正式的也是内容最丰富的,然而两者之间的内容可能存在重复甚至矛盾,因此就有了这个选项,用于指定优先使用哪里的设定. 然而实际上它的功能比较有效,并非所有mcmod.info中的设定都能覆盖@Mod,只有以下设定可以覆盖: 依赖:当useMetadata为false(默认值),或mcmod.info中的useDependencyInformation为false(默认值)时,会使用@Mod中的dependencies作为Mod的依赖;否则会使用mcmod.info中的requiredMods、dependencies和dependants来作为Mod依赖.需要注意的是@Mod中的dependencies和mcmod.info中的dependencies作用完全不同. Mod顺序:准确地说,它和上面的"依赖"应该是一体的,当"依赖"满足使用@Mod的条件时,FML会将@Mod中的dependencies作为排序依据;否则会使用...一个空字符串作为排序依据?也许这是个Bug? |
false |
clientSideOnly | boolean | 是否为客户端专用Mod,若为true,则不会在独立服务器被加载. | false |
serverSideOnly | boolean | 是否为独立服务器专用Mod,若为true,则不会在客户端被加载. | false |
acceptedMinecraftVersions | String | 表明Mod可以运行在哪些MC版本上,默认空字符串表示不检查,里面填的内容采用Maven Version Range Specification规则. | 空字符串 |
acceptableRemoteVersions | String | 表明联机Mod的服务器端所允许的客户端Mod版本,比如服务器端运行着1.1.5版,默认情况下客户端运行的Mod也必须是1.1.5版,然而通过设置acceptableRemoteVersions,可以让运行着其他版本Mod的服务器端也能连入游戏,比如1.1.0~1.1.4.设置格式依然采用Maven Version Range Specification规则,不过如果填"*"(星号)则是允许一切版本.此外,如果Mod主类中有一个方法带有@NetworkCheckHandler注解的话,这一项会被忽略. | 空字符串 |
acceptableSaveVersions | String | 大概是对游戏存档所使用的Mod版本号的限制,然而怎么看都感觉像是一个尚未被实现的功能... | 空字符串 |
certificateFingerprint | String | 用来实现对Mod的Jar包签名验证,大概是要求Mod的Jar包必须有一个SHA-1格式的验证签名,否则就会拒绝加载,然而我不是很了解这个 233 | 空字符串 |
modLanguage | String | 描述该Mod所使用的编程语言,可以是"java"或"scala". | "java" |
modLanguageAdapter | String | 如果你的Mod是使用其他JVM语言(也就是除Java和Scala以外的语言)编写的话,你需要手动写一个语言适配器,这个适配器需要实现ILanguageAdapter接口,这里填入的是适配器的类名,也就是形如"package.MyClass"的格式. | 空字符串 |
canBeDeactivated | boolean | 是否可以在Mod菜单中被关闭,又是一个尚未实现的功能... | false |
guiFactory | String | 指示一个实现了IModGuiFactory接口的类,这个类主要是负责创建Mod菜单中的Config界面,具体可以参考ForgeGuiFactory类和FMLConfigGuiFactory类. | 空字符串 |
updateJSON | String | 标示获取升级信息Json的URL,关于这个Json文件的格式可以参考https://gist.github.com/LexManos/7aacb9aa991330523884. | 空字符串 |
customProperties | @CustomProperty[] | 标明Mod的自定义属性,例如@Mod(modid="XXX", customProperties = {@CustomProperty(k = "键", v = "值")}) 获取属性可以通过Loader.instance().getCustomModProperties([Mod ID]).get([键]) 不过这里有个隐患就是如果那个Mod不存在的话会直接NullPointerException.此外它也只能存字符串,因此实在不明白它能拿来干什么. | 空数组 |
注:如果你给一个参数指定了null或空字符串(对于String类型)的话,也会被置为默认值.
version的格式:version的格式采用Maven的版本号规则,简单地说,它最多包含5部分:主版本号(Major),次版本号(Minor),无功能性更新纯粹是修复Bug时的递增版本号(Incremental),累计构建编号(Build)以及不限数量的文字修饰符(Qualifier).在不引入修饰符时一切都好说,比较版本时直接从前往后比,不相等就返回结果,相等就对比下一位,然而在引入修饰符后情况就复杂了很多,那篇文章几乎有一半的内容在描述如何处理修饰符,有兴趣的话可以看看那篇文章.
version的默认值:version的默认值规则比较复杂,如果你没有给version指定值,或者指定一个空值或null的话,系统会先在Mod包的根目录寻找"version.properties"这个文件,然后按照标准的Java Properties文件的格式从中读取"[modid].version"这个条目,比如"diracon.version";如果没有找到文件、文件格式错误或没有此条目的话,系统会去使用Metadata中的version;如果还是没有值的话,则此处的version和Metadata中的version都会被置为"1.0".
代码部分看起来很糟糕的样子。。
LiveWriter把格式弄花了...以后打死不用LiveWriter了= =
而且我不知道forge把MCP下载到哪里去了
如果有问题可以来提问么 = =,另外可以加一个企鹅么
可以加Q,就地留言也行但我不是经常看blog...
能发全部代码出来么。。。
代码和纹理http://sdrv.ms/17iPu7R 感觉意义不大啊(¯﹃¯)如果遇到问题了就尽管问吧
话说 如果想写 在水桶端使用的插件或MOD 应该怎么配置呢??
必须在反编译之前么? 希望帮帮我.... 发个邮件是最好的了 = =
多谢 多谢 多谢...............
没编过水桶插件/w捂脸 如果是要做能用在水桶端的ForgeMod的话,可以看一下MCPC的wiki...
其实,我现在纠结的是不知道要学啥...
以前一点编程基础都木 = = C看了看、C++看了看、VB也看了看.....啥都没学到(看见鹰语就头晕),玩MC玩的又看了看JAVA,还是同上....JAVA的类啊包啊啥的把我搞晕了......
现在开始接触 易语言(最起码 教程都是中文滴) - -
其实学易语言也没什么的(虽然我知道你肯定没觉得学易语言可耻(¯﹃¯)但网上确实有不少人喷易语言),毕竟它也是个面向对象语言,在编程思路上和主流的面向对象语言都是类似的,仅仅只是语法是中文而已← ←(不过它的运行环境苛刻是真心艹蛋)
虽然我不是搞教育的→ →但个人感觉学语言可以分为"循序渐进"或"从需求出发"两种方式.
对从未有编程基础的人来说,"循序渐进"是个值得考虑的方式,循序渐进就是开始从最基础的语法开始,用面向结构的思维编程,然后慢慢转入面向对象.面向对象的优点只有达到一定编程水平后才会体会到,强迫初学者从一开始就去学习何为函数/方法,何为类和访问级并不妥当,刚开始学习语法时最好排除掉这些因素,虽然有很多人喷VisualStudio和C#无脑,但它们确实是新手程序员的温床~特别是用VS编窗口软件,对新人来说画界面然后双击控件便能添加代码是件非常有意思也是很有成就感的事...(而且由于C#原生支持事件(event),所以代码结构对新人而言非常清晰,Java的监听器+匿名类的代码结构很让人困惑)虽然刚开始(假设你学的是C#)你可能会纠结为什么xxx.ToString后面要带一个括号,为什么xxx.Text后面直接是等号,但这时基本的语法和面向结构编程思路已经在你脑中成型.接下来是冲击面向对象编程,刚开始学习类,方法,访问级,静态/非静态等东西时可能很让人痛苦甚至会怒喷"这分明是面向吃屎语言嘛"(我自己就这样喷过C#,所以我看YYF喷Java时一点也不奇怪~),但只要掌握后便会理解设计者的初衷,那时你会习惯上面向对象编程,习惯写类,写方法,写属性(如果你学的是C#)或包(如果你学的是Java,Java对包的使用远比C#多,C#的重名类很罕见,Java的则非常多).通常来讲这是大多数新人学习的过程...如果你是像Indeed那样小学就征服C++的巨触的话...当我没说吧.
另一种"从需求出发"则是适合已经掌握一定编程基础的人去学习新语言,比如我从C#转Java和学习JS,PureDark(PD服服主)学PHP和SQL那样,没有抱着本书看十天半个月然后才实际上机操作,也没有从最基础的地方一点点开始弄,而是简单地看了下教程后就按自己的需求开始编程了...遇到不会的地方则立刻百度/谷歌搜索,虽然刚开始编的东西可能有些难看,但很快便能上手,对于一些困难的东西(比如ASM)这个方法尤为有效,毕竟实践出真知,有些东西如果不实际操作的话恐怕永远只能停留在"只敢远观不敢亵玩"的阶段...
最后一点,多实践!不用羞于照葫芦画瓢,只要代码是你自己动手码下来的,就一定能有收获,即使是复制粘贴...也别忘了要读读对方的代码,把思路也一并复制粘贴入自己的脑袋里!^ ^
多谢,我对所有的编程语言没有其他人有那么大的偏见,每种编程语言都可以看成是一种方言,只是表述方式不同而已其实最后所要做的还不是编写软件么 = =
我只是对英语等鸟语的学习感到很困难而已,记不住啊- -
你刚刚接触编程时是怎么学习的呢?我总感觉找不到路啊.......
没有面向结构只有面向过程或结构化编程
其实,java也就开始讲解和理解类的概念难一点,我整整看了2天整个人都喵了个咪了。才搞懂概念。其实到应用的时候简单的。
我运行recompile时出现
== MCP 7.44 (data: 7.44, client: 1.5.1, server: 1.5.1) ==
# found ff, ff patches, srgs, name csvs, doc csvs, param csvs, renumber csv, ast
yle, astyle config
== Recompiling client ==
> Cleaning bin
> Recompiling
'"C:Program FilesJavajdk1.7.0_21binjavac" -encoding UTF-8 -Xlint:-options -
deprecation -g -sourc...' failed : 1
== ERRORS FOUND ==
srcminecraftnetvincenttandiraconDiracon.java:18: error: class, interface, o
r enum expected
public void preLoad(FMLPreInitializationEvent event)
^
srcminecraftnetvincenttandiraconDiracon.java:23: error: class, interface, o
r enum expected
public void load(FMLInitializationEvent event)
^
srcminecraftnetvincenttandiraconDiracon.java:28: error: class, interface, o
r enum expected
public void postLoad(FMLPostInitializationEvent event)
^
3 errors
==================
!! Can not find server sources, try decompiling !!
Press any key to continue . . .
而我运行starclient时出现
== MCP 7.44 (data: 7.44, client: 1.5.1, server: 1.5.1) ==
# found ff, ff patches, srgs, name csvs, doc csvs, param csvs, renumber csv, ast
yle, astyle config
== Recompiling client ==
> Cleaning bin
> Recompiling
'"C:Program FilesJavajdk1.7.0_21binjavac" -encoding UTF-8 -Xlint:-options -
deprecation -g -sourc...' failed : 1
== ERRORS FOUND ==
srcminecraftnetvincenttandiraconDiracon.java:18: error: class, interface, o
r enum expected
public void preLoad(FMLPreInitializationEvent event)
^
srcminecraftnetvincenttandiraconDiracon.java:23: error: class, interface, o
r enum expected
public void load(FMLInitializationEvent event)
^
srcminecraftnetvincenttandiraconDiracon.java:28: error: class, interface, o
r enum expected
public void postLoad(FMLPostInitializationEvent event)
^
3 errors
==================
!! Can not find server sources, try decompiling !!
Press any key to continue . . .
什么回事啊,求解,谢谢
发一下你的代码吧...
请问为什么不能导入一些package,代码已完全照楼主打了..
谢谢,我已自行解决了,顶楼主
我目前用 minecraftforge-src-1.5.1-7.7.1.611.zip 下载回来用它内建的install.cmd一路自动安装到好都没问题
然后, 我使用eclipse (版本20130225-0426)来编辑, 照着你这篇的方式依序输入, 也有做recomplie, 最后才 startclient, 但是进入后, 我查MOD的画面, 它并没有载入, 请帮我查看一下问题出在哪.
我的 TestOre.java档的内容如下:
package net.minecraft.unoya;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.Init;
import cpw.mods.fml.common.Mod.PostInit;
import cpw.mods.fml.common.Mod.PreInit;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.network.NetworkMod;
@Mod(modid="testxx",name="Rtest", version="1.0.1")
@NetworkMod(clientSideRequired=true, serverSideRequired=false)
public class TestOre {
@PreInit
public void preload(FMLPreInitializationEvent event){
}
@Init
public void load(FMLInitializationEvent event){
}
@PostInit
public void postload(FMLPostInitializationEvent event){
}
}
好厉害的问题= =我也跪了...试试换个更新版本的FML,检查一下源代码文件的位置,既然你的package是net.minecraft.unoya,那源代码文件是在MCP目录下的srcminecraftnetminecraftunoya中吗
是的, 写的JAVA源码的被eclipse自动放在srcminecraftnetminecraftunoya里.
不过, 我等不及得到解答, 一气之下我把MCP和Ecllipse两个都砍掉重灌了XD
我没有摸过JAVA, 10几年前有学过一点C语言而已, 目前较会的只有VisualBasic2010.
我发觉目前Forge1.5.1的SRC版本很赞, 只要下载这个回来执行install.cmd就可以了, MCP的整个安装它都把你搞定.
我之前还傻傻的按照文章写的一步步操作...
由于MCP和Ecllipse我都重灌了, 我也重新开工作区再继续新的专案, 目前已经没有MOD无载入的情况发生, 之前怎么发生的,我也一头雾水 -.-
目前我还是一直对照着你其它的教学文章一边看一边实作, 但是有个很大的问题, 1.5版在MC来讲是不是很大的转泪点? 你的文章里很多的指令都跟现在1.5.1版的有很多不同之处, 使用方式也有很多不同, 对于我这新手而言, 学起来有点困扰.
我目前从你的文章里学会的有:
1. 把MOD载入
2. 造出新的方块
3. 造出新的工具
4. 造出新的合成公式
5. 增加熔炉的可炼制物品
另外我也从一些日文网站学到小皮毛的知识.
目前对于GUI这东西很感兴趣, 但是你的文章使用的版本与目前的差异很大, 我实作不起来啊~
可否教一下用目前的版本最简单的做法, 我想在画面左上角不断的显示 How are you 这字串.
我比较想从FML学起, 旧有的ML方式可否不要学?
不好意思打扰你的读书时间XD
在MC1.1版以后有几次大的变动,一次是在1.2.x改了坐标系系统,一次是改了目录结构(具体哪个版本忘了...),将客户端和服务器端合为一体,还有一次则是1.5.0重做了渲染系统和纹理系统.现在的教程第一次编写时是基于1.4.x,在1.5.0更新后我已经重写了变动的部分,应该没有不同之处了啊...
ModLoader当然可以不用学了,这年头除了日本的一些Moder已经很少有人用ModLoader(好奇为什么他们那麽偏爱ModLoader?)
我传了一个在画面左上角显示一个字符串的演示,package为net.minecraft.unoya.下载地址在http://sdrv.ms/16miWxM
我想问下,我把鼠标放到红线上,没有出现 import ‘mod’XXXX 的选项啊,
只有CREATE xxxx
和 FIX xxxxx
为什么我的minecraft文件夹(Eclipse中的Minecraft项目中的那个)打开后只有net.minecraft.client?楼主截图中的一大堆cpw什么什么的package是从哪来的呀?
那些是Forge的一部分(准确说是FML的),会不会是在安装过程中遇到了什么错误...?
我上次在运行install.bat的时候貌似有几个文件总是下载失败……但是忘记截图了TAT
...翻墙吧!开VPN或者到http://files.minecraftforge.net/fmllibs/里手动下载需要的文件...← ←
发现自己好笨QAQ
那啥recompile.bat和start.bat显示找不到指定路径怎么破?
完全按照你的方法来的,之前一切正常,点了小虫子啥事都没发生……
我是不是得把minecraft放在某个指定的目录里?