How Bedrock Tracks Villages
A village in Bedrock Edition is not defined by the structures that generate in the world. Instead, the engine dynamically creates a village whenever an entity with the `minecraft:dweller` component successfully links to a point of interest (POI), most notably a bed.
Once a bed is claimed, the game establishes a village bounding box around it. As dwellers claim additional beds, bells, and job site blocks within range, the village boundaries expand to encompass them. The engine tracks the population, available beds, and hostile threats within this invisible volume.
For your custom entity to interact with this system—whether to sleep, work, or defend the area—it must register itself with the village manager. Without this registration, village-specific AI behaviors will fail to find targets because the entity does not belong to any settlement.
Registering an Entity as a Dweller
The core of all village interaction is the `minecraft:dweller` component. This component adds the entity to the internal village roster and determines what kind of role it plays in the population calculations.
When you add `minecraft:dweller` to your behavior file, you must specify the `dweller_role`. The role tells the village whether this entity counts toward the bed limit, whether it is a defender, or whether it is an attacker.
| Field | What it does | Notes |
|---|---|---|
| dwelling_type | Defines the settlement type the entity looks for. | Always set to "village". No other vanilla dwelling types exist. |
| dweller_role | Sets how the village counts this entity. | Common values are "inhabitant" (villagers), "defender" (iron golems), "hostile" (raiders), and "passive" (cats). |
| can_find_poi | Allows the entity to search for and claim beds and workstations. | Requires proper navigation components to function. |
| can_migrate | Allows the entity to leave a full village and link to a new one. | Important for custom inhabitants so they do not get stuck when beds are broken. |
| preferred_profession | Hints at which workstation POI the entity should prioritize. | Matches vanilla profession names like "farmer" or "librarian". |
{
"format_version": "1.20.80",
"minecraft:entity": {
"description": {
"identifier": "wiki:custom_townsman",
"is_spawnable": true,
"is_summonable": true
},
"components": {
"minecraft:type_family": {
"family": [ "villager", "mob" ]
},
"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
}
}
}
}Navigation Requirements for POIs
Setting `can_find_poi` to true is not enough on its own. The Bedrock village manager requires an entity to pathfind to a block before it can claim it as a bed or workstation. If the entity cannot calculate a valid path to the POI, the claim fails.
Furthermore, villages rely heavily on doors. Your custom entity needs a navigation component configured to pass through closed doors, alongside the `minecraft:annotation.open_door` component. Without these, your custom villager will get trapped outside or inside buildings and eventually lose its link to its bed and workstation.
{
"minecraft:movement.basic": {},
"minecraft:navigation.walk": {
"can_path_over_water": true,
"can_pass_doors": true,
"can_open_doors": true,
"avoid_water": true
},
"minecraft:annotation.open_door": {}
}Daily Routine and AI Goals
Once an entity is registered as an `inhabitant` dweller and can navigate doors, you can attach the AI goals that drive the daily village routine. These goals read the POI data stored by the `minecraft:dweller` component.
For a standard townsfolk routine, you combine sleeping, working, mingling around the bell, and fleeing inside during emergencies. Note that many of these behaviors are Normally driven by the `minecraft:scheduler` component in vanilla villagers to switch component groups based on the time of day, though the AI goals themselves can sit in the main component list if configured properly.
| AI Goal | What it does | Notes |
|---|---|---|
| minecraft:behavior.sleep | Paths the entity to its claimed bed and puts it in a sleeping state. | Only functions if the entity has claimed a bed via `minecraft:dweller`. |
| minecraft:behavior.work | Paths the entity to its claimed job site block and triggers work sounds. | plays the sound linked to the entity's `preferred_profession`. |
| minecraft:behavior.mingle | Causes entities to gather near the village bell and face each other. | Set `mingle_partner_type` to your custom identifier or `minecraft:villager_v2`. |
| minecraft:behavior.move_indoors | Instructs the entity to seek shelter under a roof near a door. | Crucial for keeping custom dwellers alive at night or during raids. |
| minecraft:behavior.move_towards_dwelling_restriction | Keeps the entity inside the calculated boundaries of its village. | Prevents custom guards and villagers from wandering off into unloaded chunks. |
{
"minecraft:behavior.sleep": {
"priority": 3,
"goal_radius": 1.5,
"speed_multiplier": 0.5,
"sleep_collider_height": 0.3,
"sleep_collider_width": 1.0,
"sleep_y_offset": 0.6,
"timeout_cooldown": 8.0
},
"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": 100
},
"minecraft:behavior.mingle": {
"priority": 5,
"speed_multiplier": 0.5,
"duration": 30.0,
"cooldown_time": 10.0,
"mingle_partner_type": "wiki:custom_townsman",
"mingle_distance": 2.0
},
"minecraft:behavior.move_indoors": {
"priority": 2,
"speed_multiplier": 0.8,
"timeout_cooldown": 8.0
},
"minecraft:behavior.move_towards_dwelling_restriction": {
"priority": 6,
"speed_multiplier": 1.0
}
}Creating Custom Village Defenders
If you are building a custom guard, turret, or golem, you do not want it taking beds away from villagers. By setting `dweller_role` to `defender`, the entity is bound to the village volume without occupying an inhabitant slot.
Defenders gain access to `minecraft:behavior.defend_village_target`. This target goal queries the village manager for any entity that has recently attacked an inhabitant or holds a hostile dweller role. Combine this with `minecraft:behavior.move_towards_dwelling_restriction` to create a guard that patrols the settlement and automatically aggros on threats to the townsfolk.
{
"minecraft:dweller": {
"dwelling_type": "village",
"dweller_role": "defender",
"update_interval_base": 60,
"update_interval_variant": 40,
"can_find_poi": false,
"can_migrate": true
},
"minecraft:behavior.defend_village_target": {
"priority": 1,
"must_reach": true,
"attack_chance": 1.0,
"entity_types": [
{
"filters": {
"any_of": [
{ "test": "is_family", "subject": "other", "value": "monster" },
{ "test": "is_family", "subject": "other", "value": "illager" }
]
}
}
]
},
"minecraft:behavior.move_towards_dwelling_restriction": {
"priority": 4,
"speed_multiplier": 0.6
}
}Hardcoded Limitations
While the dweller component is flexible, large parts of the village system remain hardcoded in the C++ engine. You cannot define custom Point of Interest blocks in an add-on; entities with `can_find_poi` will only ever search for vanilla beds, bells, and the standard vanilla job site blocks (lectern, composter, smithing table, etc.).
Similarly, you cannot invent new `dweller_role` strings. If you want a custom block to act as a workstation, the standard workaround is to place an invisible marker entity inside your custom block, or have your custom entity use `minecraft:behavior.move_to_block` instead of the village POI system.
Which versions this applies to
Applies to Bedrock Edition 1.14.0 and newer (Village & Pillage architecture). All components shown are stable and do not require any experimental toggles.
When it does not work
| What you see | Why | The fix |
|---|---|---|
| Custom villager spawns near a bed, shows no green particles, and refuses to sleep at night. | Either there is no existing village and the entity has `can_find_poi` set to false, or the entity lacks a navigation component that allows it to pathfind to the pillow end of the bed. | Ensure `can_find_poi` is true in `minecraft:dweller`, and verify the entity has `minecraft:navigation.walk` with `can_pass_doors` and `can_open_doors` enabled. |
| Content Log Error: [Json][error] entities/custom_townsman.json: minecraft:dweller - invalid dweller_role | You entered a custom string like "guard" or "mayor" into the `dweller_role` field. This field only accepts a strict list of engine-defined roles. | Change `dweller_role` to one of the valid vanilla strings: "inhabitant", "defender", "hostile", or "passive". |
| Custom guard with `minecraft:behavior.defend_village_target` stands still while zombies attack villagers. | The guard has not linked to the village because it lacks the `minecraft:dweller` component, or it has a target selector but no actual attack behavior (like `minecraft:behavior.melee_attack`). | Add `minecraft:dweller` with `"dweller_role": "defender"` so the guard can read the village threat list, and ensure `minecraft:behavior.melee_attack` and `minecraft:attack` are present. |
Reference, straight from the game files
Read out of the game itself, so the ids match the version you are building for.
