diff --git a/CHANGELOG.md b/CHANGELOG.md
index d8905696a9..6fd598c87b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -68,6 +68,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - Significantly improved terrain generation performance
 - Significantly stabilized the game clock, to produce more "constant" TPS
 - Transitioned main menu and character selection screen to a using iced for the ui (fixes paste keybinding on macos, removes password field limits, adds tabbing between input fields in the main menu, adds language selection in the main menu)
+- Made settings less likely to reset when the format changes
+- Adjusted some keybindings
 
 ### Removed
 
diff --git a/voxygen/src/controller.rs b/voxygen/src/controller.rs
index 86f3020a3f..172353c110 100644
--- a/voxygen/src/controller.rs
+++ b/voxygen/src/controller.rs
@@ -7,7 +7,8 @@ use hashbrown::HashMap;
 use serde::{Deserialize, Serialize};
 
 /// Contains all controller related settings and keymaps
-#[derive(Clone, Debug, Serialize, Deserialize)]
+#[derive(Clone, Debug, Serialize, Deserialize, Default)]
+#[serde(default)]
 pub struct ControllerSettings {
     pub game_button_map: HashMap<Button, Vec<GameInput>>,
     pub menu_button_map: HashMap<Button, Vec<MenuInput>>,
@@ -285,6 +286,10 @@ pub enum Button {
     EventCode(u32),
 }
 
+impl Default for Button {
+    fn default() -> Self { Button::Simple(GilButton::Unknown) }
+}
+
 /// AnalogButton::Simple(GilButton::Unknown) is invalid and equal to mapping an
 /// action to nothing
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
@@ -293,6 +298,10 @@ pub enum AnalogButton {
     EventCode(u32),
 }
 
+impl Default for AnalogButton {
+    fn default() -> Self { AnalogButton::Simple(GilButton::Unknown) }
+}
+
 /// Axis::Simple(GilAxis::Unknown) is invalid and equal to mapping an action to
 /// nothing
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
@@ -301,6 +310,10 @@ pub enum Axis {
     EventCode(u32),
 }
 
+impl Default for Axis {
+    fn default() -> Self { Axis::Simple(GilAxis::Unknown) }
+}
+
 impl From<(GilAxis, GilCode)> for Axis {
     fn from((axis, code): (GilAxis, GilCode)) -> Self {
         match axis {
diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs
index ffc344d3ac..1ccf95d029 100644
--- a/voxygen/src/hud/mod.rs
+++ b/voxygen/src/hud/mod.rs
@@ -381,43 +381,50 @@ pub enum Windows {
 
 #[derive(Clone, Copy, Debug, Serialize, Deserialize)]
 pub enum CrosshairType {
-    Round,
     RoundEdges,
     Edges,
+    #[serde(other)]
+    Round,
 }
 #[derive(Clone, Copy, Debug, Serialize, Deserialize)]
 pub enum Intro {
-    Show,
     Never,
+    #[serde(other)]
+    Show,
 }
 #[derive(Clone, Copy, Debug, Serialize, Deserialize)]
 pub enum XpBar {
-    Always,
     OnGain,
+    #[serde(other)]
+    Always,
 }
 
 #[derive(Clone, Copy, Debug, Serialize, Deserialize)]
 pub enum BarNumbers {
-    Values,
     Percent,
     Off,
+    #[serde(other)]
+    Values,
 }
 #[derive(Clone, Copy, Debug, Serialize, Deserialize)]
 pub enum ShortcutNumbers {
-    On,
     Off,
+    #[serde(other)]
+    On,
 }
 
 #[derive(Clone, Copy, Debug, Serialize, Deserialize)]
 pub enum BuffPosition {
-    Bar,
     Map,
+    #[serde(other)]
+    Bar,
 }
 
 #[derive(Clone, Copy, Debug, Serialize, Deserialize)]
 pub enum PressBehavior {
-    Toggle = 0,
     Hold = 1,
+    #[serde(other)]
+    Toggle = 0,
 }
 
 pub struct Show {
diff --git a/voxygen/src/render/mod.rs b/voxygen/src/render/mod.rs
index 61077b19a6..4e2224b3b8 100644
--- a/voxygen/src/render/mod.rs
+++ b/voxygen/src/render/mod.rs
@@ -67,7 +67,6 @@ use serde::{Deserialize, Serialize};
 /// Anti-aliasing modes
 #[derive(PartialEq, Clone, Copy, Debug, Serialize, Deserialize)]
 pub enum AaMode {
-    None,
     /// Fast approximate antialiasing.
     ///
     /// This is a screen-space technique, and therefore works fine with greedy
@@ -99,6 +98,8 @@ pub enum AaMode {
     /// meshing that (without significantly more work) invalidate the
     /// GPU's assumptions about importance sampling.
     SsaaX4,
+    #[serde(other)]
+    None,
 }
 
 impl Default for AaMode {
@@ -140,8 +141,9 @@ pub enum CloudMode {
     ///   future that player better with the GPU.
     Minimal,
     Low,
-    Medium,
     High,
+    #[serde(other)]
+    Medium,
 }
 
 impl Default for CloudMode {
@@ -171,6 +173,7 @@ pub enum FluidMode {
     /// Another issue is that we don't always know whether light is *blocked*,
     /// which causes attenuation to be computed incorrectly; this can be
     /// addressed by using shadow maps (at least for terrain).
+    #[serde(other)]
     Shiny,
 }
 
@@ -187,15 +190,16 @@ pub enum LightingMode {
     /// This model may not work as well with purely directional lighting, and is
     /// more expensive than the other models.
     Ashikhmin,
-    /// Standard Blinn-Phong shading, combing Lambertian diffuse reflections and
-    /// specular highlights.
-    BlinnPhong,
     /// Standard Lambertian lighting model, with only diffuse reflections.  The
     /// cheapest lighting model by a decent margin, but the performance
     /// difference between it and Blinn-Phong will probably only be
     /// significant on low-end machines that are bottlenecked on fragment
     /// shading.
     Lambertian,
+    /// Standard Blinn-Phong shading, combing Lambertian diffuse reflections and
+    /// specular highlights.
+    #[serde(other)]
+    BlinnPhong,
 }
 
 impl Default for LightingMode {
@@ -220,15 +224,16 @@ impl Default for ShadowMapMode {
 pub enum ShadowMode {
     /// No shadows at all.  By far the cheapest option.
     None,
+    /// Shadow map (render the scene from each light source, and also renders
+    /// LOD shadows using horizon maps).
+    Map(ShadowMapMode),
     /// Point shadows (draw circles under figures, up to a configured maximum;
     /// also render LOD shadows using horizon maps).  Can be expensive on
     /// some machines, probably mostly due to horizon mapping; the point
     /// shadows are not rendered too efficiently, but that can probably
     /// be addressed later.
+    #[serde(other)] // Would normally be on `Map`, but only allowed on unit variants
     Cheap,
-    /// Shadow map (render the scene from each light source, and also renders
-    /// LOD shadows using horizon maps).
-    Map(ShadowMapMode),
 }
 
 impl Default for ShadowMode {
@@ -254,15 +259,11 @@ impl ShadowMode {
 
 /// Render modes
 #[derive(PartialEq, Clone, Debug, Default, Serialize, Deserialize)]
+#[serde(default)]
 pub struct RenderMode {
-    #[serde(default)]
     pub aa: AaMode,
-    #[serde(default)]
     pub cloud: CloudMode,
-    #[serde(default)]
     pub fluid: FluidMode,
-    #[serde(default)]
     pub lighting: LightingMode,
-    #[serde(default)]
     pub shadow: ShadowMode,
 }
diff --git a/voxygen/src/settings.rs b/voxygen/src/settings.rs
index e74be75932..49d166fe47 100644
--- a/voxygen/src/settings.rs
+++ b/voxygen/src/settings.rs
@@ -120,7 +120,7 @@ impl ControlSettings {
         match game_input {
             GameInput::Primary => KeyMouse::Mouse(MouseButton::Left),
             GameInput::Secondary => KeyMouse::Mouse(MouseButton::Right),
-            GameInput::ToggleCursor => KeyMouse::Key(VirtualKeyCode::Tab),
+            GameInput::ToggleCursor => KeyMouse::Key(VirtualKeyCode::Caret),
             GameInput::Escape => KeyMouse::Key(VirtualKeyCode::Escape),
             GameInput::Chat => KeyMouse::Key(VirtualKeyCode::Return),
             GameInput::Command => KeyMouse::Key(VirtualKeyCode::Slash),
@@ -136,7 +136,7 @@ impl ControlSettings {
             GameInput::ClimbDown => KeyMouse::Key(VirtualKeyCode::LControl),
             GameInput::SwimUp => KeyMouse::Key(VirtualKeyCode::Space),
             GameInput::SwimDown => KeyMouse::Key(VirtualKeyCode::LShift),
-            GameInput::Fly => KeyMouse::Key(VirtualKeyCode::F),
+            GameInput::Fly => KeyMouse::Key(VirtualKeyCode::H),
             GameInput::Sneak => KeyMouse::Key(VirtualKeyCode::LControl),
             //GameInput::WallLeap => MIDDLE_CLICK_KEY,
             GameInput::ToggleLantern => KeyMouse::Key(VirtualKeyCode::G),
@@ -171,7 +171,7 @@ impl ControlSettings {
             GameInput::Slot8 => KeyMouse::Key(VirtualKeyCode::Key8),
             GameInput::Slot9 => KeyMouse::Key(VirtualKeyCode::Key9),
             GameInput::Slot10 => KeyMouse::Key(VirtualKeyCode::Q),
-            GameInput::SwapLoadout => KeyMouse::Key(VirtualKeyCode::LAlt),
+            GameInput::SwapLoadout => KeyMouse::Key(VirtualKeyCode::Tab),
             GameInput::Select => KeyMouse::Key(VirtualKeyCode::Y),
             GameInput::AcceptGroupInvite => KeyMouse::Key(VirtualKeyCode::U),
             GameInput::DeclineGroupInvite => KeyMouse::Key(VirtualKeyCode::I),
@@ -540,7 +540,7 @@ impl Default for GameplaySettings {
             intro_show: Intro::Show,
             xp_bar: XpBar::Always,
             shortcut_numbers: ShortcutNumbers::On,
-            buff_position: BuffPosition::Map,
+            buff_position: BuffPosition::Bar,
             bar_numbers: BarNumbers::Values,
             ui_scale: ScaleMode::RelativeToWindow([1920.0, 1080.0].into()),
             free_look_behavior: PressBehavior::Toggle,
@@ -654,8 +654,9 @@ pub enum AudioOutput {
     // If this option is disabled, functions in the rodio
     // library MUST NOT be called.
     Off,
-    Automatic,
     Device(String),
+    #[serde(other)]
+    Automatic,
 }
 
 impl AudioOutput {
diff --git a/voxygen/src/ui/scale.rs b/voxygen/src/ui/scale.rs
index 6b7ecfde42..ae9916e4a2 100644
--- a/voxygen/src/ui/scale.rs
+++ b/voxygen/src/ui/scale.rs
@@ -7,12 +7,14 @@ use vek::*;
 pub enum ScaleMode {
     // Scale against physical size.
     Absolute(f64),
-    // Use the dpi factor provided by the windowing system (i.e. use logical size).
-    DpiFactor,
     // Scale based on the window's physical size, but maintain aspect ratio of widgets.
     // Contains width and height of the "default" window size (ie where there should be no
     // scaling).
     RelativeToWindow(Vec2<f64>),
+    // Use the dpi factor provided by the windowing system (i.e. use logical size).
+    #[serde(other)]
+    // Would be `RelativeToWindow([1920.0, 1080.0].into())`, but only supported on unit variants
+    DpiFactor,
 }
 
 #[derive(Clone, Copy)]
diff --git a/voxygen/src/window.rs b/voxygen/src/window.rs
index eba4675f8c..d6a33c2458 100644
--- a/voxygen/src/window.rs
+++ b/voxygen/src/window.rs
@@ -1388,6 +1388,7 @@ impl Window {
 #[derive(Copy, Clone, Hash, Eq, PartialEq, Debug, Serialize, Deserialize)]
 pub enum FullscreenMode {
     Exclusive,
+    #[serde(other)]
     Borderless,
 }
 
@@ -1395,6 +1396,7 @@ impl Default for FullscreenMode {
     fn default() -> Self { FullscreenMode::Borderless }
 }
 #[derive(PartialEq, Clone, Copy, Debug, Serialize, Deserialize)]
+#[serde(default)]
 pub struct FullScreenSettings {
     pub enabled: bool,
     pub mode: FullscreenMode,