KubeJS Goety
KubeJS integration for Goety mod. Allows customizing Goety ritual requirements, brew system, and recipe system via JavaScript scripts.
Features
- ✅ Uses GoetyEvents event system
- ✅ Create and modify ritual types with fully customizable ritual condition checking logic
- ✅ Brew system configuration (capacity modifiers, catalysts, augmentations)
- ✅ Recipe system configuration (ritual recipes, brewing recipes, pulverize recipes, etc.)
- ✅ Server-side script support (server_scripts)
- ✅ No need to modify the Goety mod itself
Requirements
- Minecraft 1.20.1
- Forge 47.1.65+
- KubeJS 2001.6+
- Goety 2.5.38+
Installation
- Put the mod into the
mods folder
- Make sure KubeJS and Goety mods are installed
- Start the game
Ritual System Configuration
GoetyEvents.modifyRitual and GoetyEvents.registerRitual
Use GoetyEvents event system to customize Goety ritual requirements.
Create Script File
Create a script file in your world save directory:
your_world_save/
└── kubejs/
└── server_scripts/
└── goety_rituals.js
Modify Existing Ritual Conditions
GoetyEvents.modifyRitual(event => {
// event.modify(ritualId, modifier)
// - ritualId: Ritual ID to modify (string)
// - modifier: Modifier function that receives a ritual object
// Modify using configuration style
event.modify('storm', ritual => {
ritual.blocks = ['8x #minecraft:copper_ores', '3x minecraft:lightning_rod'];
ritual.setWeather('thunder'); // Requires thunder weather
ritual.setMinY(128); // Height >= 128
ritual.setRequireSkyVisible(true); // Requires sky visibility
});
// Modify using custom function
event.modify('magic', ritual => {
ritual.setRequirement((tileEntity, pos, level) => {
// Custom check logic
// Return true if conditions are met, false otherwise
return true;
});
});
});
Create New Ritual Type
GoetyEvents.registerRitual(event => {
// event.create(ritualId, builder)
// - ritualId: Unique identifier for the ritual (string)
// - builder: Builder function that receives a ritual object
// Create simple ritual (only needs blocks)
event.create('diamond_ritual', ritual => {
ritual.blocks = ['5x minecraft:diamond_block', '3x minecraft:emerald_block'];
});
// Create complex ritual (needs special conditions and completion effects)
event.create('thunder_ritual', ritual => {
ritual.blocks = ['minecraft:lightning_rod'];
ritual.setWeather('thunder'); // Requires thunder weather
ritual.setRequireSkyVisible(true); // Requires sky visibility
ritual.setJeiIcon('minecraft:lightning_rod'); // Set JEI display icon (optional)
// Set callback when ritual completes (optional)
// Note: This callback is triggered when the recipe completes, i.e., after the ritual successfully executes and produces results
ritual.setOnFinish((world, darkAltarPos, tileEntity, castingPlayer, activationItem) => {
// Get coordinates
let x = darkAltarPos.getX ? darkAltarPos.getX() : darkAltarPos.x;
let y = darkAltarPos.getY ? darkAltarPos.getY() : darkAltarPos.y;
let z = darkAltarPos.getZ ? darkAltarPos.getZ() : darkAltarPos.z;
// Use commands to play sound (server-side)
let server = world.getServer ? world.getServer() : null;
if (server) {
server.runCommandSilent(`playsound minecraft:entity.lightning_bolt.thunder weather @a ${x} ${y} ${z} 1 1`);
}
});
});
});
Disabling Built-in Rituals
To disable a built-in ritual, use modifyRitual to make the condition check always return false:
GoetyEvents.modifyRitual(event => {
event.modify('storm', ritual => {
ritual.requirement = () => false; // Always return false to disable ritual
});
});
Configuration Options
The ritual object supports the following configuration options:
ritual.range (integer): Scan range (default 16)
ritual.blocks (array/string): Block requirement configuration
- Supported formats:
'9x minecraft:stone', '/pattern/', '#tag', '@mod'
- Regex example:
'16x /prismarine/' matches all blocks containing prismarine
ritual.setDimension(dimensionId, containsMatch) (string, boolean): Dimension restriction
dimensionId: Dimension ID, e.g., 'minecraft:the_nether' or 'aether'
containsMatch: false (exact match, default) or true (fuzzy match)
ritual.setWeather(weather) (string): Weather requirement ('thunder'/'rain'/'clear')
ritual.setTimeOfDay(timeOfDay) (string): Time requirement ('day'/'night')
ritual.setBiome(biomeValue, type) (object, string): Biome requirement
biomeValue: Biome value (can be string or array), or method name (when type='func')
type: 'id' (biome ID, default), 'tags' (tags), 'func' (method call)
- Method call:
ritual.setBiome('coldEnoughToSnow', 'func') calls biome.coldEnoughToSnow(pos) method
- Supports any boolean method in Biome class, invoked via reflection
ritual.setMinY(y) (integer): Minimum height requirement
ritual.setMaxY(y) (integer): Maximum height requirement
ritual.setRequireSkyVisible(boolean) (boolean): Whether sky visibility is required
ritual.setRequireAltarWaterlogged(boolean) (boolean): Whether altar must be waterlogged
ritual.setJeiIcon(item) (string/object): JEI display icon (item ID or item object, optional, defaults to obsidian)
ritual.setOnFinish(callback) (function): Callback function triggered when the recipe completes (i.e., after the ritual successfully executes and produces results), receives (world, darkAltarPos, tileEntity, castingPlayer, activationItem)
ritual.setRequirement(function) (function): Custom check function (overrides all configurations)
Localization (Optional)
If you create new ritual types and want to display English names in JEI or in-game, you need to add localization files:
Using KubeJS Resource Pack
Create a resource pack structure in your world save directory:
your_world_save/
└── kubejs/
└── assets/
└── goety/
└── lang/
└── en_us.json
Add to en_us.json:
{
"jei.goety.craftType.diamond_ritual": "Diamond Ritual",
"jei.goety.craftType.flame_ritual": "Flame Ritual"
}
Localization Key Format:
- Key name:
jei.goety.craftType.<ritualId>
- Where
<ritualId> is the ID you used when creating the ritual
Note:
- If you don't add localization, the ritual name will display as the ritual ID (e.g.,
diamond_ritual)
- Localization is optional and does not affect ritual functionality
- You can add only the language files you need
Brew System Configuration
GoetyEvents.registerBrew
Configure Goety's brew system, including capacity modifiers, catalysts, and augmentations.
Create Script File
Create a script file in your world save directory:
your_world_save/
└── kubejs/
└── server_scripts/
└── goety_brews.js
Register Capacity Modifiers
GoetyEvents.registerBrew(event => {
// event.addCapacity(item, level)
// - item: Item ID (string) or item object
// - level: Level (0-7)
event.addCapacity('minecraft:nether_wart', 0);
event.addCapacity('mymod:magic_crystal', 6);
});
Register Augmentations
GoetyEvents.registerBrew(event => {
// event.addAugmentation(item, modifier, level)
// - item: Item ID (string) or item object
// - modifier: Augmentation type (string)
// - 'capacity' - Capacity
// - 'duration' - Duration
// - 'amplifier' - Effect amplifier
// - 'aoe' - Area of effect
// - 'linger' - Linger effect
// - 'quaff' - Quaff effect
// - 'velocity' - Velocity
// - 'aquatic' - Aquatic
// - 'fire_proof' - Fire proof
// - level: Level (integer)
event.addAugmentation('minecraft:redstone', 'duration', 0);
event.addAugmentation('mymod:time_crystal', 'duration', 3);
event.addAugmentation('mymod:power_crystal', 'amplifier', 2);
});
Complete Example
GoetyEvents.registerBrew(event => {
// Capacity modifiers
event.addCapacity('mymod:magic_crystal', 6);
event.addCapacity('mymod:magic_dust', 5);
// Augmentations
event.addAugmentation('mymod:time_crystal', 'duration', 3);
event.addAugmentation('mymod:power_crystal', 'amplifier', 2);
event.addAugmentation('mymod:range_crystal', 'aoe', 1);
});
Note:
- Add capacity modifiers and augmentations → Use
GoetyEvents.registerBrew
- Add catalysts (brewing recipes) → Use
event.recipes.goety.brewing (see Recipe System below)
Recipe System Configuration
ServerEvents.recipes
Use KubeJS standard recipe events to configure Goety's recipe system.
Create Script File
Create a script file in your world save directory:
your_world_save/
└── kubejs/
└── server_scripts/
└── goety_recipes.js
Ritual Recipes
ServerEvents.recipes(event => {
// event.recipes.goety.ritual(result, ritualType, ingredients)
// - result: Output item (OutputItem)
// - ritualType: Ritual type ID, choose based on function:
// - 'goety:craft' - Craft items (most common)
// - 'goety:enchant' - Enchanting
// - 'goety:summon' - Summon entities
// - 'goety:summon_tamed' - Summon tamed entities
// - 'goety:convert' - Convert entities
// - 'goety:teleport' - Teleportation
// - ingredients: Material array (InputItem[])
// Crafting ritual
event.recipes.goety.ritual('minecraft:emerald', 'goety:craft', [
'minecraft:gold_ingot',
'minecraft:gold_ingot',
'minecraft:diamond'
])
.activationItem('minecraft:ender_pearl')
.craftType('forge') // Forge ritual
.soulCost(5)
.duration(20);
// Summoning ritual
event.recipes.goety.ritual('goety:jei_dummy/none', 'goety:summon', [
'minecraft:rotten_flesh',
'minecraft:bone'
])
.activationItem('minecraft:ender_pearl')
.craftType('necroturgy')
.soulCost(10)
.entityToSummon('minecraft:zombie')
.summonLife(6000);
});
Brewing Recipes
ServerEvents.recipes(event => {
// event.recipes.goety.brewing(ingredient, effect)
// - ingredient: Material item (InputItem)
// - effect: Effect ID (String, e.g., 'minecraft:regeneration')
event.recipes.goety.brewing('minecraft:golden_apple', 'minecraft:regeneration')
.soulCost(15)
.capacityExtra(0)
.duration(30); // 30 seconds
// Brewing recipe requiring specific entity
event.recipes.goety.brewing('minecraft:nether_star', 'minecraft:resistance')
.soulCost(50)
.entityType('minecraft:ender_dragon'); // Requires ender dragon
});
Configuration Priority:
- You can use
event.recipes.goety.brewing to add new catalyst recipes or adjust soul costs for existing effects (.soulCost())
- If both
config/goety-brews.toml and KubeJS scripts are used, KubeJS scripts have higher priority and will override config file settings
- Using KubeJS scripts is recommended as they are more flexible and easier to version control
Pulverize Recipes
ServerEvents.recipes(event => {
// event.recipes.goety.pulverize(ingredient)
// - ingredient: Material item (InputItem)
// Pulverize recipe producing block
event.recipes.goety.pulverize('minecraft:cobblestone')
.blockResult('minecraft:gravel');
// Pulverize recipe producing item
event.recipes.goety.pulverize('minecraft:gravel')
.itemResult('minecraft:flint');
});
Cursed Infuser Recipes
ServerEvents.recipes(event => {
// event.recipes.goety.cursed_infuser_recipes(result, ingredient)
// - result: Output item ID (String)
// - ingredient: Material item (InputItem)
event.recipes.goety.cursed_infuser_recipes('minecraft:emerald', 'minecraft:iron_sword')
.cookingTime(100); // 5 seconds (100 ticks)
});
Brazier Recipes
ServerEvents.recipes(event => {
// event.recipes.goety.brazier(result, ingredients)
// - result: Output item (OutputItem)
// - ingredients: Material array (InputItem[])
event.recipes.goety.brazier('minecraft:emerald', [
'minecraft:soul_sand',
'minecraft:soul_sand',
'minecraft:soul_sand',
'minecraft:lapis_lazuli'
])
.soulCost(10);
});
Remove Recipes
ServerEvents.recipes(event => {
// Remove existing recipes
event.remove({ type: 'goety:ritual', craftType: 'magic' });
event.remove({ type: 'goety:brewing', effect: 'minecraft:poison' });
event.remove({ type: 'goety:pulverize', ingredient: 'minecraft:cobblestone' });
});
Contributing
Issues and Pull Requests are welcome!