Files
kubejs-thaumcraft/README_EN.md
T
2026-08-18 22:23:25 +08:00

356 lines
8.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TC KubeJS Bridge (tckubejsbridge)
> **English** | [中文](README.md)
Bridges the **Thaumcraft 4 (port)** recipe and research systems to **KubeJS**.
Modpack authors can use scripts in `kubejs/server_scripts/` to register:
- Infusion recipes
- Crucible recipes
- Shaped / shapeless arcane recipes
- Item aspect tags
- Custom research categories / research nodes
- Replacing existing TC recipes
Author: AlkSur | License: GPL-3.0
---
## Requirements
| Mod | Version | Relation |
|---|---|---|
| NeoForge | 21.1.234 | Required |
| Minecraft | 1.21.1 | Required |
| Thaumcraft (TC4 port) | 0.2.2.34-port.1 | Required |
| KubeJS (NeoForge) | 2101.7.x | Required (plugin depends on its API) |
> KubeJS is declared **optional** in `neoforge.mods.toml`: without KubeJS the plugin part
> simply does not load, and the game still starts.
---
## Building & Installation
The project lives at `modules/tc-kubejs-bridge` inside a multi-module Gradle build.
```bash
# Run from the repository root
gradle :tckubejsbridge:build
```
Artifact:
```text
modules/tc-kubejs-bridge/build/libs/KubeJS Thaumcraft-<mod_version>+<neoforge_version>.jar
```
For example:
```text
KubeJS Thaumcraft-1.0.0+21.1.234.jar
```
Put the jar into your `mods/` folder.
---
## Quick Start
1. Create a `.js` file under `kubejs/server_scripts/`.
2. Use `ServerEvents.recipes(event => { ... })`.
3. Run `/reload` or restart the game.
All `thaumcraft.xxx` calls are **top-level bindings**; do not use `event.thaumcraft.xxx`.
---
## Recipe Registration
### 1. Infusion Recipe
```js
ServerEvents.recipes(event => {
event.recipes.thaumcraft.infusion(
'MY_INFUSION', // research key (globally unique)
'minecraft:diamond', // result
3, // instability
['ignis 64', 'potentia 32'], // required aspects
'minecraft:golden_apple', // central item
'minecraft:blaze_rod', // component
'minecraft:ender_pearl'
);
});
```
### 2. Crucible Recipe
```js
ServerEvents.recipes(event => {
event.recipes.thaumcraft.crucible(
'MY_CRUCIBLE',
'minecraft:diamond',
'minecraft:coal', // catalyst
{ aer: 16, ignis: 8 } // object syntax also works
);
});
```
### 3. Shaped Arcane Recipe
```js
ServerEvents.recipes(event => {
event.recipes.thaumcraft.arcane(
'MY_ARCANE',
'minecraft:diamond_sword',
['ignis 16', 'ordo 8'],
[' I ', ' I ', ' S '], // pattern: up to 3 rows
{ I: 'minecraft:iron_ingot', S: 'minecraft:stick' }
);
});
```
### 4. Shapeless Arcane Recipe
> Note: `arcane_shapeless` ingredients must be provided as **one array**.
```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'
]
);
});
```
---
## Item Aspect Tags
```js
ServerEvents.recipes(event => {
// add
thaumcraft.addObjectTag('minecraft:stick', { aer: 1, ignis: 2 });
// remove
thaumcraft.removeObjectTag('minecraft:stick');
});
```
---
## Replacing Existing Recipes
```js
ServerEvents.recipes(event => {
// remove first
thaumcraft.removeInfusion('INFUSIONPROVIDER'); // infusion
// thaumcraft.removeArcane('RESEARCH_KEY'); // arcane
// thaumcraft.removeCrucible('RESEARCH_KEY'); // crucible
// then register a new recipe
event.recipes.thaumcraft.infusion(
'INFUSIONPROVIDER',
'thaumicenergistics:infusion_provider',
0,
['auram 10'],
'ae2:interface',
'minecraft:oak_planks'
);
});
```
---
## Custom Research Categories / Nodes
### Add a Research Category
```js
ServerEvents.recipes(event => {
thaumcraft.addResearchCategory(
'MY_CATEGORY',
'textures/research/cat_icon.png',
'textures/research/cat_bg.png'
);
});
```
- A two-argument form is also available: `addResearchCategory('MY_CATEGORY', 'textures/research/cat_icon.png')`
- Paths without a namespace default to the `kubejs:` namespace.
### Add a Research Node
```js
ServerEvents.recipes(event => {
thaumcraft.addResearchNode({
key: 'MY_RESEARCH',
category: 'MY_CATEGORY',
icon: 'textures/research/my_research.png',
parents: ['PARENT_KEY'],
autoUnlock: true, // unlocked by default
virtual: false, // visible in the Thaumonomicon; true hides it
hidden: false,
col: 0,
row: 0,
complexity: 1,
aspects: { aer: 1, ignis: 1 }
});
});
```
Supported fields:
| Field | Description |
|---|---|
| `key` | Unique research node ID |
| `category` | Existing research category |
| `icon` | Icon path |
| `parents` / `parentsHidden` / `siblings` | Research dependencies |
| `autoUnlock` | Unlocked by default |
| `virtual` | Hidden from the Thaumonomicon when `true` |
| `hidden` / `concealed` / `lost` | Visibility flags |
| `special` / `stub` / `secondary` / `round` | Research type flags |
| `col` / `row` / `complexity` | Position and complexity on the research map |
| `aspects` | Associated aspects |
### Icon File Location
If you write:
```js
icon: 'textures/research/my_research.png'
```
The file should be at:
```text
kubejs/assets/kubejs/textures/research/my_research.png
```
You can also use a full path:
```js
icon: 'kubejs:textures/research/my_research.png'
```
### Research Names / Descriptions
TC research names use language files.
Add this to `kubejs/assets/kubejs/lang/en_us.json`:
```json
{
"tc.research_category.MY_CATEGORY": "My Category",
"tc.research_name.MY_RESEARCH": "My Research",
"tc.research_text.MY_RESEARCH": "This is a research description."
}
```
For Chinese, add the same keys to `kubejs/assets/kubejs/lang/zh_cn.json`.
---
## Aspect Tag Reference (actual values in the TC4 port)
**Important: the port uses the original Latin tags, not the TC4 English/localized names.**
| Aspect | Tag | Aspect | Tag |
|---|---|---|---|
| Air | `aer` | Earth | `terra` |
| Fire | `ignis` | Water | `aqua` |
| Order | `ordo` | Entropy | `perditio` |
| Void | `vacuos` | Light | `lux` |
| Weather | `tempestas` | Motion | `motus` |
| Crystal | `vitreus` | Life | `victus` |
| Energy | `potentia` | Exchange | `permutatio` |
| Death | `mortuus` | Darkness | `tenebrae` |
| Soul | `spiritus` | Eldritch | `alienis` |
| Magic | `praecantatio` | Aura | `auram` |
| Slime | `limus` | Plant | `herba` |
| Tree | `arbor` | Beast | `bestia` |
| Flesh | `corpus` | Undead | `exanimis` |
| Mind | `cognitio` | Senses | `sensus` |
| Man | `humanus` | Tool | `instrumentum` |
| Greed | `lucrum` | Craft | `fabrico` |
| Cloth | `pannus` | Mechanism | `machina` |
## Hot Reload
| Content | `/reload` | Notes |
|---|---|---|
| Infusion / Crucible / Arcane recipes | ✅ | Can be hot-reloaded |
| Item aspect tags | ✅ | Can be hot-reloaded |
| Research categories / nodes | ❌ | Requires a game restart |
### Research key notes
- If `research` is **not** an existing TC research, the bridge registers a default-unlocked virtual research node and treats the recipe as having **no research requirement**.
- If `research` **is** an existing TC research, the recipe still requires that research to be completed.
- Research keys are globally unique; duplicate keys are skipped.
## Troubleshooting
| Symptom | Cause |
|---|---|
| `Constructor for thaumcraft:arcane_shapeless with N arguments not found` | Ingredients were not placed in an array |
| `Unknown aspect 'xxx'` | Wrong aspect tag |
| `Item with ID xxx does not exist` | Wrong item id |
| Research category name shows `tc.research_category.XXX` | Missing language file |
| Research icon / background is purple-black | Texture missing, wrong path, not a PNG, or KubeJS assets not loaded |
| `event.thaumcraft is undefined` | Use top-level `thaumcraft.xxx`, not `event.thaumcraft.xxx` |
## Project Layout
```text
src/main/java/tckubejsbridge/
├── TCKubeJSBridge.java // @Mod main class
└── kubejs/
├── TCKubeJSPlugin.java // KubeJS plugin: schemas + bindings
├── TCRecipeKJS.java // Custom KubeRecipe base
├── TCRecipeBridge.java // TC API calls / dedup / removal / research registration
├── AspectListComponent.java // Aspect list component
├── InfusionRecipeKJS.java // Infusion recipe
├── CrucibleRecipeKJS.java // Crucible recipe
├── ShapedArcaneRecipeKJS.java // Shaped arcane recipe
└── ShapelessArcaneRecipeKJS.java // Shapeless arcane recipe
src/main/resources/
├── kubejs.plugins.txt // Plugin discovery file
└── META-INF/neoforge.mods.toml
example/infusion_example.js // Example script
```