• Forge论坛

导航页

  • 主页
  • 向文档做出贡献
  • 入门
    • 概述
    • 模组文件
    • 规划你的模组结构
      • 程序包
      • 类的命名规则
      • 选择仅用一个方法而非多个
    • 版本号
  • 核心概念
    • 注册表
    • 端位(Sides)
    • 事件
    • 模组生命周期
    • 资源
    • 国际化与本地化
  • 方块
    • 概述
    • 方块状态
  • 物品
    • 概述
    • BlockEntityWithoutLevelRenderer
  • 网络
    • 概述
    • SimpleImpl
    • 实体的同步
  • 方块实体
    • 概述
    • BlockEntityRenderer
  • 游戏特效
    • 粒子效果
    • 音效
  • 数据储存
    • Capabilities
    • Saved Data
    • 编解码器(Codecs)
  • 图形用户界面
    • 菜单(Menus)
    • 屏幕(Screens)
  • 渲染
    • 模型扩展
      • 概述
      • 根变换
      • 渲染类型
      • 部分可见度
      • 面数据
    • 模型加载器
      • 概述
      • 烘焙模型
      • 变换
      • 物品重载
  • 资源
    • 客户端资源(Assets)
      • 概述
      • 模型
        • 概述
        • 纹理色调
        • 物品属性
    • 服务端数据(Data)
      • 概述
      • 配方
        • 概述
        • 自定义配方
        • 原料
        • 非数据包配方
      • 战利品表
      • 全局战利品修改器
      • 标签
      • 进度
      • 条件性加载数据
  • 数据生成
    • 概述
    • 客户端资源(Assets)
      • 模型提供者
      • 语言提供者
      • 音效提供者
    • 服务端数据(Data)
      • 配方提供者
      • 战利品表提供者
      • 标签提供者
      • 进度提供者
      • 全局战利品修改器提供者
      • 数据包注册表对象提供者
  • 杂项功能
    • 配置
    • 键盘布局
    • 游戏测试
    • Forge更新检查器
    • 调试分析器
  • 进阶主题
    • 访问转换器
  • 向Forge做出贡献
    • 概述
    • Pull Request准则
  • 旧版本
    • 概述
    • 移植到当前版本

规划你的模组结构

结构分明的模组有利于维护和做出贡献,并提供对底层代码库的更清晰理解。下面列举了由Java、Minecraft和Forge提出的一些建议。

注意

你不必遵循以下建议;你可以以任何你认为合适的方式规划你的模组。然而,我们仍强烈建议这样做。

程序包

在规划你的模组时,选择一个独特的、顶级的程序包结构。许多程序员会对不同的类、接口等使用相同的名称。Java允许类具有相同的名称,只要它们位于不同的包中。因此,如果两个类具有相同的名称和相同的包,则只有一个会被加载,这很可能导致游戏崩溃。

a.jar
  - com.example.ExampleClass
b.jar
  - com.example.ExampleClass // 这个类不会被正常加载

当涉及到加载模块时,这一点更为重要。如果在不同的模块中有两个同名包下的类文件,这将导致模组加载器在启动时崩溃,因为模组模块会被导出到游戏和其他模组中。

module A
  - package X
    - class I
    - class J
module B
  - package X // 此包将导致模组加载器崩溃,因为已经有一个模块将包X导出
    - class R
    - class S
    - class T

正因如此,你的顶级程序包应该是你自己的东西:域名、电子邮件地址、网站的子域等。它甚至可以是你的名字或用户名,只要你能保证它在预期目标中是唯一可识别的。

类型 值 顶级程序包
域名 example.com com.example
子域名 example.github.io io.github.example
电子邮箱地址 example@gmail.com com.gmail.example

下一个级别的包应该是你的mod id(例如com.example.examplemod,其中examplemod是mod id)。这将保证,除非你有两个id相同的模组(这种情况永远不会发生),否则你的包在加载时不会出现任何问题。

你可以在Oracle的教程页面上找到一些其他命名约定。

子包的组织

除了顶级包以外,强烈建议将你的模组的类拆分为不同的子包。关于如何做到这一点,主要有两种方法:

  • 按功能分组: 将具有共同目的的类归入同一个子包。例如,方块相关的类可被置于block或blocks子包下,实体相关的类可被置于entity或entities子包下等等。Mojang就在使用这种结构,单词用的是单数形式(block、entity)。
  • 按逻辑分组: 将具有共同逻辑的类归入同一个子包。例如,如果你正在创建一种新配方,你可以将它的方块、菜单、物品等等都放在feature.crafting_table子包下。

客户端、服务端和数据相关的子包

通常,仅用于给定端位或运行时的代码都应该在单独的子包中与其他类隔离。例如,与数据生成相关的代码应该放在data子包中,而仅与dedicated服务器相关的代码应该在server子包中。

然而,强烈建议在client子包中隔离仅限客户端的代码。这是因为dedicated服务器不应有任何权限访问Minecraft中仅限客户端的包。因此,拥有一个专用的包将提供一个不错的健全性检查,以保证你的模组中的代码没有越过端位的行为。

类的命名规则

一个普适的类命名方案可以让你更容易地读懂类的目的或查找某个特定的类。

类的名称通常以其类型作为后缀,例如:

  • 一个叫作PowerRing的Item -> PowerRingItem。
  • 一个叫作NotDirt的Block -> NotDirtBlock。
  • 为Oven设计的一个菜单 -> OvenMenu。

注意

Mojang通常对除实体以外的所有类命名时都遵循类似的结构。而实体只用它们的名字来表示(例如Pig、Zombie等)。

选择仅用一个方法而非多个

执行特定任务的方法有很多:注册对象、监听事件等。通常建议使用单一方法来完成给定的任务以保持一致。这在改善了代码格式的同时,也避免了可能发生的任何奇怪的交互或冗余(例如,你的事件监听器执行了两次)。

Built with MkDocs using a custom theme. Hosted by Read the Docs.
Enable Dark Theme