dragoness_e: (Raditz)
[personal profile] dragoness_e

Courtesy of Draco18s:

The loot modifier is a replacement system for HarvestDropsEvent. It allows a modder to hook into the loot system and examine or modify the loot being dropped without having to overwrite dozens or possibly hundreds of loot tables (which does not have inter-mod compatibility: if two mods try to replace the same loot table, which ever mod loads last wins).

As an example, a smelting enchantment that when used on any block causes it to drop the item as if it was smelted in a furnace instead of its usual drop.

There's essentially three pieces:

1) The json data file

2) The backing code

3) The inclusion of the registry name in the global_loot_modifiers.json Forge data file (this file is the tag-like master list: any modifier not listed will not be loaded, the rest are loaded in the resulting order from the data file merging, same as how tags are handled).


#3 is the easiest. Just create a new json file called global_loot_modifiers in the Forge data/loot_modifiers folder and list the registry names of your modifiers.

#1 is the serialized form of your modifier. The important bit is the conditions attribute which determines under what conditions your modifier is executed.

#2 is the java code that actually performs the loot modification, similar to the code you would have used in a HarvestDropsEvent handler.


So as an example, the smelting modifier.


1) https://github.com/MinecraftForge/MinecraftForge/blob/1.15.x/src/test/resources/data/global_loot_test/loot_modifiers/smelting.json#L2-L16

Line 17 is obsolete and I forgot to clean it up.

2) https://github.com/MinecraftForge/MinecraftForge/blob/1.15.x/src/test/java/net/minecraftforge/debug/gameplay/loot/GlobalLootModifiersTest.java#L77-L104

Lines 98-103 are a factory class (same as is used in all other json data classes)

Lines 78-80 are a standard constructor, most modifiers likely won't need something more complex (but here's an example). Its just whatever data gets stored in the json and is deserialized, it needs to be passed in. The parent class only needs to know about the conditions.

Lines 84-88 is the automatically invoked method that performs the modification. Smelting is a little complicated, but those lines there just say "for every item in the generated loot, attempt to smelt it."

Lines 90-96 is the method that attempts to smelt a given item. It just fetches the smelting recipe list, smelts the input, and collects the output. If the item can't be smelted, then the item itself is returned. All you're looking at is a sequence of LINQ queries.


3) https://github.com/MinecraftForge/MinecraftForge/blob/1.15.x/src/test/resources/data/forge/loot_modifiers/global_loot_modifiers.json#L5

Should be pretty self explanatory

And of course, the serializers are Forge registry entries, so they need to be registered. These are the registry names that are looked up from the "master list" that step 1 builds.

https://github.com/MinecraftForge/MinecraftForge/blob/1.15.x/src/test/java/net/minecraftforge/debug/gameplay/loot/GlobalLootModifiersTest.java#L58-L62

Profile

dragoness_e: (Default)
Dragoness Eclectic

May 2025

S M T W T F S
     123
45678910
11121314151617
18192021222324
25262728293031

Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jun. 9th, 2025 10:59 am
Powered by Dreamwidth Studios