Falling Alchemy
Provides an alchemy system based on falling block physical interactions, supporting highly customizable recipe configurations. Core Extension: Deeply integrated with CraftTweaker, supporting probability control, complex condition logic, event listening, and sound effect control.
Demo: https://www.bilibili.com/video/BV1aKJVzsEzo
Features
✅ Core Mechanisms
- Custom falling blocks (Sand/Gravel/Anvil, etc.)
- Detect and replace specified items within range
- Support for multiple output generation and quantity proportion control
⚙️ Advanced Configuration
- Recipe Success Rate (
0.0~1.0) - Block Retention Chance (
0.0~1.0) - Single Processing
- Input protection under falling anvils
- Block displacement detection and extra output calculation
- Detection radius adjustment
- Custom Failure/Success sound effects
- NBT Fuzzy Matching (
fuzzyNBT) - Recipe Execution Priority (
priority)
🌦️ Condition System
- Biome restriction
- Time range (MC Time
0~24000) - Weather state (Clear/Rain/Thunder)
- Height restriction
- Moon phase restriction
Configuration Guide
Quick Start
import mods.fallingalchemy.FallingAlchemy;
import mods.fallingalchemy.ConsumedItem;
// 1. Create ConsumedItem object
val coalReq = FallingAlchemy.createConsumedItem(
<minecraft:coal_ore>.withTag({Unbreakable: 1 as byte}), // Match item
3, // Required count (optional, default 1)
true, // Match NBT (optional, default false)
true // Fuzzy NBT match (optional, default false)
);
// 2. Create Builder
val builder = FallingAlchemy.addConversion(
<minecraft:anvil>, // Trigger block
[coalReq], // Inputs
[<minecraft:diamond>] // Outputs
);
// 3. Chain configuration parameters
builder.setRadius(2.0) // Set radius
.setSingle(true) // Enable single processing (only one recipe per fall event)
.setRescueItems(true) // Enable item protection (prevents remaining coal from being destroyed by the anvil)
.setSuccessChance(0.8) // 80% success rate
.addHeightCondition(0, 60) // Height restriction
.register(); // Register recipe
Method Explanation
FallingAlchemy.addConversion(IItemStack fallingBlock, ConsumedItem[] inputs, IItemStack[] outputs)
Returns a ConversionBuilder object.
Builder Methods
| Method Name | Parameters | Description |
|---|---|---|
setRadius |
double |
Detection radius (Default 2.0) |
setSingle |
boolean |
If true, the recipe executes only once per fall event, preventing consumption of all materials in range. |
setRescueItems |
boolean |
If true, if the input stack size exceeds the requirement, the mod will "rescue" remaining items that would otherwise be destroyed by the falling anvil. |
setPriority |
int |
Priority. Higher values are checked first. |
setSuccessChance |
double |
Success rate (0.0 - 1.0). |
setKeepBlockChance |
double |
Probability that the falling block (e.g., Anvil) does not disappear after alchemy. |
setDisplacement |
double, boolean |
Sets minimum fall distance. The second parameter controls whether extra output is added based on additional distance. |
setSuccessSound |
string, float, float |
Set Success Sound ID, Volume, Pitch. |
setFailureSound |
string, float, float |
Set Failure Sound ID, Volume, Pitch. |
register |
string(Optional) |
Register the recipe. Can pass a string as the recipe ID. |
ConsumedItem Parameters:
IIngredient ingredient: The input itemint requiredCount: Required quantity (Optional, default is 1)bool matchNBT: Whether to strictly match NBT (Optional, default is false)bool fuzzyNBT: When matchNBT=true, only validates if existing tags match (does not check for extra tags) (Optional, default is false)
Script Example
import mods.fallingalchemy.FallingAlchemy;
import mods.fallingalchemy.ConsumedItem;
import mods.fallingalchemy.event.FallingConversionPreEvent;
import mods.fallingalchemy.event.FallingConversionPostEvent;
// Scenario: Anvil falls on "Enchanted Golden Apple" and "Stick named Magic" -> Generates "Nether Star"
val builder = FallingAlchemy.addConversion(
<minecraft:anvil>, // Trigger block
[
// NBT Strict Match Example: Must be Enchanted Golden Apple (Metadata 1)
FallingAlchemy.createConsumedItem(<minecraft:golden_apple:1>, 1),
// NBT + Fuzzy Match Example:
// Requires a stick named "Magic"
// Params: Item, Count(1), MatchNBT(true), FuzzyMatch(true - allows extra tags)
FallingAlchemy.createConsumedItem(<minecraft:stick>.withTag({display: {Name: "Magic"}}), 1, true, true)
],
[<minecraft:nether_star>] // Output
);
// Chain detailed configuration
builder.setRadius(2.5) // Detection radius 2.5 blocks
.setSuccessChance(0.8) // 80% success rate
.setKeepBlockChance(0.0) // Anvil always disappears (0% keep)
.setPriority(100) // High priority, checked before other recipes
.setSingle(true) // Process only one recipe per fall to prevent consuming entire stacks
.setRescueItems(true) // Rescue remaining materials from anvil damage
.setSuccessSound("minecraft:ui.toast.challenge_complete", 1.0, 1.0)
.setFailureSound("minecraft:entity.item.break", 1.0, 0.8)
.addHeightCondition(0, 60) // Can only happen underground (Y < 60)
.addMoonPhaseCondition(0) // Must be Full Moon
.register("apple"); // Register with ID
// Pre Event: Triggered when recipe matches successfully but before items are generated (Can cancel, modify outputs)
events.onFallingConversionPre(function(event as FallingConversionPreEvent) {
if (event.id == "apple") {
// Example: Double rewards if it is raining
if (event.world.raining) {
event.addOutput(<minecraft:nether_star>); // Add an extra Nether Star
}
// Example: Cancel if player is unlucky
if (event.world.random.nextInt(100) < 5) {
event.cancel(); // Cancel execution, items are not consumed
}
}
}
});
// Post Event: Triggered after the recipe has fully executed
events.onFallingConversionPost(function(event as FallingConversionPostEvent) {
// Log the location where alchemy occurred
print(event.position.x ~ "," ~ event.position.y ~ "," ~ event.position.z);
});
Condition System
Condition Types
| Method | Parameter Example | Description |
|---|---|---|
addBiomeCondition |
"minecraft:jungle" |
Limit Biome |
addTimeCondition |
0, 12000 |
Time Range (MC Time) |
addWeatherCondition |
true, false |
Is Raining/Thundering |
addHeightCondition |
60, 128 |
Y-Axis Height Range |
addMoonPhaseCondition |
3 |
Specific Moon Phase (0-7) |
Special Notes:
- Weather condition auto-correction: When
requireThundering=trueis set, it will automatically enable the requirement for rain. - Height condition supports single value mode:
addHeightCondition(100)means trigger at exactly Y=100.
Event System
The mod provides Pre (Before execution) and Post (After execution) events, allowing dynamic control via ZenScript.
Import event classes at the start of your script:
import mods.fallingalchemy.event.FallingConversionPreEvent;
import mods.fallingalchemy.event.FallingConversionPostEvent;
- Pre Event (FallingConversionPreEvent)
Trigger: Recipe matched successfully, just before consumption and output generation. Usage: Cancel recipe, modify outputs, add extra logic.
| Property (Getter) | Type | Description |
|---|---|---|
| event.id | string |
Recipe ID (if set during register), else empty string. |
| event.fallingBlock | IItemStack |
The falling block triggering this alchemy. |
| event.inputs | ConsumedItem[] |
List of required input items. |
| event.world | IWorld |
The world where the event occurs. |
| event.position | IBlockPos |
The position where the event occurs. |
| event.outputs | List<IItemStack> |
List of outputs to be generated. |
| Method (Setter) | Description |
|---|---|
| event.cancel() | Cancel this alchemy. Items won't be consumed or generated. |
| event.addOutput(item) | Add a new ItemStack to the output list. |
| event.setOutputs(items) | item[], overrides the current output list. |
- Post Event (FallingConversionPostEvent)
Trigger: After recipe execution is complete and items are generated. Usage: Logging, statistics, spawning extra effects.
| Property (Getter) | Type | Description |
|---|---|---|
| event.id | string |
Recipe ID. |
| event.fallingBlock | IItemStack |
The triggering falling block. |
| event.inputs | ConsumedItem[] |
List of input items used. |
| event.world | IWorld |
The world where the event occurs. |
| event.position | IBlockPos |
The position where the event occurs. |
| event.outputs | List<IItemStack> |
List of final generated outputs. |
// Pre Event Listener
events.onFallingConversionPre(function(event as FallingConversionPreEvent) {
// Method 1: Check by ID (Recommended)
// Requires using .register("my_recipe_id") during registration
if (event.id == "my_recipe_id") {
if (event.world.raining) {
event.addOutput(<minecraft:slime_ball>); // Extra output when raining
}
return;
}
// Method 2: Check by Falling Block
if (event.fallingBlock.definition.id == "minecraft:anvil") {
// 5% Chance to fail
if (event.world.random.nextInt(100) < 5) {
event.cancel();
print("Alchemy unexpectedly failed!");
}
}
});
// Post Event Listener
events.onFallingConversionPost(function(event as FallingConversionPostEvent) {
print("Alchemy Success! ID: " + event.id + " Pos: " + event.position.x + "," + event.position.y);
});
Sound System
Sound Configuration
// Specify directly in the builder
builder.setSuccessSound("Sound ID", Volume, Pitch);
Sound Parameter Specs:
- Volume Range:
0.1~2.0(Default 1.0) - Pitch Range:
0.5~2.0(Default 1.0) - Resource Format: Use standard Minecraft sound IDs, e.g.,
"minecraft:entity.lightning.thunder"
FAQ
❓ Recipe not triggering
- Confirm the falling block is registered.
- Check if detection radius covers item positions.
- Verify if set conditions are met.
❓ Sound not playing
- Confirm Sound ID is correct (Use F3+H to view item/sound IDs).
- Check if Volume/Pitch parameters are within legal range.
❓ Multiple input matching issues
- Check NBT matching mode of consumed items.
- Ensure total count of all consumed items meets the requirement.
❓ Priority not working
- Check if priority parameter is set (Default 0).
- High priority recipes should have larger values (e.g., 10 > 5).
Todo
- √ Sound effects for alchemy success/failure
- √ Y-Axis limit conditions
- √ Recipe events
- √ Cross-dimension condition support (Temporarily implementable via Biome conditions)
- - Support for "Alchemy" based on the block the falling block lands on (Can be implemented via events)
License: MIT
Feedback: Submit Issue

