diff --git a/src/main/java/chylex/bettercontrols/config/BetterControlsConfig.java b/src/main/java/chylex/bettercontrols/config/BetterControlsConfig.java
index a8d725a..4426b69 100644
--- a/src/main/java/chylex/bettercontrols/config/BetterControlsConfig.java
+++ b/src/main/java/chylex/bettercontrols/config/BetterControlsConfig.java
@@ -10,11 +10,14 @@ public final class BetterControlsConfig{
 	
 	private Path path;
 	
+	public final KeyBindingWithModifier keyToggleSprint = new KeyBindingWithModifier("key.bettercontrols.toggle_sprint");
 	public boolean doubleTapForwardToSprint = true;
 	public boolean resumeSprintingAfterHittingObstacle = false;
 	
+	public final KeyBindingWithModifier keyToggleSneak = new KeyBindingWithModifier("key.bettercontrols.toggle_sneak");
 	public boolean sneakingMovesCameraSmoothly = true;
 	
+	public final KeyBindingWithModifier keyToggleFlight = new KeyBindingWithModifier("key.bettercontrols.toggle_flight");
 	public boolean flyOnGroundInCreative = false;
 	public float flightSpeedMpCreativeDefault = 1F;
 	public float flightSpeedMpCreativeSprinting = 2F;
@@ -34,6 +37,9 @@ public final class BetterControlsConfig{
 	
 	public KeyBinding[] getAllKeyBindings(){
 		return new KeyBinding[]{
+			keyToggleSprint,
+			keyToggleSneak,
+			keyToggleFlight,
 			keyToggleWalkForward,
 			keyToggleJump,
 			keyOpenMenu
diff --git a/src/main/java/chylex/bettercontrols/config/ConfigSerializer.java b/src/main/java/chylex/bettercontrols/config/ConfigSerializer.java
index 5254ad4..d3fddd8 100644
--- a/src/main/java/chylex/bettercontrols/config/ConfigSerializer.java
+++ b/src/main/java/chylex/bettercontrols/config/ConfigSerializer.java
@@ -30,11 +30,14 @@ final class ConfigSerializer implements JsonSerializer<BetterControlsConfig>, Js
 	public JsonElement serialize(final BetterControlsConfig cfg, final Type typeOfSrc, final JsonSerializationContext context){
 		final JsonObject obj = new JsonObject();
 		
+		Json.writeKeyBinding(obj, "Sprint.KeyToggle", cfg.keyToggleSprint);
 		Json.setBool(obj, "Sprint.DoubleTapForward", cfg.doubleTapForwardToSprint);
 		Json.setBool(obj, "Sprint.ResumeAfterHittingObstacle", cfg.resumeSprintingAfterHittingObstacle);
 		
+		Json.writeKeyBinding(obj, "Sneak.KeyToggle", cfg.keyToggleSneak);
 		Json.setBool(obj, "Sneak.SmoothCamera", cfg.sneakingMovesCameraSmoothly);
 		
+		Json.writeKeyBinding(obj, "Flight.KeyToggle.Creative", cfg.keyToggleFlight);
 		Json.setBool(obj, "Flight.FlyOnGround.Creative", cfg.flyOnGroundInCreative);
 		Json.setFloat(obj, "Flight.SpeedMp.Creative.Default", cfg.flightSpeedMpCreativeDefault);
 		Json.setFloat(obj, "Flight.SpeedMp.Creative.Sprinting", cfg.flightSpeedMpCreativeSprinting);
@@ -53,11 +56,14 @@ final class ConfigSerializer implements JsonSerializer<BetterControlsConfig>, Js
 		final BetterControlsConfig cfg = new BetterControlsConfig();
 		final JsonObject obj = json.getAsJsonObject();
 		
+		Json.readKeyBinding(obj, "Sprint.KeyToggle", cfg.keyToggleSprint);
 		cfg.doubleTapForwardToSprint = Json.getBool(obj, "Sprint.DoubleTapForward", cfg.doubleTapForwardToSprint);
 		cfg.resumeSprintingAfterHittingObstacle = Json.getBool(obj, "Sprint.ResumeAfterHittingObstacle", cfg.resumeSprintingAfterHittingObstacle);
 		
+		Json.readKeyBinding(obj, "Sneak.KeyToggle", cfg.keyToggleSneak);
 		cfg.sneakingMovesCameraSmoothly = Json.getBool(obj, "Sneak.SmoothCamera", cfg.sneakingMovesCameraSmoothly);
 		
+		Json.readKeyBinding(obj, "Flight.KeyToggle.Creative", cfg.keyToggleFlight);
 		cfg.flyOnGroundInCreative = Json.getBool(obj, "Flight.FlyOnGround.Creative", cfg.flyOnGroundInCreative);
 		cfg.flightSpeedMpCreativeDefault = Json.getFloat(obj, "Flight.SpeedMp.Creative.Default", cfg.flightSpeedMpCreativeDefault);
 		cfg.flightSpeedMpCreativeSprinting = Json.getFloat(obj, "Flight.SpeedMp.Creative.Sprinting", cfg.flightSpeedMpCreativeSprinting);
diff --git a/src/main/java/chylex/bettercontrols/gui/BetterControlsScreen.java b/src/main/java/chylex/bettercontrols/gui/BetterControlsScreen.java
index ebadc7a..6e989a8 100644
--- a/src/main/java/chylex/bettercontrols/gui/BetterControlsScreen.java
+++ b/src/main/java/chylex/bettercontrols/gui/BetterControlsScreen.java
@@ -44,6 +44,10 @@ public class BetterControlsScreen extends GameOptionsScreen{
 	private int generateSprintingOptions(int y, final List<Element> elements){
 		final BetterControlsConfig cfg = BetterControlsMod.config;
 		
+		generateKeyBindingWithModifierOption(y, elements, Text.of("Toggle Sprint"), cfg.keyToggleSprint);
+		
+		y += ROW_HEIGHT;
+		
 		generateLeftSideText(y, elements, Text.of("Double Tap 'Walk Forwards' To Sprint"));
 		elements.add(new BooleanValueWidget(col2(1), y, COL2_W, cfg.doubleTapForwardToSprint, value -> cfg.doubleTapForwardToSprint = value));
 		
@@ -59,6 +63,10 @@ public class BetterControlsScreen extends GameOptionsScreen{
 	private int generateSneakingOptions(int y, final List<Element> elements){
 		final BetterControlsConfig cfg = BetterControlsMod.config;
 		
+		generateKeyBindingWithModifierOption(y, elements, Text.of("Toggle Sneak"), cfg.keyToggleSneak);
+		
+		y += ROW_HEIGHT;
+		
 		generateLeftSideText(y, elements, Text.of("Move Camera Smoothly"));
 		elements.add(new BooleanValueWidget(col2(1), y, COL2_W, cfg.sneakingMovesCameraSmoothly, value -> cfg.sneakingMovesCameraSmoothly = value));
 		
@@ -83,6 +91,10 @@ public class BetterControlsScreen extends GameOptionsScreen{
 			new Option<>(Float.valueOf(8.00F), Text.of("8x"))
 		);
 		
+		generateKeyBindingWithModifierOption(y, elements, Text.of("Toggle Flight (Creative)"), cfg.keyToggleFlight);
+		
+		y += ROW_HEIGHT;
+		
 		generateLeftSideText(y, elements, Text.of("Fly On Ground (Creative Mode)"));
 		elements.add(new BooleanValueWidget(col2(1), y, COL2_W, cfg.flyOnGroundInCreative, value -> cfg.flyOnGroundInCreative = value));
 		
diff --git a/src/main/java/chylex/bettercontrols/player/PlayerTicker.java b/src/main/java/chylex/bettercontrols/player/PlayerTicker.java
index 442ff5d..8b29478 100644
--- a/src/main/java/chylex/bettercontrols/player/PlayerTicker.java
+++ b/src/main/java/chylex/bettercontrols/player/PlayerTicker.java
@@ -3,11 +3,13 @@ import chylex.bettercontrols.BetterControlsMod;
 import chylex.bettercontrols.config.BetterControlsConfig;
 import chylex.bettercontrols.gui.BetterControlsScreen;
 import chylex.bettercontrols.input.ToggleTracker;
+import chylex.bettercontrols.input.ToggleTrackerForStickyKey;
 import chylex.bettercontrols.mixin.AccessCameraFields;
 import chylex.bettercontrols.mixin.AccessClientPlayerFields;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.input.KeyboardInput;
 import net.minecraft.client.network.ClientPlayerEntity;
+import net.minecraft.client.options.GameOptions;
 import java.lang.ref.WeakReference;
 
 public final class PlayerTicker{
@@ -37,14 +39,18 @@ public final class PlayerTicker{
 	
 	// Logic
 	
+	private final ToggleTracker toggleSprint = new ToggleTrackerForStickyKey(cfg().keyToggleSprint, mc().options.keySprint, toggled -> mc().options.sprintToggled = toggled);
+	private final ToggleTracker toggleSneak = new ToggleTrackerForStickyKey(cfg().keyToggleSneak, mc().options.keySneak, toggled -> mc().options.sneakToggled = toggled);
 	private final ToggleTracker toggleWalkForward = new ToggleTracker(cfg().keyToggleWalkForward, mc().options.keyForward);
 	private final ToggleTracker toggleJump = new ToggleTracker(cfg().keyToggleJump, mc().options.keyJump);
 	
+	private boolean stopSprintingAfterReleasingSprintKey = false;
 	private boolean wasHittingObstacle = false;
 	private boolean wasSprintingBeforeHittingObstacle = false;
 	
 	private boolean wasSneakingBeforeTouchingGround = false;
 	private boolean holdingSneakWhileTouchingGround = false;
+	private int temporaryFlyOnGroundTimer = 0;
 	
 	public void atHead(final ClientPlayerEntity player){
 		if (FlightHelper.shouldFlyOnGround(player)){
@@ -54,6 +60,24 @@ public final class PlayerTicker{
 		if (!cfg().doubleTapForwardToSprint){
 			((AccessClientPlayerFields)player).setTicksLeftToDoubleTapSprint(0);
 		}
+		
+		final GameOptions opts = mc().options;
+		final boolean wasSprintToggled = opts.sprintToggled;
+		final boolean isSprintToggled = toggleSprint.tick();
+		
+		if (isSprintToggled){
+			stopSprintingAfterReleasingSprintKey = false;
+		}
+		else if (wasSprintToggled){
+			stopSprintingAfterReleasingSprintKey = true;
+		}
+		
+		if (stopSprintingAfterReleasingSprintKey && !opts.keySprint.isPressed()){
+			stopSprintingAfterReleasingSprintKey = false;
+			player.setSprinting(false);
+		}
+		
+		toggleSneak.tick();
 	}
 	
 	public void afterInputAssignsPressingForward(final KeyboardInput input){
@@ -132,6 +156,32 @@ public final class PlayerTicker{
 			holdingSneakWhileTouchingGround = false;
 		}
 		
+		if (player.isCreative()){
+			if (cfg().keyToggleFlight.wasPressed()){
+				final boolean isFlying = !player.abilities.flying;
+				
+				player.abilities.flying = isFlying;
+				player.sendAbilitiesUpdate();
+				
+				if (isFlying){
+					temporaryFlyOnGroundTimer = 10;
+				}
+			}
+			
+			if (temporaryFlyOnGroundTimer > 0){
+				if (player.isSneaking()){
+					temporaryFlyOnGroundTimer = 0;
+				}
+				else{
+					--temporaryFlyOnGroundTimer;
+					player.setOnGround(false);
+				}
+			}
+		}
+		else{
+			temporaryFlyOnGroundTimer = 0;
+		}
+		
 		if (!cfg().sneakingMovesCameraSmoothly){
 			final AccessCameraFields camera = (AccessCameraFields)mc().gameRenderer.getCamera();
 			
diff --git a/src/main/resources/assets/bettercontrols/lang/en_us.json b/src/main/resources/assets/bettercontrols/lang/en_us.json
index 83f8e94..160efaf 100644
--- a/src/main/resources/assets/bettercontrols/lang/en_us.json
+++ b/src/main/resources/assets/bettercontrols/lang/en_us.json
@@ -1,5 +1,8 @@
 {
   "key.categories.bettercontrols": "Better Controls",
+  "key.bettercontrols.toggle_sprint": "Toggle Sprint",
+  "key.bettercontrols.toggle_sneak": "Toggle Sneak",
+  "key.bettercontrols.toggle_flight": "Toggle Flight",
   "key.bettercontrols.toggle_forward": "Toggle Walk Forwards",
   "key.bettercontrols.toggle_jump": "Toggle Jump",
   "key.bettercontrols.open_menu": "Open Menu"