diff --git a/voxygen/src/scene/camera.rs b/voxygen/src/scene/camera.rs
index 01dda44cb8..1ffe1a1876 100644
--- a/voxygen/src/scene/camera.rs
+++ b/voxygen/src/scene/camera.rs
@@ -527,15 +527,19 @@ impl Camera {
     }
 
     /// Zoom the camera by the given delta, limiting the input accordingly.
-    pub fn zoom_by(&mut self, delta: f32) {
+    pub fn zoom_by(&mut self, delta: f32, cap: Option<f32>) {
         if self.mode == CameraMode::ThirdPerson {
             // Clamp camera dist to the 2 <= x <= infinity range
             self.tgt_dist = (self.tgt_dist + delta).max(2.0);
         }
+
+        if let Some(cap) = cap {
+            self.tgt_dist = self.tgt_dist.min(cap);
+        }
     }
 
     /// Zoom with the ability to switch between first and third-person mode.
-    pub fn zoom_switch(&mut self, delta: f32) {
+    pub fn zoom_switch(&mut self, delta: f32, cap: Option<f32>) {
         if delta > 0_f32 || self.mode != CameraMode::FirstPerson {
             let t = self.tgt_dist + delta;
             const MIN_THIRD_PERSON: f32 = 2.35;
@@ -554,6 +558,10 @@ impl Camera {
                 _ => {},
             }
         }
+
+        if let Some(cap) = cap {
+            self.tgt_dist = self.tgt_dist.min(cap);
+        }
     }
 
     /// Get the distance of the camera from the focus
@@ -679,13 +687,13 @@ impl Camera {
             self.mode = mode;
             match self.mode {
                 CameraMode::ThirdPerson => {
-                    self.zoom_by(5.0);
+                    self.zoom_by(5.0, None);
                 },
                 CameraMode::FirstPerson => {
                     self.set_distance(MIN_ZOOM);
                 },
                 CameraMode::Freefly => {
-                    self.zoom_by(0.0);
+                    self.zoom_by(0.0, None);
                 },
             }
         }
diff --git a/voxygen/src/scene/mod.rs b/voxygen/src/scene/mod.rs
index a25e6e598b..a666b2d407 100644
--- a/voxygen/src/scene/mod.rs
+++ b/voxygen/src/scene/mod.rs
@@ -340,7 +340,7 @@ impl Scene {
     /// window closed).
     ///
     /// If the event is handled, return true.
-    pub fn handle_input_event(&mut self, event: Event) -> bool {
+    pub fn handle_input_event(&mut self, event: Event, client: &Client) -> bool {
         match event {
             // When the window is resized, change the camera's aspect ratio
             Event::Resize(dims) => {
@@ -357,13 +357,16 @@ impl Scene {
                 // when zooming in the distance the camera travelles should be based on the
                 // final distance. This is to make sure the camera travelles the
                 // same distance when zooming in and out
+                let cap = (!client.is_moderator()).then_some(30.0);
                 if delta < 0.0 {
                     self.camera.zoom_switch(
+                        // Thank you Imbris for doing the math
                         delta * (0.05 + self.camera.get_distance() * 0.01) / (1.0 - delta * 0.01),
-                    ); // Thank you Imbris for doing the math
+                        cap,
+                    );
                 } else {
                     self.camera
-                        .zoom_switch(delta * (0.05 + self.camera.get_distance() * 0.01));
+                        .zoom_switch(delta * (0.05 + self.camera.get_distance() * 0.01), cap);
                 }
                 true
             },
@@ -643,9 +646,10 @@ impl Scene {
                 .state
                 .terrain()
                 .get((cam_pos + focus_off).map(|e| e.floor() as i32))
-                .map(|b| b.kind())
+                .ok()
                 // Don't block the camera's view in solid blocks if the player is a moderator
-                .filter(|b| !(b.is_filled() && self.client.is_moderator()))
+                .filter(|b| !(b.is_filled() && client.is_moderator()))
+                .map(|b| b.kind())
                 .unwrap_or(BlockKind::Air),
             self.select_pos.map(|e| e - focus_off.map(|e| e as i32)),
             scene_data.gamma,
diff --git a/voxygen/src/session/mod.rs b/voxygen/src/session/mod.rs
index ccfa85b6eb..7e74f38936 100644
--- a/voxygen/src/session/mod.rs
+++ b/voxygen/src/session/mod.rs
@@ -826,7 +826,10 @@ impl PlayState for SessionState {
                             self.key_state.analog_matrix.y = v;
                         },
                         other => {
-                            self.scene.handle_input_event(Event::AnalogGameInput(other));
+                            self.scene.handle_input_event(
+                                Event::AnalogGameInput(other),
+                                &self.client.borrow(),
+                            );
                         },
                     },
                     Event::ScreenshotMessage(screenshot_message) => {
@@ -838,7 +841,7 @@ impl PlayState for SessionState {
 
                     // Pass all other events to the scene
                     event => {
-                        self.scene.handle_input_event(event);
+                        self.scene.handle_input_event(event, &self.client.borrow());
                     }, // TODO: Do something if the event wasn't handled?
                 }
             }