Village Mechanic

This article is for anyone who wants to try imitate the village mechanic for their entities

First let's start with some basic navigation behavior.

BP/entities/custom_villager.json#componentsCopy
"minecraft:preferred_path":{
    "max_fall_blocks":1,
    "jump_cost":5,
    "default_block_cost":1.5,
    "preferred_path_blocks":[
        {
            "cost":0,
            "blocks":[
                "grass_path"
            ]
        },
        {
            "cost":1,
            "blocks":[
                "cobblestone",
                "stone"
            ]
        },
        {
            "cost":50,
            "blocks":[
                "bed",
                "lectern"
            ]
        }
    ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

Allows entity to do random walk.

BP/entities/custom_villager.json#componentsCopy
"minecraft:behavior.random_stroll":{
    "priority":9,
    "speed_multiplier":0.55,
    "xz_dist":10,
    "y_dist":5
}
1
2
3
4
5
6

Makes entity navigate around a village by creating a path to patrol. Used by Iron Golem.

BP/entities/custom_villager.json#componentsCopy
"minecraft:behavior.move_through_village": {
	"priority": 3,
	"speed_multiplier": 0.6,
	"only_at_night": true
}
1
2
3
4
5

Allows entity to enter a building and also take shelter when raining. Needs open door capabilities.

BP/entities/custom_villager.json#componentsCopy
"minecraft:behavior.move_indoors":{
    "priority":5
}
1
2
3

Makes entity stay indoors while sun is down.

BP/entities/custom_villager.json#componentsCopy
"minecraft:behavior.restrict_open_door":{
    "priority": 5
}
1
2
3

Use in pair with:

BP/entities/custom_villager.json#componentsCopy
"minecraft:annotation.open_door":{
    "priority": 5
}
1
2
3
BP/entities/custom_villager.json#componentsCopy
"minecraft:navigation.walk":{
    "can_pass_doors":true,
    "can_open_doors":true
}
1
2
3
4
BP/entities/custom_villager.json#componentsCopy
 "minecraft:behavior.open_door":{
    "priority":6,
    "close_door_after":true
}
1
2
3
4

Main Behavior

BP/entities/custom_villager.json#componentsCopy
"minecraft:dweller": {
	"dwelling_type": "village",
	"dweller_role": "inhabitant",
	"preferred_profession": "farmer",
	"update_interval_base": 60,
	"update_interval_variant": 40,
	"can_find_poi": true,
	"can_migrate": true,
	"first_founding_reward": 5
}
1
2
3
4
5
6
7
8
9
10
  • dweller_role: inhabitant Allows entity claim a bed and bell. minecraft:behavior.sleep needed.
  • preferred_profession: farmer Optional for minecraft:behavior.work
  • can_find_poi Add it so entity is able to find point of interest. Known POI types:
bed
jobsite
meeting_area
1
2
3
  • can_migrate Defines if entity can migrate from one village to another or not.

Sleep

You can find out how to make your entity sleep here.

Work

Requires "dweller_role" set to be "inhabitant" also if "preferred_profession" doesn't exist the entity will try to move to the closest any job site.

Copy
"minecraft:behavior.work": {
	"priority": 4,
	"active_time": 250,
	"speed_multiplier": 0.5,
	"goal_cooldown": 200,
	"sound_delay_min": 100,
	"sound_delay_max": 200,
	"can_work_in_rain": false,
	"work_in_rain_tolerance": 1000,
	"on_arrival": {
		"event": "minecraft:resupply_trades",
		"target": "self"
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

Gathering

Allows the entity to gather. Requires "dweller_role" set to be "inhabitant".

"minecraft:behavior.mingle": {
  "priority": 4,
  "speed_multiplier": 0.5,
  "duration": 30,
  "cooldown_time": 10,
  "mingle_partner_type": "my:custom_entity",
  "mingle_distance": 2.0
}
1
2
3
4
5
6
7
8

Scheduler

Now you know everything about needed mechanic, let's try to put all of this together in "minecraft:scheduler" First let's do something simple. Put work behavior in component group work like this:

Copy
"component_groups":{
    "work_schedule":{
        "minecraft:behavior.work":{
            "priority":4,
            "active_time":250,
            "speed_multiplier":0.5,
            "goal_cooldown":200,
            "sound_delay_min":100,
            "sound_delay_max":200,
            "can_work_in_rain":true,
            "work_in_rain_tolerance":1000,
            "on_arrival":{
                "event":"minecraft:resupply_trades",
                "target":"self"
            }
        }
    },
    "gather_schedule":{
        "minecraft:behavior.mingle":{
            "priority": 5,
            "speed_multiplier": 0.8,
            "cooldown_time":10.0,
            "duration": 30.0,
            "mingle_dist": 1.5,
            "mingle_partner_type": "my:custom_entity"
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

Next, make your entity work.

Copy
"minecraft:scheduler":{
    "min_delay_secs":0,
    "max_delay_secs":10,
    "scheduled_events":[
        {
            "filters":{
                "all_of":[
                    {
                        "test":"hourly_clock_time",
                        "operator":">=",
                        "value":0 //Morning
                    },
                    {
                        "test":"hourly_clock_time",
                        "operator":"<",
                        "value":12000 //Evening
                    }
                ]
            },
            "event":"work"
        },
        {
            "filters":{
                "all_of":[
                    {
                        "test":"hourly_clock_time",
                        "operator":">=",
                        "value":21000
                    },
                    {
                        "test":"hourly_clock_time",
                        "operator":"<",
                        "value":24000
                    }
                ]
            },
            "event":"gather"
        }
    ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

The events section looks something like this:

Copy
"events":{
    "work":{
        "remove":{
            "component_groups":[
                "gather_schedule"
            ]
        },
        "add":{
            "component_groups":[
                "work_schedule"
            ]
        }
    },
    "gather":{
        "remove":{
            "component_groups":[
                "work_schedule"
            ]
        },
        "add":{
            "component_groups":[
                "gather_schedule"
            ]
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

Open your world, spawn entity then put a bed and you should see green particle.

Other Behavior

All of this is usable by custom entities:

  • minecraft:behavior.move_to_village Used by Pillager this may keep the entity to stay in the village.
  • minecraft:behavior.stroll_towards_village Used by fox to seach a village and go there.
  • minecraft:behavior.inspect_bookshelf Used by librarian villager allows an entity to look at and inspect a bookshelf.
  • minecraft:behavior.explore_outskirts Allows entity to explore beyond the bounds of village (use schedule and component group to keep the entity return to the village).
  • minecraft:behavior.defend_village_target Use this on melee attack. Ranged attack can accidently shoot any entity with inhabitant dwelling role.

All of this can be used by custom entities and have relation to villager or village:

BehaviorUsesNote
minecraft:behavior.defend_village_targetAllows entity to attack other entity that hurt the entity who had "dweller_role": "inhabitant".Recommended to use only on entities with melee attack.
minecraft:behavior.hideUsed by villager to hide and stay at defined POI.Currently, there is no documentation for the POI type that's why I recommend not to change "poi_type": "bed".
minecraft:behavior.move_to_villageUsed by Illager and also witch. Allows entity to travel to a random x,y,z coordinate in a village.-
"minecraft:behavior.nap"Used by Fox to take a nap.Similar with sleep but offers more flexibility also has built-in wake up system by detecting specific entity.

Contributors