diff --git a/assets/world/module/misc/well.vox b/assets/world/module/misc/well.vox
new file mode 100644
index 0000000000..8c6cf5667a
--- /dev/null
+++ b/assets/world/module/misc/well.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f7087b9506ea520ddd847e363acf4d5a19b9bbd1b6d8c3e4abe0b00a94860b65
+size 1900
diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs
index 76e8e35927..fb382a941f 100644
--- a/world/src/column/mod.rs
+++ b/world/src/column/mod.rs
@@ -171,7 +171,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
                 .get((wposf_turb.div(200.0)).into_array()) as f32)
                 .abs()
                 .mul(chaos.max(0.025))
-                .mul(50.0)
+                .mul(75.0)
             + (sim
                 .gen_ctx
                 .small_nz
@@ -179,7 +179,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
                 .abs()
                 .mul(1.0 - chaos)
                 .mul(1.0 - humidity)
-                .mul(75.0);
+                .mul(85.0);
 
         let is_cliffs = sim_chunk.is_cliffs;
         let near_cliffs = sim_chunk.near_cliffs;
diff --git a/world/src/generator/town/mod.rs b/world/src/generator/town/mod.rs
index 7bf84c9c62..cf2ef5eb26 100644
--- a/world/src/generator/town/mod.rs
+++ b/world/src/generator/town/mod.rs
@@ -70,6 +70,7 @@ impl<'a> Sampler<'a> for TownGen {
                 CellKind::Park => None,
                 CellKind::Rock => Some(Block::new(BlockKind::Normal, Rgb::broadcast(100))),
                 CellKind::Wall => Some(Block::new(BlockKind::Normal, Rgb::broadcast(175))),
+                CellKind::Well => Some(Block::new(BlockKind::Normal, Rgb::broadcast(0))),
                 CellKind::Road => {
                     if (wpos.z as f32) < height - 1.0 {
                         Some(Block::new(
@@ -154,6 +155,7 @@ impl TownState {
         vol.gen_parks(rng, 3);
         vol.emplace_columns();
         let houses = vol.gen_houses(rng, 50);
+        vol.gen_wells(rng, 5);
         vol.gen_walls(rng);
         vol.resolve_modules(rng);
         vol.cull_unused();
@@ -301,10 +303,7 @@ impl TownVol {
                     self.set_col_kind(cell, Some(ColumnKind::Internal));
                     let col = self.col(cell).unwrap();
                     let ground = col.ground;
-                    for z in 0..2 {
-                        let _ =
-                            self.set(Vec3::new(cell.x, cell.y, ground + z), CellKind::Park.into());
-                    }
+                    let _ = self.set(Vec3::new(cell.x, cell.y, ground), CellKind::Park.into());
                 }
 
                 break;
@@ -394,6 +393,20 @@ impl TownVol {
         }
     }
 
+    fn gen_wells(&mut self, rng: &mut impl Rng, n: usize) {
+        for _ in 0..n {
+            if let Some(cell) = self.choose_cell(rng, |_, cell| {
+                if let CellKind::Park = cell.kind {
+                    true
+                } else {
+                    false
+                }
+            }) {
+                self.set(cell, CellKind::Well.into());
+            }
+        }
+    }
+
     fn gen_houses(&mut self, rng: &mut impl Rng, n: usize) -> Vec<House> {
         const ATTEMPTS: usize = 10;
 
@@ -421,7 +434,7 @@ impl TownVol {
 
                 let mut cells: HashSet<_> = Some(entrance).into_iter().collect();
 
-                let mut energy = 3000;
+                let mut energy = 2300;
                 while energy > 0 {
                     energy -= 1;
 
@@ -604,6 +617,7 @@ fn modules_from_kind(kind: &CellKind) -> Option<&'static [(Arc<Structure>, [Modu
     match kind {
         CellKind::House(_) => Some(&HOUSE_MODULES),
         CellKind::Wall => Some(&WALL_MODULES),
+        CellKind::Well => Some(&WELL_MODULES),
         _ => None,
     }
 }
@@ -659,4 +673,26 @@ lazy_static! {
             module("wall.single_top", [That, That, That, That, That, This]),
         ]
     };
+    pub static ref WELL_MODULES: Vec<(Arc<Structure>, [ModuleKind; 6])> = {
+        use ModuleKind::*;
+        vec![module("misc.well", [That; 6])]
+    };
+}
+
+struct ModuleModel {
+    near: u64,
+    mask: u64,
+    vol: Arc<Structure>,
+}
+
+#[derive(Copy, Clone)]
+pub enum NearKind {
+    This,
+    That,
+}
+
+impl ModuleModel {
+    pub fn generate_list(details: &[(&str, &[([i32; 3], NearKind)])]) -> Vec<Self> {
+        unimplemented!()
+    }
 }
diff --git a/world/src/generator/town/vol.rs b/world/src/generator/town/vol.rs
index a3b0ddb6aa..27bcdd1a7a 100644
--- a/world/src/generator/town/vol.rs
+++ b/world/src/generator/town/vol.rs
@@ -48,6 +48,7 @@ pub enum CellKind {
     Road,
     Wall,
     House(usize),
+    Well,
 }
 
 #[derive(Clone, PartialEq)]