208 lines
7.6 KiB
Markdown
208 lines
7.6 KiB
Markdown
# TC KubeJS Bridge (tckubejsbridge)
|
||
|
||
Bridges the **Thaumcraft 4 (port)** recipe system to **KubeJS**, allowing modpack authors and
|
||
server admins to register TC infusion, crucible, arcane crafting recipes and item aspect tags
|
||
directly from KubeJS scripts — including **replacing existing 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
|
||
|
||
The project lives at `modules/tc-kubejs-bridge` inside a multi-module Gradle build:
|
||
|
||
```bash
|
||
# Run from the repository root
|
||
gradle :tckubejsbridge:build
|
||
```
|
||
|
||
Artifact: `modules/tc-kubejs-bridge/build/libs/KubeJS Thaumcraft-<mod_version>+<neoforge_version>.jar`
|
||
(e.g. `KubeJS Thaumcraft-1.0.0+21.1.234.jar`)
|
||
|
||
Compile dependencies (local jars, paths editable in `build.gradle`):
|
||
- KubeJS: `F:/downloads/kubejs-neoforge-2101.7.2-build.368.jar`
|
||
- Rhino: `F:/downloads/rhino-2101.2.7-build.81.jar` (KubeJS script engine)
|
||
- Thaumcraft: `modules/thaumicenergistics-neo/library/thaumcraft-0.2.2.34-port.1.jar`
|
||
|
||
> Adjust the `files(...)` paths in the `dependencies` block if your local layout differs.
|
||
|
||
## Script Usage
|
||
|
||
Put scripts into `kubejs/server_scripts/` and **restart the game** (see Note #1).
|
||
|
||
### 1. Infusion Recipe
|
||
|
||
```js
|
||
ServerEvents.recipes(event => {
|
||
event.recipes.thaumcraft.infusion(
|
||
'MY_INFUSION', // research key (globally unique; used by Thaumonomicon/dedup)
|
||
'minecraft:diamond', // result
|
||
3, // instability
|
||
['ignis 64', 'potentia 32'],// aspects: aspect tag + amount
|
||
'minecraft:golden_apple', // central item
|
||
'minecraft:blaze_rod', // components (one or more)
|
||
'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
|
||
|
||
```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'
|
||
);
|
||
});
|
||
```
|
||
|
||
### 5. Item Aspect Tags
|
||
|
||
```js
|
||
ServerEvents.recipes(event => {
|
||
event.thaumcraft.addObjectTag('minecraft:stick', { aer: 1, ignis: 2 });
|
||
});
|
||
```
|
||
|
||
### 6. Replacing an Existing Recipe (remove first, then register)
|
||
|
||
```js
|
||
ServerEvents.recipes(event => {
|
||
// NOTE: thaumcraft is a TOP-LEVEL binding, not event.thaumcraft
|
||
thaumcraft.removeInfusion('INFUSIONPROVIDER'); // remove TC infusion recipes by research key
|
||
// thaumcraft.removeArcane('RESEARCH_KEY'); // remove arcane recipes by research key
|
||
|
||
// then register the new recipe for a true replacement
|
||
event.recipes.thaumcraft.infusion(
|
||
'INFUSIONPROVIDER',
|
||
'thaumicenergistics:infusion_provider',
|
||
0,
|
||
['auram 10'],
|
||
'ae2:interface',
|
||
'minecraft:oak_planks'
|
||
);
|
||
});
|
||
```
|
||
|
||
## 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` |
|
||
|
||
## Notes
|
||
|
||
1. **Restart after editing scripts — `/reload` does NOT work**:
|
||
- TC recipes live in the `ThaumcraftApi.getCraftingRecipes()` in-memory list, which KubeJS
|
||
`/reload` never clears.
|
||
- This mod's dedup set (keyed by research) is also not cleared on `/reload`.
|
||
- If you need `/reload` support later, call `thaumcraft.clearRegistered()` in the script
|
||
to reset the dedup set.
|
||
2. **Research keys are globally unique**: duplicate keys are skipped (prevents double
|
||
registration). Use a different key for same-name recipes.
|
||
3. **Recipes do NOT go into the vanilla RecipeManager**: TC infusion/crucible/arcane recipes
|
||
live in TC's own in-memory list. The bridge calls the TC API directly during script
|
||
execution and emits a harmless placeholder recipe to KubeJS, so it does not affect other
|
||
mods' recipe operations. (The schema uses `typeOverride = minecraft:crafting_shapeless`
|
||
so KubeJS can find a serializer.)
|
||
4. **Aspect lists accept two syntaxes**: array `['ignis 64']` or object `{ignis: 64}`.
|
||
5. **Item arguments** accept: item id strings (`minecraft:xxx` / `ae2:xxx`), `Item.of(...)`,
|
||
and item tags (`#minecraft:planks`).
|
||
6. **AE2's namespace is `ae2`**: e.g. the AE2 interface is `ae2:interface`,
|
||
NOT `appliedenergistics2:interface`.
|
||
7. **KubeJS version compatibility**: the bridge is built on KubeJS 2101.7.x RecipeSchema API
|
||
(marked `@ApiStatus.Experimental`). Upgrading KubeJS to another patch version may require
|
||
adjustments to the bridge layer.
|
||
|
||
## Troubleshooting
|
||
|
||
| Symptom | Cause |
|
||
|---|---|
|
||
| Log shows `Serializer for type thaumcraft:infusion is not found` | Missing `typeOverride` (already fixed in code; rebuild) |
|
||
| Log shows `Unknown aspect 'xxx'` | Wrong aspect tag — check the aspect table above |
|
||
| Log shows `Item with ID xxx does not exist` | Wrong item id — remember the `ae2:` namespace |
|
||
| No `TC-KubeJS-Bridge` lines in the log at all | Mod not installed, or script not in `server_scripts` |
|
||
| Script reports `event.thaumcraft is undefined` | Use the top-level `thaumcraft.xxx`, not `event.thaumcraft.xxx` |
|
||
|
||
## Project Layout
|
||
|
||
```
|
||
src/main/java/tckubejsbridge/
|
||
├── TCKubeJSBridge.java // @Mod main class
|
||
└── kubejs/
|
||
├── TCKubeJSPlugin.java // KubeJS plugin: schemas + bindings
|
||
├── TCRecipeKJS.java // Custom KubeRecipe base (bridge + placeholder serialization)
|
||
├── TCRecipeBridge.java // TC API calls + dedup + removal + placeholder JSON
|
||
├── AspectListComponent.java // Aspect list RecipeComponent
|
||
├── 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
|
||
```
|