配置文件

两个 .cfg 文件、4 个配置项,全部由 MrTJPCore 的 ModConfig 基类读写(该基类不在本仓库)。ForgeRelocation 与 MCFrames 各一个。

文件名的确定方式

ModConfig 基类(MrTJPCore src/main/scala/mrtjp/core/data/configurations.scala:79-85):

def getFileName = modID

def loadConfig() {
  config = new Configuration(new File(Loader.instance.getConfigDir, getFileName + ".cfg"))
  initValues()
  if (config.hasChanged) config.save()
  ...
}

文件名 = 传入 ModConfig 构造器的字符串 + .cfg,落在 Loader.instance.getConfigDir(即 config/)。构造实参分别是:

声明 生成的配置文件
object RelocationConfig extends ModConfig("ForgeRelocation")(handler/mod.scala:66) config/ForgeRelocation.cfg
object MCFramesConfig extends ModConfig("MCFrames")(mcframes/handler/mod.scala:63) config/MCFrames.cfg

两个 mod 都有配置 GUI 入口:RelocationConfigGui / GuiConfigFactory(@Mod(guiFactory = "mrtjp.relocation.handler.GuiConfigFactory"))与 MCFramesConfigGui / GuiConfigFactory(@Mod(guiFactory = "mrtjp.mcframes.handler.GuiConfigFactory"))——两个类简单名都是 GuiConfigFactory,但位于不同包。两者都继承 MrTJPCore 的 SpecialConfigGui 与 TModGuiFactory。

config/ForgeRelocation.cfg 全表

段(category) 键 类型 默认值 注释原文
General moveLimit Integer 2048 Maximum amount of blocks that can be moved at once.
Tile Movers mover registry String 列表 ["default -> saveload"] 见下方动态描述

moveLimit

var moveLimit = 2048

val general = new BaseCategory("General", "Basic settings")
moveLimit = general.put("moveLimit", moveLimit, "Maximum amount of blocks that can be moved at once.")
  • 类型:Integer(put[T] 按值类型推断 Property.Type.INTEGER)
  • 默认值:2048
  • 段注释:Basic settings
  • 唯一消费点:tryStartMove 的首行 if (blocks.size > RelocationConfig.moveLimit) return false——超出即整次移动失败。这是唯一的容量上限,不区分方块种类

mover registry

var moverMap = Array("default -> saveload")

val movers = new BaseCategory("Tile Movers", buildMoverDesc)
moverMap = movers.put("mover registry", moverMap)
moverMap = movers.put("mover registry", MovingTileRegistry.parseAndSetMovers(moverMap), true)
  • 类型:String 列表(Array[String] → Property.Type.STRING,读写走 getStringList)
  • 默认值:单条 default -> saveload
  • 同一个键被连续 put 两次,第二次带 force = true。BaseCategory.put 的实现是 if (force || !cat.containsKey(key)) cat.put(key, prop),因此第二次会用第一次读回的值重写配置项——即把配置文件归一化成 parseAndSetMovers 返回的规范形式("key -> value" 字符串、含所有 mod 软绑定、值已按 ListMap 顺序排列)。所以这个文件每次加载后都会被重写。

⚠️ 副作用:玩家在文件里加的空行、注释顺序、ListMap 之外的自定义顺序都会被覆盖;值本身(哪些 key 绑哪个 mover)会被保留。

段注释 buildMoverDesc

Tile Movers 段的注释是运行时拼出来的(handler/mod.scala:90-113),原文如下:

Used to configure which registered Tile Mover is used for a block. Key-Value pairs are defined using
the syntax key -> value.
Most blocks are configurable, but some mods may have opted to lock which handlers can be used for its
blocks.
Possible keys:
    'default' - to assign default handler.
    'mod:<modID>' - to assign every block from a mod.
    '<modID>:<blockname>' - to assign block from a mod for every meta.
    '<modID>:<blockname>m<meta>' - to assign block from mod for specific meta.

Available tile movers:
    'saveload' - Saves the tile and then reloads it in the next position. Reliable but CPU intensive.
    'coordpush' - Physically changes the location of tiles. Works if tiles do not cache their position.
    'static' - Setting this disables movement for the specified block.

Movers locked via API:
    <key> -> <value>       (仅当有 mod 调用过 registerMandatoryMover 才出现)

“Available tile movers” 一节由 MovingTileRegistry.moverDescMap 动态遍历生成——其他 mod 通过 API 注册的新搬运器会自动出现在配置注释里。“Movers locked via API” 一节遍历 MovingTileRegistry.mandatoryMovers,ForgeRelocation 自己不注册任何 mandatory mover(registerMandatoryMover 在本仓库内无调用点),所以这一节默认不存在。

键语法与查找优先级的完整规则见 方块搬运器注册表。

config/MCFrames.cfg 全表

段(category) 键 类型 默认值
Latched Sets latch registry String 列表 见下
var setMap = Array(
  "minecraft:bed -> minecraft:bed",
  "minecraft:wooden_door -> minecraft:wooden_door",
  "minecraft:iron_door -> minecraft:iron_door"
)

val sets = new BaseCategory("Latched Sets", buildLatchSetsDesc)
setMap = sets.put("latch registry", setMap)
setMap = sets.put("latch registry", StickRegistry.parseAndAddLatchSets(setMap), true)

三条默认值(全部自映射):

键 值 含义
minecraft:bed minecraft:bed 床的上半与下半一起动
minecraft:wooden_door minecraft:wooden_door 门的上下两格一起动
minecraft:iron_door minecraft:iron_door 铁门的上下两格一起动

这三条是唯一能让多方块化方块(床、门)被框架结构整体推动的配置;不配的话框架只会抓住其中一格。语义与判定的完整说明见 MCFrames 卡扣注册表。

