diff --git a/src/main/java/chylex/bettercontrols/config/BetterControlsConfig.java b/src/main/java/chylex/bettercontrols/config/BetterControlsConfig.java
index d7bab42..05f0330 100644
--- a/src/main/java/chylex/bettercontrols/config/BetterControlsConfig.java
+++ b/src/main/java/chylex/bettercontrols/config/BetterControlsConfig.java
@@ -11,6 +11,7 @@ public final class BetterControlsConfig{
 	
 	public boolean doubleTapForwardToSprint = true;
 	
+	public boolean flyOnGroundInCreative = false;
 	public float flightSpeedMpCreativeDefault = 1F;
 	public float flightSpeedMpCreativeSprinting = 2F;
 	public float flightSpeedMpSpectatorDefault = 1F;
diff --git a/src/main/java/chylex/bettercontrols/config/ConfigSerializer.java b/src/main/java/chylex/bettercontrols/config/ConfigSerializer.java
index b1a8c83..151c96b 100644
--- a/src/main/java/chylex/bettercontrols/config/ConfigSerializer.java
+++ b/src/main/java/chylex/bettercontrols/config/ConfigSerializer.java
@@ -32,6 +32,7 @@ final class ConfigSerializer implements JsonSerializer<BetterControlsConfig>, Js
 		
 		Json.setBool(obj, "Sprint.DoubleTapForward", cfg.doubleTapForwardToSprint);
 		
+		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);
 		Json.setFloat(obj, "Flight.SpeedMp.Spectator.Default", cfg.flightSpeedMpSpectatorDefault);
@@ -47,6 +48,7 @@ final class ConfigSerializer implements JsonSerializer<BetterControlsConfig>, Js
 		
 		cfg.doubleTapForwardToSprint = Json.getBool(obj, "Sprint.DoubleTapForward", cfg.doubleTapForwardToSprint);
 		
+		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);
 		cfg.flightSpeedMpSpectatorDefault = Json.getFloat(obj, "Flight.SpeedMp.Spectator.Default", cfg.flightSpeedMpSpectatorDefault);
diff --git a/src/main/java/chylex/bettercontrols/gui/BetterControlsScreen.java b/src/main/java/chylex/bettercontrols/gui/BetterControlsScreen.java
index a0231d9..a337c23 100644
--- a/src/main/java/chylex/bettercontrols/gui/BetterControlsScreen.java
+++ b/src/main/java/chylex/bettercontrols/gui/BetterControlsScreen.java
@@ -63,6 +63,11 @@ public class BetterControlsScreen extends GameOptionsScreen{
 			new Option<>(Float.valueOf(8.00F), Text.of("8x"))
 		);
 		
+		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));
+		
+		y += ROW_HEIGHT * 4 / 3;
+		
 		generateLeftSideText(y, elements, Text.of("Speed Multiplier (Creative)"));
 		elements.add(new DiscreteValueSliderWidget<>(col2(1), y, COL2_W, flightSpeedOptions, cfg.flightSpeedMpCreativeDefault, value -> cfg.flightSpeedMpCreativeDefault = value));
 		
diff --git a/src/main/java/chylex/bettercontrols/mixin/HookClientPlayerTick.java b/src/main/java/chylex/bettercontrols/mixin/HookClientPlayerTick.java
index faf2e62..998132b 100644
--- a/src/main/java/chylex/bettercontrols/mixin/HookClientPlayerTick.java
+++ b/src/main/java/chylex/bettercontrols/mixin/HookClientPlayerTick.java
@@ -27,4 +27,10 @@ public abstract class HookClientPlayerTick extends AbstractClientPlayerEntity{
 		final ClientPlayerEntity player = (ClientPlayerEntity)(Object)this;
 		PlayerTicker.get(player).afterInputTick(player);
 	}
+	
+	@Inject(method = "tickMovement()V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/AbstractClientPlayerEntity;tickMovement()V", ordinal = 0, shift = AFTER))
+	private void afterSuperCall(final CallbackInfo info){
+		final ClientPlayerEntity player = (ClientPlayerEntity)(Object)this;
+		PlayerTicker.get(player).afterSuperCall(player);
+	}
 }
diff --git a/src/main/java/chylex/bettercontrols/player/FlightHelper.java b/src/main/java/chylex/bettercontrols/player/FlightHelper.java
index d3e38d2..8324a68 100644
--- a/src/main/java/chylex/bettercontrols/player/FlightHelper.java
+++ b/src/main/java/chylex/bettercontrols/player/FlightHelper.java
@@ -13,6 +13,10 @@ final class FlightHelper{
 		return BetterControlsMod.config;
 	}
 	
+	static boolean shouldFlyOnGround(final ClientPlayerEntity player){
+		return cfg().flyOnGroundInCreative && player.isCreative() && player.abilities.flying;
+	}
+	
 	static float getFlightSpeed(final ClientPlayerEntity player){
 		if (player.isCreative()){
 			if (player.isSprinting()){
diff --git a/src/main/java/chylex/bettercontrols/player/PlayerTicker.java b/src/main/java/chylex/bettercontrols/player/PlayerTicker.java
index 3556287..f17f024 100644
--- a/src/main/java/chylex/bettercontrols/player/PlayerTicker.java
+++ b/src/main/java/chylex/bettercontrols/player/PlayerTicker.java
@@ -33,7 +33,14 @@ public final class PlayerTicker{
 	
 	// Logic
 	
+	private boolean wasSneakingBeforeTouchingGround = false;
+	private boolean holdingSneakWhileTouchingGround = false;
+	
 	public void atHead(final ClientPlayerEntity player){
+		if (FlightHelper.shouldFlyOnGround(player)){
+			player.setOnGround(false);
+		}
+		
 		if (!cfg().doubleTapForwardToSprint){
 			((AccessClientPlayerFields)player).setTicksLeftToDoubleTapSprint(0);
 		}
@@ -46,4 +53,44 @@ public final class PlayerTicker{
 			player.abilities.setFlySpeed(flightSpeed);
 		}
 	}
+	
+	public void afterSuperCall(final ClientPlayerEntity player){
+		if (FlightHelper.shouldFlyOnGround(player)){
+			final boolean isSneaking = player.isSneaking();
+			final boolean isOnGround = player.isOnGround();
+			
+			if (!isSneaking){
+				wasSneakingBeforeTouchingGround = false;
+			}
+			else if (!isOnGround){
+				wasSneakingBeforeTouchingGround = true;
+			}
+			
+			if (!isOnGround){
+				holdingSneakWhileTouchingGround = false;
+			}
+			else{
+				boolean cancelLanding = true;
+				
+				if (!wasSneakingBeforeTouchingGround){
+					if (isSneaking){
+						holdingSneakWhileTouchingGround = true;
+					}
+					else if (holdingSneakWhileTouchingGround){
+						player.abilities.flying = false;
+						player.sendAbilitiesUpdate();
+						cancelLanding = false;
+					}
+				}
+				
+				if (cancelLanding){
+					player.setOnGround(false);
+				}
+			}
+		}
+		else{
+			wasSneakingBeforeTouchingGround = false;
+			holdingSneakWhileTouchingGround = false;
+		}
+	}
 }