数据、设置与本地化
本页介绍 Copper 模组如何读写数据文件、创建设置项、访问资源与做多语言本地化。
主类继承自原版 Mod,直接使用 getConfigFolder() 与 getConfig():
public class ExampleMod extends CopperMod { @Override public void init() { // 配置文件夹 Fi folder = getConfigFolder(); // config.json 文件句柄 Fi config = getConfig(); Log.info("config: " + config.file().getAbsolutePath()); }}Copper 模组的配置文件夹位于 <数据目录>/copper/datas/<作者-模组名>/(与 id 对应,冒号换连字符),与原版模组不同(见主类与生命周期 · 配置文件夹的差异)。
推荐使用 copper.core.Copper.createSettings() 创建绑定到模组数据目录的 Settings 实例:
import arc.Settings;import copper.core.Copper;
public class ExampleMod extends CopperMod { @Override public void init() { Settings settings = Copper.createSettings(ExampleMod.class); settings.put("myOption", true); Log.info("myOption = " + settings.getBool("myOption")); }}- 设置文件位于模组数据目录(
<数据目录>/copper/datas/<作者-模组名>/); - 每个模组使用独立的设置实例,互不干扰;
- 修改即保存:
put()、remove()、clear()会立即把设置写回文件,不需要手动保存; - 底层使用
CopperSettings(Settings子类):它跳过了 Mindustry v146 中一次性的全局按键绑定重载,避免模组设置污染游戏全局按键数据。你无需关心,直接使用即可。
游戏内设置页面
Section titled “游戏内设置页面”模组的设置项可以直接显示在游戏的设置菜单里,不需要自己写弹窗。
用原版 API 注册分类即可,Copper 会自动识别它属于哪个模组:
import arc.*;import copper.core.*;import copper.core.mod.*;import copper.core.util.*;import mindustry.Vars;import mindustry.ui.*;
public class ExampleMod extends CopperMod { public static Settings settings; public static I18NBundle bundles;
public ExampleMod() { settings = Copper.createSettings(ExampleMod.class); bundles = Copper.createBundle(ExampleMod.class); }
@Override public void init() { Vars.ui.settings.addCategory(bundles.get("settings.category"), Icon.settings, t -> { CopperSettingsTable st = new CopperSettingsTable(settings, bundles); st.checkPref("myOption", true); st.sliderPref("myNumber", 50, 0, 100, 5, i -> i + "%"); t.add(st).grow(); }); }}- 分类名用自己的 bundle 取本地化文本(
bundles.get("settings.category"))。Copper 模组的 bundle 是独立实例、没有注册进游戏,因此这里不能像原版那样写@键名,要自己把文本取出来; - 用
CopperSettingsTable取代原版的SettingsTable:原版表格的读写走游戏的全局Settings,而CopperSettingsTable绑定到你传入的Settings实例与 bundle(见上文); - 把它
add进传入的t即可——t是游戏自己创建的普通表格,只作为容器使用。
设置项与文案
Section titled “设置项与文案”CopperSettingsTable 提供与原版一致的一组方法:
| 方法 | 说明 |
|---|---|
checkPref(name, def) / checkPref(name, def, changed) | 勾选项,可选变更回调 |
sliderPref(name, def, min, max, format) / sliderPref(name, def, min, max, step, format) | 滑条,format 把数值转成显示文本 |
textPref(name, def) / textPref(name, def, changed) | 单行文本 |
areaTextPref(name, def) / areaTextPref(name, def, changed) | 多行文本 |
pref(Setting) | 自定义条目:继承 CopperSettingsTable.Setting 并实现 add(table) |
条目的标题与说明同样从你传入的 bundle 读取,键的约定与原版一致:
settings.category = 示例模组
setting.myOption.name = 启用某功能setting.myOption.description = 鼠标悬停时显示的说明。setting.myNumber.name = 数值setting.<键名>.name:条目标题;Windows 上若存在setting.<键名>.name.windows则优先使用(与原版一致);setting.<键名>.description:可选,鼠标悬停提示;- 表格底部会自动附带一个 Reset to Defaults 按钮,点击后删除该表格所有条目的值、恢复默认。
两种资源位置
Section titled “两种资源位置”模组 Jar 内的 assets/ 目录会被挂载为原版 LoadedMod 的资源根,也就是说,游戏按原版方式加载的资源都从这里找。而 Copper 自己使用的资源约定放在 assets/copper/ 下,两者互不干扰:
| 位置 | 用途 |
|---|---|
assets/ | 原版模组资源:bundles/、sprites/、content/、maps/ 等,由游戏按原版规则加载 |
assets/copper/ | Copper 侧资源:例如 Mixin 配置 assets/copper/mixins/、Copper bundle assets/copper/bundles/,由加载器按 Copper 约定读取 |
构建时由 resources.srcDirs = ["res"] 把 res/ 目录内容打进 Jar,因此源目录布局为 res/assets/...。
import arc.files.Fi;import copper.core.Copper;
// assets 文件夹Fi assets = Copper.getModAssetFolder(ExampleMod.class);// assets/foo/bar.pngFi file = Copper.getModAsset(ExampleMod.class, "foo/bar.png");// 模组根目录下的任意文件Fi root = Copper.getModRoot(ExampleMod.class);- 模组目录内非 assets 的文件用
Copper.getModFile(clazz, path)访问; - 图片等资源按原版规则注册到 Atlas(sprite 名前缀为
copper-<作者-模组名>-,与游戏内注册的模组名一致;命名细节与例外见命名与映射 · 贴图文件名)。
多语言本地化
Section titled “多语言本地化”Copper 提供与 arc 的 I18NBundle 结合的工具方法。约定资源布局(Copper 自己的 bundle,位于 assets/copper/bundles/):
文件夹res/
文件夹assets/
文件夹copper/
文件夹bundles/
- bundle.properties — 默认语言
- bundle_zh_CN.properties — 简体中文
创建 bundle
Section titled “创建 bundle”import arc.util.I18NBundle;import copper.core.Copper;
public class ExampleMod extends CopperMod { public static I18NBundle bundles;
public ExampleMod() { bundles = Copper.createBundle(ExampleMod.class); }}Copper.createBundle(clazz)从assets/copper/bundles/bundle读取,并按系统语言自动选择语言文件;- 建议把 bundle 存为静态字段,在主类构造器中创建。
翻译模组元数据
Section titled “翻译模组元数据”Copper.translateModMeta(clazz, bundle) 会用 bundle 翻译模组的 name、author、description、subtitle,并同步到原版模组注册表:
public class ExampleMod extends CopperMod { public static I18NBundle bundles;
public ExampleMod() { bundles = Copper.createBundle(ExampleMod.class); Copper.translateModMeta(ExampleMod.class, bundles); }}bundle 中约定使用的键:
mod.name = Example Modmod.author = Examplemod.description = A Copper example mod.subtitle = My Subtitle文件目录速查
Section titled “文件目录速查”| 用途 | 路径 |
|---|---|
| 加载器数据目录 | <数据目录>/copper |
| Copper 模组文件夹 | <数据目录>/copper/mods |
| Copper 模组数据目录 | <数据目录>/copper/datas |
| 单个模组的配置/设置目录 | <数据目录>/copper/datas/<作者-模组名> |
| 原生库(自动解压) | <数据目录>/copper/lib |
copper.core.Copper 提供对应访问方法(见主类与生命周期 · 模组上下文工具类)。