This commit is contained in:
1820982382
2026-08-18 22:23:25 +08:00
parent 2c1aabe78a
commit 429d21a72f
8 changed files with 798 additions and 163 deletions
+206 -62
View File
@@ -2,11 +2,21 @@
> **中文** | [English](README_EN.md)
将 **神秘时代4(Thaumcraft 4 移植版)** 的配方系统桥接到 **KubeJS**,让整合包作者/服务器管理员
可以在 KubeJS 脚本中直接注册 TC 的注魔、炼金、奥术合成配方以及物品固有要素,并支持**替换原有配方**。
将 **神秘时代4(Thaumcraft 4 移植版)** 的配方与研究系统桥接到 **KubeJS**。
整合包作者可以通过 `kubejs/server_scripts/` 下的 KubeJS 脚本直接注册:
- 注魔配方
- 坩埚炼金配方
- 奥术有序 / 无序合成配方
- 物品固有要素
- 自定义研究分类 / 研究节点
- 替换 TC 原有配方
作者:AlkSur | 许可证:GPL-3.0
---
## 依赖
| Mod | 版本 | 关系 |
@@ -16,43 +26,59 @@
| Thaumcraft (TC4 移植版) | 0.2.2.34-port.1 | 必需 |
| KubeJS (NeoForge) | 2101.7.x | 必需(插件依赖其 API) |
> 本 mod 与 KubeJS 为**可选依赖关系**(mods.toml 中 `kubejs` 标记为 optional):
> 未安装 KubeJS 时本 mod 不加载插件部分,不影响游戏启动。
> KubeJS 在 `neoforge.mods.toml` 中声明为 **optional**:
> 未安装 KubeJS 时本 mod 不会加载插件部分,不影响游戏启动。
## 构建
---
工程位于 `modules/tc-kubejs-bridge`,属多 module Gradle 工程:
## 构建与安装
工程位于 `modules/tc-kubejs-bridge`,属于多 module Gradle 工程。
```bash
# 在仓库根目录执行
gradle :tckubejsbridge:build
```
产物:`modules/tc-kubejs-bridge/build/libs/KubeJS Thaumcraft-<mod_version>+<neoforge_version>.jar`
(例:`KubeJS Thaumcraft-1.0.0+21.1.234.jar`)
构建产物:
编译依赖(本地 jar,路径在 `build.gradle` 中可改):
- KubeJS:`F:/downloads/kubejs-neoforge-2101.7.2-build.368.jar`
- Rhino:`F:/downloads/rhino-2101.2.7-build.81.jar`(KubeJS 的脚本引擎)
- Thaumcraft:`modules/thaumicenergistics-neo/library/thaumcraft-0.2.2.34-port.1.jar`
```text
modules/tc-kubejs-bridge/build/libs/KubeJS Thaumcraft-<mod_version>+<neoforge_version>.jar
```
> 若本地路径不同,请修改 `build.gradle` 中 `dependencies` 的 `files(...)` 路径。
例如:
## 脚本用法
```text
KubeJS Thaumcraft-1.0.0+21.1.234.jar
```
将脚本放入 `kubejs/server_scripts/`,然后**重启游戏或执行 `/reload` 生效**(见"注意事项"第 1 条)。
把 jar 放入 `mods/` 文件夹即可。
---
## 快速开始
1. 在 `kubejs/server_scripts/` 下新建一个 `.js` 文件。
2. 在脚本里使用 `ServerEvents.recipes(event => { ... })`。
3. 保存后执行 `/reload`,或重启游戏。
所有 `thaumcraft.xxx` 都是**顶层绑定**,不要写成 `event.thaumcraft.xxx`。
---
## 配方注册
### 1. 注魔配方
```js
ServerEvents.recipes(event => {
event.recipes.thaumcraft.infusion(
'MY_INFUSION', // research 键(全局唯一,用于魔导手册/去重)
'minecraft:diamond', // 输出
3, // 不稳定性
['ignis 64', 'potentia 32'],// 源质:要素 tag + 数量
'minecraft:golden_apple', // 中心物品
'minecraft:blaze_rod', // 祭品(可多个)
'MY_INFUSION', // research 键(全局唯一)
'minecraft:diamond', // 输出
3, // 不稳定性
['ignis 64', 'potentia 32'], // 所需源质
'minecraft:golden_apple', // 中心物品
'minecraft:blaze_rod', // 祭品
'minecraft:ender_pearl'
);
});
@@ -65,8 +91,8 @@ ServerEvents.recipes(event => {
event.recipes.thaumcraft.crucible(
'MY_CRUCIBLE',
'minecraft:diamond',
'minecraft:coal', // 催化剂
{ aer: 16, ignis: 8 } // 对象写法
'minecraft:coal', // 催化剂
{ aer: 16, ignis: 8 } // 对象写法
);
});
```
@@ -79,7 +105,7 @@ ServerEvents.recipes(event => {
'MY_ARCANE',
'minecraft:diamond_sword',
['ignis 16', 'ordo 8'],
[' I ', ' I ', ' S '], // pattern:最多 3 行
[' I ', ' I ', ' S '], // pattern:最多 3 行
{ I: 'minecraft:iron_ingot', S: 'minecraft:stick' }
);
});
@@ -87,37 +113,50 @@ ServerEvents.recipes(event => {
### 4. 奥术无序合成配方
> 注意:`arcane_shapeless` 的材料必须放在**一个数组**里。
```js
ServerEvents.recipes(event => {
event.recipes.thaumcraft.arcane_shapeless(
'MY_SHAPELESS',
'minecraft:diamond_helmet',
['aer 8', 'aqua 8'],
'minecraft:leather_helmet',
'minecraft:diamond',
'minecraft:diamond',
'minecraft:diamond'
[
'minecraft:leather_helmet',
'minecraft:diamond',
'minecraft:diamond',
'minecraft:diamond'
]
);
});
```
### 5. 物品固有要素
---
## 物品固有要素
```js
ServerEvents.recipes(event => {
event.thaumcraft.addObjectTag('minecraft:stick', { aer: 1, ignis: 2 });
// 添加
thaumcraft.addObjectTag('minecraft:stick', { aer: 1, ignis: 2 });
// 移除
thaumcraft.removeObjectTag('minecraft:stick');
});
```
### 6. 替换(先删后注册)已有配方
---
## 替换已有配方
```js
ServerEvents.recipes(event => {
// 注意:thaumcraft 是顶层绑定,不是 event.thaumcraft
thaumcraft.removeInfusion('INFUSIONPROVIDER'); // 按 research 键删除 TC 注魔配方
// thaumcraft.removeArcane('RESEARCH_KEY'); // 按 research 键删除奥术配方
// 先删
thaumcraft.removeInfusion('INFUSIONPROVIDER'); // 注魔
// thaumcraft.removeArcane('RESEARCH_KEY'); // 奥术
// thaumcraft.removeCrucible('RESEARCH_KEY'); // 坩埚
// 然后注册新配方,实现真正替换
// 后注册,实现真正替换
event.recipes.thaumcraft.infusion(
'INFUSIONPROVIDER',
'thaumicenergistics:infusion_provider',
@@ -129,6 +168,96 @@ ServerEvents.recipes(event => {
});
```
---
## 自定义研究分类 / 研究节点
### 添加研究分类
```js
ServerEvents.recipes(event => {
thaumcraft.addResearchCategory(
'MY_CATEGORY',
'textures/research/cat_icon.png',
'textures/research/cat_bg.png'
);
});
```
- 两个参数也可以:`addResearchCategory('MY_CATEGORY', 'textures/research/cat_icon.png')`
- 不带命名空间的路径默认使用 `kubejs:` 命名空间。
### 添加研究节点
```js
ServerEvents.recipes(event => {
thaumcraft.addResearchNode({
key: 'MY_RESEARCH',
category: 'MY_CATEGORY',
icon: 'textures/research/my_research.png',
parents: ['PARENT_KEY'],
autoUnlock: true, // 默认解锁
virtual: false, // 显示在魔导手册中;true 会隐藏
hidden: false,
col: 0,
row: 0,
complexity: 1,
aspects: { aer: 1, ignis: 1 }
});
});
```
支持字段:
| 字段 | 说明 |
|---|---|
| `key` | 研究节点唯一 ID |
| `category` | 所属研究分类,必须已存在 |
| `icon` | 图标路径 |
| `parents` / `parentsHidden` / `siblings` | 研究依赖关系 |
| `autoUnlock` | 是否默认解锁 |
| `virtual` | 是否虚拟节点(`true` 不会显示在魔导手册) |
| `hidden` / `concealed` / `lost` | 可见性控制 |
| `special` / `stub` / `secondary` / `round` | 研究类型标记 |
| `col` / `row` / `complexity` | 研究树位置和复杂度 |
| `aspects` | 研究关联要素 |
### 图标文件位置
脚本里写:
```js
icon: 'textures/research/my_research.png'
```
对应文件:
```text
kubejs/assets/kubejs/textures/research/my_research.png
```
也可以写完整路径:
```js
icon: 'kubejs:textures/research/my_research.png'
```
### 研究名称 / 描述
TC 的研究名称通过语言文件翻译。
在 `kubejs/assets/kubejs/lang/zh_cn.json` 中添加:
```json
{
"tc.research_category.MY_CATEGORY": "我的分类",
"tc.research_name.MY_RESEARCH": "我的研究",
"tc.research_text.MY_RESEARCH": "这是研究描述。"
}
```
英文则写在 `kubejs/assets/kubejs/lang/en_us.json`。
---
## 要素 tag 参考(TC4 移植版实际值)
**注意:移植版的要素 tag 是拉丁文原名,不是 TC4 汉化/英文名。**
@@ -153,50 +282,65 @@ ServerEvents.recipes(event => {
| 贪婪 GREED | `lucrum` | 工艺 CRAFT | `fabrico` |
| 布料 CLOTH | `pannus` | 机制 MECHANISM | `machina` |
## 注意事项
## 热重载说明
1. **支持热重载**:改脚本后执行 `/reload` 即可生效,无需重启游戏。
- KubeJS 每次 `/reload` 都会重新执行 `ServerEvents.recipes`,脚本会再次运行。
- 若脚本使用"先删后注册"(`thaumcraft.removeInfusion(...)` 再 `infusion(...)`)写法,
删除步骤会清掉本 mod 的去重键并移除 TC 内存列表中的旧配方,因此新配方能正确重新注册。
- 纯新增(不先删)的脚本重复 `/reload` 会被去重拦截(`skipping`),请配合
`thaumcraft.clearRegistered()` 使用或在脚本开头调用它。
2. **research 键全局唯一**:重复键会被跳过(防止重复注册)。如需同名配方,请改键。
3. **配方不进原版 RecipeManager**:TC 注魔/炼金/奥术配方是 TC 自己的内存列表。
本桥接在脚本执行时直接调用 TC API 注册,并对 KubeJS 输出无害占位配方,
不影响其他 mod 的配方操作(schema 的 `typeOverride` 指向 `minecraft:crafting_shapeless` 以满足 KubeJS 的 serializer 查找)。
4. **源质列表两种写法**:数组 `['ignis 64']` 或对象 `{ignis: 64}` 均可。
5. **物品参数**:支持物品 id 字符串(`minecraft:xxx` / `ae2:xxx`)、`Item.of(...)`、物品 tag(`#minecraft:planks`)。
6. **AE2 物品命名空间是 `ae2`**:如 AE2 接口是 `ae2:interface`,不是 `appliedenergistics2:interface`。
7. **KubeJS 版本兼容**:桥接层基于 KubeJS 2101.7.x 的 RecipeSchema API(标注
`@ApiStatus.Experimental`),升级 KubeJS 小版本后如遇编译错误,可能需要同步调整。
| 内容 | `/reload` | 说明 |
|---|---|---|
| 注魔 / 坩埚 / 奥术配方 | ✅ | 可以热重载 |
| 物品固有要素 | ✅ | 可以热重载 |
| 研究分类 / 研究节点 | ❌ | TC 研究系统缓存较多,需要重启游戏 |
### research 键说明
- 如果 `research` 不是 TC 已有研究,桥接会自动注册一个**默认解锁的虚拟研究节点**,并按“无研究要求”处理。
- 如果 `research` 是 TC 已有研究,则仍然要求玩家完成对应研究。
- `research` 键全局唯一,重复键会被跳过。
## 排障
| 现象 | 原因 |
|---|---|
| 日志 `Serializer for type thaumcraft:infusion is not found` | 缺 `typeOverride`(已内置修复,重新构建即可) |
| 日志 `Unknown aspect 'xxx'` | 要素 tag 写错,对照上面要素表 |
| 日志 `Item with ID xxx does not exist` | 物品 id 错误,注意 `ae2:` 命名空间 |
| 日志无任何 `TC-KubeJS-Bridge` 输出 | mod 未装入 mods、或脚本未放入 `server_scripts` |
| 脚本报 `event.thaumcraft is undefined` | 顶层绑定用 `thaumcraft.xxx`,不要写 `event.thaumcraft.xxx` |
| `Constructor for thaumcraft:arcane_shapeless with N arguments not found` | 材料没有放在数组里 |
| `Unknown aspect 'xxx'` | 要素 tag 写错 |
| `Item with ID xxx does not exist` | 物品 id 错误 |
| 研究分类名字显示为 `tc.research_category.XXX` | 缺少语言文件 |
| 研究图标 / 背景紫黑色 | 贴图不存在、路径不对、不是 PNG,或 KubeJS assets 未被加载 |
| `event.thaumcraft is undefined` | 顶层绑定是 `thaumcraft.xxx`,不是 `event.thaumcraft.xxx` |
## 项目结构
```
```text
src/main/java/tckubejsbridge/
├── TCKubeJSBridge.java // @Mod 主类
└── kubejs/
├── TCKubeJSPlugin.java // KubeJS 插件:注册 schema + bindings
├── TCRecipeKJS.java // 自定义 KubeRecipe 基类(桥接 + 占位序列化)
├── TCRecipeBridge.java // TC API 调用 + 去重 + 移除 + 占位 JSON
├── AspectListComponent.java // 源质列表 RecipeComponent
├── TCKubeJSPlugin.java // KubeJS 插件:schema + bindings
├── TCRecipeKJS.java // 自定义 KubeRecipe 基类
├── TCRecipeBridge.java // TC API 调用 / 去重 / 移除 / 研究注册
├── AspectListComponent.java // 源质列表组件
├── InfusionRecipeKJS.java // 注魔配方
├── CrucibleRecipeKJS.java // 坩埚炼金配方
├── CrucibleRecipeKJS.java // 坩埚配方
├── ShapedArcaneRecipeKJS.java // 奥术有序配方
└── ShapelessArcaneRecipeKJS.java // 奥术无序配方
src/main/resources/
├── kubejs.plugins.txt // 插件发现文件
└── META-INF/neoforge.mods.toml
example/infusion_example.js // 示例脚本
```