diff --git framework/Console.cpp framework/Console.cpp
index 7f68858..f139421 100644
--- framework/Console.cpp
+++ framework/Console.cpp
@@ -425,7 +425,6 @@ void idConsoleLocal::Close() {
 	displayFrac = 0;	// don't scroll to that point, go immediately
 
 	ClearNotifyLines();
-	cv_tdm_creep_toggle.SetBool( 0 );
 }
 
 /*
diff --git framework/UsercmdGen.cpp framework/UsercmdGen.cpp
index 33eefe8..50591be 100644
--- framework/UsercmdGen.cpp
+++ framework/UsercmdGen.cpp
@@ -164,7 +164,6 @@ userCmdString_t	userCmdStrings[] = {
 	// self-explanatory names
 	{ "_jump",			UB_UP },
 	{ "_parry",			UB_PARRY_MANIPULATE },
-	{ "_creep",			UB_CREEP },
 
 	{ "_weapon0",		UB_WEAPON0 },
 	{ "_weapon1",		UB_WEAPON1 },
@@ -198,6 +197,7 @@ userCmdString_t	userCmdStrings[] = {
 	{ "_inventory_group_next", UB_INVENTORY_GROUP_NEXT },
 	{ "_inventory_use",	UB_INVENTORY_USE },
 	{ "_inventory_drop",	UB_INVENTORY_DROP },
+	{ "_creep",	UB_CREEP },
 
 	// legacy names
 	{ "_moveUp",		UB_UP },
@@ -223,7 +223,7 @@ userCmdString_t	userCmdStrings[] = {
 	{ "_button2",		UB_BUTTON2 },
 	{ "_button3",		UB_BUTTON3 },
 	{ "_button4",		UB_BUTTON4 },
-	{ "_button5",		UB_CREEP },
+	{ "_button5",		UB_BUTTON5 },
 	{ "_button6",		UB_BUTTON6 },
 	{ "_button7",		UB_BUTTON7 },
 
@@ -280,7 +280,7 @@ userCmdString_t	userCmdStrings[] = {
 	{ "_impulse50",		UB_INVENTORY_GROUP_NEXT },
 	{ "_impulse51",		UB_INVENTORY_USE },
 	{ "_impulse52",		UB_INVENTORY_DROP },
-	{ "_impulse53",		UB_IMPULSE53 },
+	{ "_impulse53",		UB_CREEP },
 	{ "_impulse54",		UB_IMPULSE54 },
 	{ "_impulse55",		UB_IMPULSE55 },
 	{ "_impulse56",		UB_IMPULSE56 },
diff --git framework/UsercmdGen.h framework/UsercmdGen.h
index 03132d6..ab6d74e 100644
--- framework/UsercmdGen.h
+++ framework/UsercmdGen.h
@@ -49,7 +49,7 @@ typedef enum {
    UB_BUTTON2,
    UB_BUTTON3,
    UB_BUTTON4,
-   UB_CREEP,
+   UB_BUTTON5,
    UB_BUTTON6,
    UB_BUTTON7,
 
@@ -118,7 +118,7 @@ typedef enum {
    UB_INVENTORY_GROUP_NEXT,
    UB_INVENTORY_USE,
    UB_INVENTORY_DROP,
-   UB_IMPULSE53,
+   UB_CREEP,
    UB_IMPULSE54,
    UB_IMPULSE55,
    UB_IMPULSE56,
@@ -140,7 +140,7 @@ const int BUTTON_RUN			= BIT(1);
 const int BUTTON_ZOOM			= BIT(2);
 const int BUTTON_SCORES			= BIT(3);
 const int BUTTON_MLOOK			= BIT(4);
-const int BUTTON_CREEP			= BIT(5);
+const int BUTTON_5			= BIT(5);
 const int BUTTON_6				= BIT(6);
 const int BUTTON_7				= BIT(7);
 
@@ -190,6 +190,7 @@ enum {
 	IMPULSE_INVENTORY_GROUP_NEXT,
 	IMPULSE_INVENTORY_USE,
 	IMPULSE_INVENTORY_DROP,
+	IMPULSE_CREEP,
 	IMPULSE_MAX
 };
 
diff --git game/Grabber.cpp game/Grabber.cpp
index 8cabe6e..27ff7ca 100755
--- game/Grabber.cpp
+++ game/Grabber.cpp
@@ -378,7 +378,7 @@ void CGrabber::Update( idPlayer *player, bool hold, bool preservePosition )
 		//stgatilov #5599: new grabber, detect if we should set silent mode
 		switch (cv_drag_rigid_silentmode.GetInteger()) {
 			case 1:
-				if (player->usercmd.buttons & BUTTON_CREEP)
+				if (player->m_CreepIntent)
 					m_silentMode = true;
 				break;
 			case 2:
diff --git game/Player.cpp game/Player.cpp
index 2dc7dab..f9af53c 100644
--- game/Player.cpp
+++ game/Player.cpp
@@ -718,6 +718,8 @@ idPlayer::idPlayer() :
 	m_CrouchIntent			= false;
 	m_CrouchToggleBypassed	= false;
 
+	m_CreepIntent			= false;
+
 	m_LeanButtonTimeStamp	= 0;
 	m_InventoryOverlay		= -1;
 	objectivesOverlay		= -1;
@@ -2329,6 +2331,8 @@ void idPlayer::Save( idSaveGame *savefile ) const {
 	savefile->WriteBool( m_IdealCrouchState );
 	savefile->WriteBool( m_CrouchIntent );
 
+	savefile->WriteBool( m_CreepIntent );
+
 	savefile->WriteInt(m_InventoryOverlay);
 
 	savefile->WriteInt(m_WaitUntilReadyGuiHandle);
@@ -2678,6 +2682,8 @@ void idPlayer::Restore( idRestoreGame *savefile ) {
 	// stgatilov: no need to save it, but better reset it on load
 	m_CrouchToggleBypassed = false;
 
+	savefile->ReadBool( m_CreepIntent );
+
 	savefile->ReadInt(m_InventoryOverlay);
 
 	savefile->ReadInt(m_WaitUntilReadyGuiHandle);
@@ -3434,12 +3440,12 @@ void idPlayer::UpdateConditions( void )
 	AI_DEAD			= ( health <= 0 );
 	
 	// DarkMod: Catch the creep modifier
-	if (cv_tdm_creep_toggle.GetBool()){
+	if (m_CreepIntent) {
 		AI_CREEP = true;
 	}
 	else {
 		int creepLimit = cv_pm_creepmod.GetFloat() * 127;
-		AI_CREEP = (usercmd.buttons & BUTTON_CREEP) ||
+		AI_CREEP = m_CreepIntent ||
 			(idMath::Abs(usercmd.forwardmove) <= creepLimit && idMath::Abs(usercmd.rightmove) <= creepLimit);
 	}
 }
@@ -4934,7 +4940,7 @@ void idPlayer::BobCycle( const idVec3 &pushVelocity ) {
 		}
 
 		// greebo: is the player creeping? (Only kicks in when not running, run key cancels out creep key)
-		if ( (cv_tdm_creep_toggle.GetBool() || (usercmd.buttons & BUTTON_CREEP)) && !(usercmd.buttons & BUTTON_RUN)) 
+		if ( m_CreepIntent && !(usercmd.buttons & BUTTON_RUN) )
 		{
 			bobmove *= 0.5f * (1 - bobFrac);
 		}
@@ -5711,6 +5717,24 @@ void idPlayer::PerformImpulse( int impulse ) {
 		}
 		break;
 
+		case IMPULSE_CREEP:		// Creep
+		{
+			if (cv_tdm_toggle_creep.GetBool())
+			{
+					if (entityNumber == gameLocal.localClientNum)
+					{
+						m_CreepIntent = !m_CreepIntent;
+					}
+			}
+			else
+			{
+				m_CreepIntent = true;
+			}
+
+			m_ButtonStateTracker.StartTracking(impulse);
+		}
+		break;
+
 		case IMPULSE_MANTLE:
 		{
 			if ( entityNumber == gameLocal.localClientNum )
@@ -6048,6 +6072,13 @@ void idPlayer::PerformKeyRelease(int impulse, int holdTime)
 
 		break;
 
+		case IMPULSE_CREEP:		// TDM creep
+			if (!cv_tdm_toggle_creep.GetBool())
+			{
+				m_CreepIntent = false;
+			}
+		break;
+
 		case IMPULSE_FROB:		// TDM Use/Frob
 		{
 			PerformFrobKeyRelease(holdTime);
@@ -6467,7 +6498,7 @@ void idPlayer::AdjustSpeed( void )
 			speed = pm_noclipspeed.GetFloat() * cv_pm_runmod.GetFloat();
 			bobFrac = 0.0f;
 		} 
-		else if ((usercmd.buttons & BUTTON_CREEP) || cv_tdm_creep_toggle.GetBool())
+		else if (m_CreepIntent)
 		{
 			// slow "creep" noclip
 			speed = pm_noclipspeed.GetFloat() * cv_pm_creepmod.GetFloat();
@@ -6488,8 +6519,7 @@ void idPlayer::AdjustSpeed( void )
 
 		speed = walkSpeed * cv_pm_runmod.GetFloat();
 		// apply creep modifier; creep is on button_5
-		const bool bCreeping = (usercmd.buttons & BUTTON_CREEP) || cv_tdm_creep_toggle.GetBool();
-		if (bCreeping)
+		if (m_CreepIntent)
 		{
 			speed *= (cv_pm_running_creepmod.GetFloat());
 		}
@@ -6527,9 +6557,8 @@ void idPlayer::AdjustSpeed( void )
 		speed = pm_walkspeed.GetFloat();
 		bobFrac = 0.0f;
 
-		// apply creep modifier; creep is on button_5
-		const bool bCreeping = (usercmd.buttons & BUTTON_CREEP) || cv_tdm_creep_toggle.GetBool();
-		if(bCreeping)
+		// apply creep modifier
+		if (m_CreepIntent)
 		{
 			speed *= cv_pm_creepmod.GetFloat();
 		}		
@@ -6537,7 +6566,7 @@ void idPlayer::AdjustSpeed( void )
 		// STiFU #1932: Apply hinderance not only to max speed but to all speeds.
 		if (cv_pm_softhinderance_active.GetBool())
 		{
-			if (bCreeping)
+			if (m_CreepIntent)
 			{
 				speed *= (cv_pm_softhinderance_creep.GetFloat() * fCurrentHinderance 
 					+ 1.0f - cv_pm_softhinderance_creep.GetFloat());
diff --git game/Player.h game/Player.h
index 228d48f..a51a589 100644
--- game/Player.h
+++ game/Player.h
@@ -396,6 +396,10 @@ public:
 	// player has pressed toggle crouch while on a rope or ladder/vine.
 	bool					m_CrouchToggleBypassed;
 
+	// Daft Mugi: For new toggle creep, this is set to true when the
+	// player is holding the creep button or toggle creep is active.
+	bool					m_CreepIntent;
+
 	// STiFU: FrobHelper alpha calculation
 	CFrobHelper				m_FrobHelper;
 
diff --git game/gamesys/SysCvar.cpp game/gamesys/SysCvar.cpp
index 05a15de..0bc7994 100644
--- game/gamesys/SysCvar.cpp
+++ game/gamesys/SysCvar.cpp
@@ -253,7 +253,7 @@ idCVar cv_tdm_crouch_toggle_hold_time(	"tdm_crouch_toggle_hold_time",	"400",			C
 idCVar cv_tdm_reattach_delay(			"tdm_reattach_delay",			"100",			CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Delay (in ms) for reattaching to ropes/ladders after detaching using crouch." );
 
 // nbohr1more: #558 Toggle Creep
-idCVar cv_tdm_creep_toggle(			    "tdm_toggle_creep",			"0",			CVAR_GAME | CVAR_BOOL, "Set to 1 to make creep toggleable." );
+idCVar cv_tdm_toggle_creep(			    "tdm_toggle_creep",			"0",			CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "Set to 1 to make creep toggleable." );
 
 // #6232: Player choice of sheathe key behavior
 idCVar cv_tdm_toggle_sheathe(
diff --git game/gamesys/SysCvar.h game/gamesys/SysCvar.h
index 708363f..0d558ff 100644
--- game/gamesys/SysCvar.h
+++ game/gamesys/SysCvar.h
@@ -222,7 +222,7 @@ extern idCVar cv_tdm_crouch_toggle_hold_time;
 extern idCVar cv_tdm_reattach_delay;
 
 // nbohr1more: #558 TDM toggle creep
-extern idCVar cv_tdm_creep_toggle;
+extern idCVar cv_tdm_toggle_creep;
 
 // #6232: Player choice of sheathe key behavior
 extern idCVar cv_tdm_toggle_sheathe;
diff --git game/physics/Physics_Player.cpp game/physics/Physics_Player.cpp
index f3aa820..e610f28 100644
--- game/physics/Physics_Player.cpp
+++ game/physics/Physics_Player.cpp
@@ -915,7 +915,7 @@ void idPhysics_Player::PlaySwimBurstSound()
 		return;
 
 	// speed mod
-	if ((pPlayer->usercmd.buttons & BUTTON_CREEP) || cv_tdm_creep_toggle.GetBool())
+	if (pPlayer->m_CreepIntent)
 	{
 		sSound += "_creep";
 	} else if (pPlayer->usercmd.buttons & BUTTON_RUN)