段注释 buildLatchSetsDesc

mcframes/handler/mod.scala:80-90 原文:

Used to define which pairs of blocks will be stuck together.
Latched sets will always move in pairs, even if only one of them are actually connected to a block.
'block1 -> block2' means that if block1 is moved, any block2 connected to it will also move.
However, moving block2 does not move block1. To do that, you must also register block2 -> block1.
Sets are defined using the syntax of key -> value.
Possible keys and values:
    '<modID>:<blockname>' - to assign block from mod for every meta.
    '<modID>:<blockname>m<meta>' - to assign block from mod for specific meta.

注意本段注释里没有 default 与 mod:<modID> 两种键(StickRegistry.rMod 正则存在但 parseBlockMeta 只处理 rNameMetaM / rName),注释与实现的可用键集一致。

同样地第二次 put(..., true) 会把 latch registry 重写为归一化形式——parseAndAddLatchSets 用 Block.blockRegistry.getNameForObject(b) 把方块反查成注册名再拼成 name 或 name + m<数字>:

latchMap.map { kv =>
  val (b, i) = kv._1
  val e1 = Block.blockRegistry.getNameForObject(b) + (if (i != -1) s"m$i" else "")
  kv._2.map { k =>
    val (b2, i2) = k
    val e2 = Block.blockRegistry.getNameForObject(b2) + (if (i2 != -1) s"m$i2" else "")
    e1 + " -> " + e2
  }
}.flatten.toArray

⚠️ 该方法返回的是展开后的实际绑定集合,不是用户输入的原始行数——minecraft:bed -> minecraft:bed 只有一条,但 latchMap 里若被别处追加过更多目标,输出行数会增加。同时 addLatchSet 是只增不减的累加(latchMap += b1 -> (latchMap(b1) + b2)),配置里删掉一行不会从内存映射里移除(但因每次游戏启动重建 latchMap,实际无残留)。

生命周期

两个 mod 的 init 阶段都调 loadConfig():

@Mod.EventHandler def init(event: FMLInitializationEvent) {
  RelocationAPI_Impl.isPreInit = false
  RelocationConfig.loadConfig()
  RelocationProxy.init()
}

注意 RelocationAPI_Impl.isPreInit = false 先于 loadConfig() 执行——配置里的 parseAndSetMovers 内部只读 preferredMovers / mandatoryMovers,不调 API,故不受影响。

⚠️ 与仓库里其他 mod 常见的"配置读取与注册同处一个 try 块、异常连带注册失败"不同,本 mod 的 loadConfig() 没有 try/catch 包裹。配置写坏(rKeyVal 不匹配 → MatchError)会让初始化直接抛异常。

src/main/resources 完整清单

本 mod 不打包任何 .cfg(配置由 Forge 在运行时生成)。仓库里 src/main/resources 全部内容如下:

路径 类型 用途
src/main/resources/mcmod.info JSON 2 条 modList 条目(见下)
src/main/resources/fr_logo.png PNG 模组列表 logo
src/main/resources/assets/mcframes/obj/frame.obj OBJ 框架方块 的模型源,运行时解析
src/main/resources/assets/mcframes/textures/blocks/frame.png PNG 框架贴图(图标键 mcframes:frame)
src/main/resources/assets/mcframes/textures/blocks/motor/side.png PNG 马达侧面
src/main/resources/assets/mcframes/textures/blocks/motor/bottom.png PNG 马达底面
src/main/resources/assets/mcframes/textures/blocks/motor/sidee.png PNG 马达侧面(东)
src/main/resources/assets/mcframes/textures/blocks/motor/top.png PNG 马达顶面
src/main/resources/assets/mcframes/textures/blocks/motor/sidew.png PNG 马达侧面(西)
src/main/resources/assets/mcframes/lang/en_US.lang properties 全 jar 唯一的语言文件

⚠️ 三点值得注意:

  1. 没有 zh_CN.lang——中文环境下所有方块名显示英文原文。
  2. 没有 assets/relocation/ 目录——ForgeRelocation 自己的方块(移动占位方块)的语言键 tile.relocation.blockmovingrow.name=Moving Block 被写在了 MCFrames 的 en_US.lang 里。
  3. 没有 META-INF/ 目录——因此既无 core mod 描述文件,也无 Access Transformer(见 ASM 核心 mod)。

en_US.lang 全部 5 行

tile.relocation.blockmovingrow.name=Moving Block
tile.mcframes.frame.name=Frame
tile.mcframes.motor.name=Debug Frame Motor
tile.mcframes.motor|0.name=Debug Frame Motor

马达的两条键分别是"无 metadata 形式"与 meta = 0 形式,文本相同,均为 “Debug Frame Motor”(调试用马达)。

mcmod.info 的两条条目

"modListVersion": 2,
"modList": [
  { "modid": "${modId}", "name": "${modName}",
    "description": "Move blocks from one place to another",
    "version": "${modVersion}", "mcversion": "${minecraftVersion}",
    "authorList": ["MrTJP"], "url": "", "updateUrl": "",
    "credits": "", "logoFile": "", "screenshots": [], "parent": "" },
  { "modid": "MCFrames", "name": "MCFrames", "description": "",
    "version": "${modVersion}", "mcversion": "${minecraftVersion}",
    "authorList": ["MrTJP"], "logoFile": "fr_logo.png", ... }
]

第一条用 Gradle token 占位(gradle.properties 里 modId = ForgeRelocation、modName = ForgeRelocation),第二条 MCFrames 的 id/name 硬编码。只有第一条有 description(“Move blocks from one place to another”),MCFrames 条目的 description 是空字符串。

相关条目