diff --git a/assets/common/entity/dungeon/tier-0/bow.ron b/assets/common/entity/dungeon/tier-0/bow.ron
index e135808266..1c3f4539f2 100644
--- a/assets/common/entity/dungeon/tier-0/bow.ron
+++ b/assets/common/entity/dungeon/tier-0/bow.ron
@@ -1,5 +1,6 @@
 EntityConfig (
     name: Some("Gnarling Stalker"),
+    body: Some(RandomWith("gnarling")),
 
     main_tool: Some(Item("common.items.npc_weapons.biped_small.gnarling.adlet_bow")),
     second_tool: None,
diff --git a/assets/common/entity/dungeon/tier-0/spear.ron b/assets/common/entity/dungeon/tier-0/spear.ron
index 72c3b46fa3..05cd042552 100644
--- a/assets/common/entity/dungeon/tier-0/spear.ron
+++ b/assets/common/entity/dungeon/tier-0/spear.ron
@@ -1,5 +1,6 @@
 EntityConfig (
     name: Some("Gnarling Mugger"),
+    body: Some(RandomWith("gnarling")),
 
     main_tool: Some(Item("common.items.npc_weapons.biped_small.gnarling.wooden_spear")),
     second_tool: None,
diff --git a/assets/common/entity/dungeon/tier-0/staff.ron b/assets/common/entity/dungeon/tier-0/staff.ron
index d8928f39fe..43b1948197 100644
--- a/assets/common/entity/dungeon/tier-0/staff.ron
+++ b/assets/common/entity/dungeon/tier-0/staff.ron
@@ -1,5 +1,6 @@
 EntityConfig (
     name: Some("Gnarling Shaman"),
+    body: Some(RandomWith("gnarling")),
 
     main_tool: Some(Item("common.items.npc_weapons.biped_small.gnarling.gnoll_staff")),
     second_tool: None,
diff --git a/assets/common/entity/dungeon/tier-1/bow.ron b/assets/common/entity/dungeon/tier-1/bow.ron
index e7ea1ed0dc..51c93c9929 100644
--- a/assets/common/entity/dungeon/tier-1/bow.ron
+++ b/assets/common/entity/dungeon/tier-1/bow.ron
@@ -1,5 +1,6 @@
 EntityConfig (
     name: Some("Adlet Tracker"),
+    body: Some(RandomWith("adlet")),
 
     main_tool: Some(Item("common.items.npc_weapons.biped_small.adlet.adlet_bow")),
     second_tool: None,
diff --git a/assets/common/entity/dungeon/tier-1/spear.ron b/assets/common/entity/dungeon/tier-1/spear.ron
index 0f2d3322e5..9943b5b3c7 100644
--- a/assets/common/entity/dungeon/tier-1/spear.ron
+++ b/assets/common/entity/dungeon/tier-1/spear.ron
@@ -1,5 +1,6 @@
 EntityConfig (
     name: Some("Adlet Hunter"),
+    body: Some(RandomWith("adlet")),
 
     main_tool: Some(Item("common.items.npc_weapons.biped_small.adlet.wooden_spear")),
     second_tool: None,
diff --git a/assets/common/entity/dungeon/tier-1/staff.ron b/assets/common/entity/dungeon/tier-1/staff.ron
index 522ec1d415..d196d2654f 100644
--- a/assets/common/entity/dungeon/tier-1/staff.ron
+++ b/assets/common/entity/dungeon/tier-1/staff.ron
@@ -1,5 +1,6 @@
 EntityConfig (
     name: Some("Adlet Shaman"),
+    body: Some(RandomWith("adlet")),
 
     main_tool: Some(Item("common.items.npc_weapons.biped_small.adlet.gnoll_staff")),
     second_tool: None,
diff --git a/assets/common/entity/dungeon/tier-2/bow.ron b/assets/common/entity/dungeon/tier-2/bow.ron
index 73950982ee..435199764c 100644
--- a/assets/common/entity/dungeon/tier-2/bow.ron
+++ b/assets/common/entity/dungeon/tier-2/bow.ron
@@ -1,5 +1,6 @@
 EntityConfig (
     name: Some("Sahagin Sniper"),
+    body: Some(RandomWith("sahagin")),
 
     main_tool: Some(Item("common.items.npc_weapons.biped_small.sahagin.adlet_bow")),
     second_tool: None,
diff --git a/assets/common/entity/dungeon/tier-2/spear.ron b/assets/common/entity/dungeon/tier-2/spear.ron
index c9499cfa47..b7270579ff 100644
--- a/assets/common/entity/dungeon/tier-2/spear.ron
+++ b/assets/common/entity/dungeon/tier-2/spear.ron
@@ -1,5 +1,6 @@
 EntityConfig (
     name: Some("Sahagin Spearman"),
+    body: Some(RandomWith("sahagin")),
 
     main_tool: Some(Item("common.items.npc_weapons.biped_small.sahagin.wooden_spear")),
     second_tool: None,
diff --git a/assets/common/entity/dungeon/tier-2/staff.ron b/assets/common/entity/dungeon/tier-2/staff.ron
index 4ecbcd121e..1bf74fc93e 100644
--- a/assets/common/entity/dungeon/tier-2/staff.ron
+++ b/assets/common/entity/dungeon/tier-2/staff.ron
@@ -1,5 +1,6 @@
 EntityConfig (
     name: Some("Sahagin Sorcerer"),
+    body: Some(RandomWith("sahagin")),
 
     main_tool: Some(Item("common.items.npc_weapons.biped_small.sahagin.gnoll_staff")),
     second_tool: None,
diff --git a/assets/common/entity/dungeon/tier-3/bow.ron b/assets/common/entity/dungeon/tier-3/bow.ron
index e642c37333..a667ca255b 100644
--- a/assets/common/entity/dungeon/tier-3/bow.ron
+++ b/assets/common/entity/dungeon/tier-3/bow.ron
@@ -1,5 +1,6 @@
 EntityConfig (
     name: Some("Haniwa Archer"),
+    body: Some(RandomWith("haniwa")),
 
     main_tool: Some(Item("common.items.npc_weapons.biped_small.haniwa.adlet_bow")),
     second_tool: None,
diff --git a/assets/common/entity/dungeon/tier-3/spear.ron b/assets/common/entity/dungeon/tier-3/spear.ron
index 4c107bdd73..9d74bd0ba6 100644
--- a/assets/common/entity/dungeon/tier-3/spear.ron
+++ b/assets/common/entity/dungeon/tier-3/spear.ron
@@ -1,5 +1,6 @@
 EntityConfig (
     name: Some("Haniwa Guard"),
+    body: Some(RandomWith("haniwa")),
 
     main_tool: Some(Item("common.items.npc_weapons.biped_small.haniwa.wooden_spear")),
     second_tool: None,
diff --git a/assets/common/entity/dungeon/tier-3/staff.ron b/assets/common/entity/dungeon/tier-3/staff.ron
index adfe8857e8..649c669272 100644
--- a/assets/common/entity/dungeon/tier-3/staff.ron
+++ b/assets/common/entity/dungeon/tier-3/staff.ron
@@ -1,5 +1,6 @@
 EntityConfig (
     name: Some("Haniwa Sorcerer"),
+    body: Some(RandomWith("haniwa")),
 
     main_tool: Some(Item("common.items.npc_weapons.biped_small.haniwa.gnoll_staff")),
     second_tool: None,
diff --git a/assets/common/entity/dungeon/tier-4/bow.ron b/assets/common/entity/dungeon/tier-4/bow.ron
index 04cf0e7b02..205cca7248 100644
--- a/assets/common/entity/dungeon/tier-4/bow.ron
+++ b/assets/common/entity/dungeon/tier-4/bow.ron
@@ -1,5 +1,6 @@
 EntityConfig (
     name: Some("Myrmidon Marksman"),
+    body: Some(RandomWith("myrmidon")),
 
     main_tool: Some(Item("common.items.npc_weapons.biped_small.myrmidon.adlet_bow")),
     second_tool: None,
diff --git a/assets/common/entity/dungeon/tier-4/spear.ron b/assets/common/entity/dungeon/tier-4/spear.ron
index d73950e575..c5688f6fe9 100644
--- a/assets/common/entity/dungeon/tier-4/spear.ron
+++ b/assets/common/entity/dungeon/tier-4/spear.ron
@@ -1,5 +1,6 @@
 EntityConfig (
     name: Some("Myrmidon Hoplite"),
+    body: Some(RandomWith("myrmidon")),
 
     main_tool: Some(Item("common.items.npc_weapons.biped_small.myrmidon.wooden_spear")),
     second_tool: None,
diff --git a/assets/common/entity/dungeon/tier-4/staff.ron b/assets/common/entity/dungeon/tier-4/staff.ron
index a022a4b330..2b4926db59 100644
--- a/assets/common/entity/dungeon/tier-4/staff.ron
+++ b/assets/common/entity/dungeon/tier-4/staff.ron
@@ -1,5 +1,6 @@
 EntityConfig (
     name: Some("Myrmidon Wizard"),
+    body: Some(RandomWith("myrmidon")),
 
     main_tool: Some(Item("common.items.npc_weapons.biped_small.myrmidon.gnoll_staff")),
     second_tool: None,
diff --git a/assets/common/entity/dungeon/tier-5/beastmaster.ron b/assets/common/entity/dungeon/tier-5/beastmaster.ron
index 4c2421ac72..3bf5cac4f2 100644
--- a/assets/common/entity/dungeon/tier-5/beastmaster.ron
+++ b/assets/common/entity/dungeon/tier-5/beastmaster.ron
@@ -1,5 +1,6 @@
 EntityConfig (
     name: Some("Beastmaster"),
+    body: Some(RandomWith("humanoid")),
 
     main_tool: Some(Choice([
         (1.0, Some(Item("common.items.weapons.axe.malachite_axe-0"))),
diff --git a/assets/common/entity/dungeon/tier-5/boss.ron b/assets/common/entity/dungeon/tier-5/boss.ron
index ffa83720a7..9f7c6d376a 100644
--- a/assets/common/entity/dungeon/tier-5/boss.ron
+++ b/assets/common/entity/dungeon/tier-5/boss.ron
@@ -1,5 +1,6 @@
 EntityConfig (
     name: Some("Mindflayer"),
+    body: Some(RandomWith("mindflayer")),
 
     main_tool: None,
     second_tool: None,
diff --git a/assets/common/entity/dungeon/tier-5/husk.ron b/assets/common/entity/dungeon/tier-5/husk.ron
index 6c23289a44..0409d98436 100644
--- a/assets/common/entity/dungeon/tier-5/husk.ron
+++ b/assets/common/entity/dungeon/tier-5/husk.ron
@@ -1,5 +1,6 @@
 EntityConfig (
     name: Some("Cultist Husk"),
+    body: Some(RandomWith("husk")),
 
     main_tool: None,
     second_tool: None,
diff --git a/assets/common/entity/dungeon/tier-5/warlock.ron b/assets/common/entity/dungeon/tier-5/warlock.ron
index 8e5fe4ae70..4553ea5ff9 100644
--- a/assets/common/entity/dungeon/tier-5/warlock.ron
+++ b/assets/common/entity/dungeon/tier-5/warlock.ron
@@ -1,5 +1,6 @@
 EntityConfig (
     name: Some("Cultist Warlock"),
+    body: Some(RandomWith("humanoid")),
 
     main_tool: Some(Item("common.items.weapons.staff.cultist_staff")),
     second_tool: None,
diff --git a/assets/common/entity/dungeon/tier-5/warlord.ron b/assets/common/entity/dungeon/tier-5/warlord.ron
index 37430fc373..53d3605fb0 100644
--- a/assets/common/entity/dungeon/tier-5/warlord.ron
+++ b/assets/common/entity/dungeon/tier-5/warlord.ron
@@ -1,5 +1,6 @@
 EntityConfig (
     name: Some("Cultist Warlord"),
+    body: Some(RandomWith("humanoid")),
 
     main_tool: Some(Choice([
         (1.0, Some(Item("common.items.weapons.axe_1h.orichalcum-0"))),
diff --git a/assets/common/entity/test.ron b/assets/common/entity/test.ron
index 915f98ade2..e967f36b6c 100644
--- a/assets/common/entity/test.ron
+++ b/assets/common/entity/test.ron
@@ -6,7 +6,7 @@ EntityConfig (
     /// Can be Exact (Body with all fields e.g BodyType, Species, Hair color and such)
     /// or Random (will use random if available for this Body)
     /// or RandomWith (will use random_with if available for this Body)
-    // body: Humanoid(Random),
+    body: Some(RandomWith("humanoid")),
 
     /// Main and second tools
     /// Can be Option<Item> (with asset_specifier for item)
diff --git a/assets/common/entity/village/guard.ron b/assets/common/entity/village/guard.ron
index 93d770cb2c..6332487f7a 100644
--- a/assets/common/entity/village/guard.ron
+++ b/assets/common/entity/village/guard.ron
@@ -1,5 +1,7 @@
 EntityConfig (
     name: Some("Guard"),
+    // body is specified outsite
+    body: None,
 
     main_tool: Some(Item("common.items.weapons.sword.iron-4")),
     second_tool: None,
diff --git a/assets/common/entity/village/merchant.ron b/assets/common/entity/village/merchant.ron
index 07dd497fdf..c1b39be174 100644
--- a/assets/common/entity/village/merchant.ron
+++ b/assets/common/entity/village/merchant.ron
@@ -1,5 +1,7 @@
 EntityConfig (
     name: Some("Merchant"),
+    // body is specified outsite
+    body: None,
 
     main_tool: Some(Item("common.items.weapons.bow.eldwood-0")),
     second_tool: None,
diff --git a/assets/common/entity/village/villager.ron b/assets/common/entity/village/villager.ron
index 45a92d5abb..bef5f5bbad 100644
--- a/assets/common/entity/village/villager.ron
+++ b/assets/common/entity/village/villager.ron
@@ -1,5 +1,7 @@
 EntityConfig (
     name: None,
+    // body is specified outsite
+    body: None,
 
     main_tool: Some(Choice([
         (1.0, Some(Item("common.items.weapons.tool.broom"))),
diff --git a/common/src/generation.rs b/common/src/generation.rs
index f31aa7628e..131815bbe2 100644
--- a/common/src/generation.rs
+++ b/common/src/generation.rs
@@ -12,9 +12,15 @@ use crate::{
 use serde::Deserialize;
 use vek::*;
 
+#[derive(Debug, Deserialize, Clone)]
+enum BodyKind {
+    RandomWith(String),
+}
+
 #[derive(Debug, Deserialize, Clone)]
 struct EntityConfig {
     name: Option<String>,
+    body: Option<BodyKind>,
     main_tool: Option<ItemSpec>,
     second_tool: Option<ItemSpec>,
     loadout_asset: Option<String>,
@@ -86,6 +92,7 @@ impl EntityInfo {
     fn with_entity_config(mut self, config: EntityConfig, asset_specifier: Option<&str>) -> Self {
         let EntityConfig {
             name,
+            body,
             main_tool,
             second_tool,
             loadout_asset,
@@ -96,6 +103,19 @@ impl EntityInfo {
             self = self.with_name(name);
         }
 
+        if let Some(body) = body {
+            match body {
+                BodyKind::RandomWith(string) => {
+                    let npc::NpcBody(_body_kind, mut body_creator) =
+                        string.parse::<npc::NpcBody>().unwrap_or_else(|err| {
+                            panic!("failed to parse body {:?}. Err: {:?}", &string, err)
+                        });
+                    let body = body_creator();
+                    self = self.with_body(body);
+                },
+            }
+        }
+
         let rng = &mut rand::thread_rng();
         if let Some(main_tool) =
             main_tool.and_then(|i| i.try_to_item(asset_specifier.unwrap_or("??"), rng))
@@ -296,7 +316,8 @@ mod tests {
                 second_tool,
                 loadout_asset,
                 skillset_asset,
-                ..
+                name: _name,
+                body,
             } = config;
 
             if let Some(main_tool) = main_tool {
@@ -307,6 +328,18 @@ mod tests {
                 second_tool.validate(EquipSlot::ActiveOffhand);
             }
 
+            if let Some(body) = body {
+                match body {
+                    BodyKind::RandomWith(string) => {
+                        let npc::NpcBody(_body_kind, mut body_creator) =
+                            string.parse::<npc::NpcBody>().unwrap_or_else(|err| {
+                                panic!("failed to parse body {:?}. Err: {:?}", &string, err)
+                            });
+                        std::mem::drop(body_creator());
+                    },
+                }
+            }
+
             if let Some(loadout_asset) = loadout_asset {
                 let rng = &mut rand::thread_rng();
                 let builder = LoadoutBuilder::default();
diff --git a/world/src/site/dungeon/mod.rs b/world/src/site/dungeon/mod.rs
index 2439027220..7fc3cd0410 100644
--- a/world/src/site/dungeon/mod.rs
+++ b/world/src/site/dungeon/mod.rs
@@ -926,12 +926,6 @@ fn enemy_0(dynamic_rng: &mut impl Rng, entity: EntityInfo) -> EntityInfo {
     let chosen = Lottery::<LootSpec>::load_expect("common.loot_tables.dungeon.tier-0.enemy");
 
     let gnarling = entity
-        .with_body(comp::Body::BipedSmall(
-            comp::biped_small::Body::random_with(
-                dynamic_rng,
-                &comp::biped_small::Species::Gnarling,
-            ),
-        ))
         .with_loot_drop(chosen.read().choose().to_item());
 
     match dynamic_rng.gen_range(0..5) {
@@ -945,9 +939,6 @@ fn enemy_1(dynamic_rng: &mut impl Rng, entity: EntityInfo) -> EntityInfo {
     let chosen = Lottery::<LootSpec>::load_expect("common.loot_tables.dungeon.tier-1.enemy");
 
     let adlet = entity
-        .with_body(comp::Body::BipedSmall(
-            comp::biped_small::Body::random_with(dynamic_rng, &comp::biped_small::Species::Adlet),
-        ))
         .with_loot_drop(chosen.read().choose().to_item());
 
     match dynamic_rng.gen_range(0..5) {
@@ -961,9 +952,6 @@ fn enemy_2(dynamic_rng: &mut impl Rng, entity: EntityInfo) -> EntityInfo {
     let chosen = Lottery::<LootSpec>::load_expect("common.loot_tables.dungeon.tier-2.enemy");
 
     let sahagin = entity
-        .with_body(comp::Body::BipedSmall(
-            comp::biped_small::Body::random_with(dynamic_rng, &comp::biped_small::Species::Sahagin),
-        ))
         .with_loot_drop(chosen.read().choose().to_item());
 
     match dynamic_rng.gen_range(0..5) {
@@ -985,12 +973,6 @@ fn enemy_3(dynamic_rng: &mut impl Rng, entity: EntityInfo) -> EntityInfo {
             )),
         _ => {
             let haniwa = entity
-                .with_body(comp::Body::BipedSmall(
-                    comp::biped_small::Body::random_with(
-                        dynamic_rng,
-                        &comp::biped_small::Species::Haniwa,
-                    ),
-                ))
                 .with_loot_drop(chosen.read().choose().to_item());
 
             match dynamic_rng.gen_range(0..5) {
@@ -1005,12 +987,6 @@ fn enemy_4(dynamic_rng: &mut impl Rng, entity: EntityInfo) -> EntityInfo {
     let chosen = Lottery::<LootSpec>::load_expect("common.loot_tables.dungeon.tier-4.enemy");
 
     let myrmidon = entity
-        .with_body(comp::Body::BipedSmall(
-            comp::biped_small::Body::random_with(
-                dynamic_rng,
-                &comp::biped_small::Species::Myrmidon,
-            ),
-        ))
         .with_loot_drop(chosen.read().choose().to_item());
 
     match dynamic_rng.gen_range(0..5) {
@@ -1031,11 +1007,9 @@ fn enemy_5(dynamic_rng: &mut impl Rng, entity: EntityInfo) -> EntityInfo {
                 "common.items.crafting_ing.twigs",
             )),
         1 => entity
-            .with_body(comp::Body::Humanoid(comp::humanoid::Body::random()))
             .with_loot_drop(chosen.read().choose().to_item())
             .with_asset_expect("common.entity.dungeon.tier-5.warlock"),
         _ => entity
-            .with_body(comp::Body::Humanoid(comp::humanoid::Body::random()))
             .with_loot_drop(chosen.read().choose().to_item())
             .with_asset_expect("common.entity.dungeon.tier-5.warlord"),
     }
@@ -1308,7 +1282,6 @@ mod tests {
         boss_fallback(&mut dynamic_rng, tile_wcenter);
     }
 
-    //FIXME: it will miss items with rng branching
     #[test]
     fn test_creating_enemies() {
         let mut dynamic_rng = rand::thread_rng();
@@ -1322,7 +1295,6 @@ mod tests {
         enemy_fallback(&mut dynamic_rng, raw_entity);
     }
 
-    //FIXME: it will miss items with rng branching
     #[test]
     fn test_creating_minibosses() {
         let mut dynamic_rng = rand::thread_rng();