教程正在向1.7更新...

基础篇第一篇已经更新了1.7下的Forge安装方法,但旧版的安装方法依旧保留在一个ToggleBox里,此外我也不建议开发者立即转向1.7开发(当然,已有Mod的升级是不能停的~),因为...众所周知,MCP组的组长Searge抛下他的好基友ProfMobius"带着小姨子卷走捐款跑了"(大雾,其实是被Mojang招安了),于是MC反混淆的任务就没有人接手了,新版MC代码中满是func_xxx,field_xxx,完全无法直视...

故此,现在(1月11日)只有第一篇教程更新到了1.7,其余教程仍停留在1.6时代.1.6到1.7的变动我会写在这里.

目录结构的变动:

现在Mod源码要放在[forge目录]\src\main\java下,资源文件(比如纹理)要放在[forge目录]\src\main\resources下.

注解的变动:

@ForgeSubscribe
现在更名为@SubscribeEvent

@NetworkMod
现在这个注解被取消了,它的功能被这些东西所替代:
clientSideRequired和serverSideRequired:现在FML支持自定义的Mod需求检测函数,这个函数必须是一个位于Mod主类公共静态(public static)方法,返回值为boolean,参数为Map<String,String>和Side.参数中的Map为远端发来的Mod列表及其版本,如下图所示,Side为远端类型.SERVER代表远端为服务器,本地为客户端,CLIENT代表远端为客户端,本地为服务器.比如当你的检测函数被调用时,如果收到的Side是SERVER的话,说明你现在的代码是运行在客户端下.返回值代表是否满足需要,返回false的话即不满足联机条件.(有趣的是,即使是在单人游戏下,检测函数也会被调用两遍,因为众所周知,MC的单人游戏其实是伪多人游戏~)
如果有多个检测函数的话,结果将依赖字节码的结构,只有在字节码中位于最后一个的检测函数才会被调用.在大多数编译器中,字节码结构基本和你的源代码结构相对应.但建议不要依赖这个特性.
如果检测函数不在Mod主类的话,那么它什么用也没有.
gradlewN1
channels:现在通过NetworkRegistry的newChannel方法来手动注册封包通道和处理句柄,详细内容看注释吧,难道一次注释写的比版权声明详细呢...更详细的使用我会在别处写.
versionBounds:由Mod需求检测函数实现.
packetHandler和tinyPacketHandler:在newChannel时指定.
connectionHandler:应该也是在newChannel时指定吧...不了解这个.
clientPacketHandlerSpec和serverPacketHandlerSpec:似乎没有发现对应的...

物品与砖块的变动:

现在Minecraft拥有了原生的命名空间系统(\散花/),不过FML很早就实现了自己的命名空间系统了...不是吗,所以如果你不急着使用这个新特性的话,那就继续使用GameRegistry的砖块/物品注册吧.

现在砖块和物品不需要ID了,它们只需要一个名字,ID会由游戏自动分配,现在你依然可以手动指定,但将来会彻底取消手动分配ID.
Block类的构造函数不再对外部可见了,即你不能再new Block()了.
Block类的大部分方法和字段仍未反混淆...
Item类的构造函数不再需要参数.
Item需要被GameRegistry的registerItem注册后才能起作用.
GameRegistry的registerBlock和registerItem必须在预初始化阶段(FMLPreInitialization)进行!
LanguageRegistry已经不建议使用了,事实上现在它有Bug...使用它录入的文本进游戏后需要重选一遍语言才能生效.现在直接在资源文件目录下的assets.[mod名].lang中加入一个UTF8格式的en_US.lang文件,然后在里面写上文本.砖块的格式为tile.[砖块的unlocalizedName].name=[砖块名],物品的格式为item.[物品的unlocalizedName].name=[物品名]
IconRegister更名为IIconRegister了.

gradlewN2

gradlewN3

关于各种func_xxx和field_xxx的含义,你可以在这个帖子http://www.minecraftforge.net/forum/index.php?topic=15275.0中查询到其中一部分,或者咨询MCP组的MCPBot http://mcpold.ocean-labs.de/index.php/MCPBot

其他一些变动

Potion类的setIconIndex的访问级变成protected了.
想向玩家屏幕上显示文本可没有addChatMessage这种简单的东西了,你需要func_145747_a.
还有很多,但懒得写了 > <

最后再顺便说一下Gradle(本来打算单独写一篇文章...后来感觉东西太jb少了,干脆就和这篇合一块了)

因为MCP组团灭了,现在FML使用Gradle作为构建工具,Gradle的优点之前已经说了,功能比Ant丰富,操作比Maven简单,还能使用Maven的中央版本库来下载所需的代码库.但缺点嘛...人气太低,在此之前我甚至都没听说过Gradle...好吧这个算缺点吗...

之前我们一直都是用控制台操作Gradle,现在我们切换到界面模式下,先打开命令窗口,执行:

gradlew.bat --gui

然后便打开界面模式了.

gradlewN4

界面模式有4个分页,分别是Task Tree(任务列表),Favorites(收藏的指令),Command Line(执行指令)和Setup(Gradle配置).默认界面在Command Line页,它可以执行任意指令,指令的格式是:

[附加选项] [要执行的任务]

这两部分可以互相颠倒,像我们在基础篇中执行的eclipse指令,它其实就是一个无附加选项的"执行eclipse任务".--gui则是要求打开一个图形界面,不要求执行任务(但实际上这里是个特例,它会自动执行tasks任务,即刷新并显示所有可用的任务)

想要发布Mod的话,执行build任务就可以了,但在此之前我们要修改一下配置,要求编译时使用UTF-8编码,用文本编辑器打开build.gradle,在最下面加入:

tasks.withType(Compile) {
options.encoding = 'UTF-8'
}

这样就能在编译时使用UTF-8编码了,同时你还可以修改archivesBaseName,version和group这几项来修改构建完后打包好的jar的名字.

如果你在执行build任务时遇到了错误的话,可以尝试按照如下步骤来解决:

  1. 资源文件中不能有包含非Ascii码的文件/文件夹名,换句话说,文件/文件夹名中不要带中文,我觉得可能是Gradle的打包有bug(没人气的小项目就是这么尿...),会把用ANSI编码写名字的文件打包错...
  2. 还没解决?运行一下clean任务.
  3. 还没解决?用文本编辑器打开build.gradle,在最下面加入:
    reobf { deobfFile = new net.minecraftforge.gradle.delayed.DelayedFile(project, "build/tmp/deobfBinJar/deobfed.jar") }
  4. 还没解决?执行"cleancache --refresh-dependencies".
  5. 还没解决?留言吧!
    虽然我也不一定能解决...

成功构建后,构建完毕的jar位于build/libs目录下.

关于Gradle的就只有这些了...想了解更多的话,就看Gradle的手册然后学习Groovy与DSL吧...

再顺便提一下关于ForgeGradle的3种开发环境配置方式,我上论坛发了个帖子,巨巨是这样回答我的:
setupDevWorkspace只准备开发环境而不生成MC源码
setupDecompWorkspace即准备开发环境也生成MC源码
setupCIWorkspace是供诸如Jenkins之类的持续集成系统使用的(苣蒻表示不会用Jenkins...)