-
Notifications
You must be signed in to change notification settings - Fork 56
Villagers
Two separate things that both concern villagers: data driven trades, and AI hooks for adding activities and schedules to their brain.
Add and remove trades from any villager, vanilla or modded, from a datapack. No code needed.
The file goes in data/[villager mod id]/moonlight/villager_trades/[profession].json. For a vanilla
farmer that's data/minecraft/moonlight/villager_trades/farmer.json.
Here is the basic trade type:
{
"type": "simple",
"offer": {
"id": "minecraft:stone",
"Count": 1
},
"price": {
"id": "minecraft:emerald",
"Count": 4
},
"price_secondary": {
"id": "minecraft:cobblestone",
"Count": 1
},
"max_trades": 16,
"price_multiplier": 0.05,
"xp": 5,
"level": 2
}Only type, offer and price are required.
| Field | Type | Default | Description |
|---|---|---|---|
offer |
item stack | What the villager sells | |
price |
item cost | What it costs | |
price_secondary |
item cost | none | Optional second cost |
max_trades |
int | 16 | Uses before it locks |
xp |
int | depends on level | Villager xp per trade |
price_multiplier |
float | 0.05 | Demand price scaling |
level |
1 to 5 | 1 | Profession level needed |
loot_function |
loot function | none | Applied to the offered stack, so you can roll enchantments or random counts |
Biome variant trades (1.21+), a different trade per villager type:
{
"type": "villager_type_variant",
"default": {
"type": "simple"
},
"trades_per_type": {
"minecraft:desert": { "type": "simple" },
"minecraft:jungle": { "type": "simple" }
}
}Removing trades. remove_all_non_data drops every non datapack trade at a level:
{
"type": "remove_all_non_data",
"level": 3
}Overriding another mod's file. Use no_op, which parses to nothing:
{
"type": "no_op"
}Register a codec and the type becomes available to datapacks:
public static void init() {
ItemListingManager.registerSerializer(MyMod.res("my_trade"), MyTrade.CODEC);
}public record MyTrade(ItemStack offer, int level) implements ModItemListing {
public static final MapCodec<MyTrade> CODEC = RecordCodecBuilder.mapCodec(i -> i.group(
ItemStack.CODEC.fieldOf("offer").forGetter(MyTrade::offer),
Codec.intRange(1, 5).optionalFieldOf("level", 1).forGetter(MyTrade::level)
).apply(i, MyTrade::new));
@Override
public MerchantOffer getOffer(Entity entity, RandomSource random) {
return new MerchantOffer(new ItemCost(Items.EMERALD, 1), offer, 16,
ModItemListing.defaultXp(true, level), 0.05f);
}
@Override
public MapCodec<? extends ModItemListing> getCodec() {
return CODEC;
}
@Override
public int getLevel() {
return level;
}
}ItemListingManager.registerSimple(id, listing, level) registers a plain vanilla ItemListing under
an id instead, when you don't need any fields.
Example: VillagerTradesExample
Villager brains are hard to extend without stomping on other mods. These hooks let several mods add activities and tasks to the same villager without fighting.
public static void init() {
VillagerAIHooks.addBrainModification(MyMod::onBrainEvent);
}
private static void onBrainEvent(IVillagerBrainEvent event) {
// add to an existing activity without clearing what's already in it
event.addTaskToActivity(Activity.WORK, Pair.of(5, new MyBehavior()));
// put your own activity in the daily schedule
event.scheduleActivity(MY_ACTIVITY.get(), 6000, 9000);
}You can also add sensors, edit the memory map, or replace a whole activity with
addOrReplaceActivity (heavier handed: other mods' additions to it are lost).
Warning
Don't touch the brain directly. The point of these methods is that two mods adding to the same activity both end up working.
Register the memory type normally, then tell the villager about it during setup, or it won't be saved:
public static final Supplier<MemoryModuleType<Integer>> CUSTOM_MEMORY =
RegHelper.registerMemoryModule(MyMod.res("custom_memory"), Codec.INT);
public static void setup() {
VillagerAIHooks.registerMemory(CUSTOM_MEMORY.get());
}Activities, schedules and sensors are registered with the usual
RegHelper calls.
Example: VillagersAIHooksExample
Basics Platform Helpers Registration Networking Events Configs Config Screen
Resources Runtime Resource Packs Texture Manipulation Resource Helpers Block Set API
Client Custom Models Item Rendering Rendered Textures Post Shaders GUI Toolkit Colors
World Block and Item Interfaces Additional Item Placements Improved Entities Fake Levels World Data Dispenser Behaviors
Utilities Codec Utilities Misc Helpers Commands
Datapacks Villagers Soft Fluids Map Markers Spawn Boxes Global Datapack Folder