diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 6dbb483590f1d0aef57862dc1ba69b96f7770614..7f9d6dd959c8daaee6129bda31d36eac40449763 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -1692,6 +1692,17 @@ static int lib_pDoJump(lua_State *L)
 	return 0;
 }
 
+static int lib_pDoSpinDashDust(lua_State *L)
+{
+	player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
+	NOHUD
+	INLEVEL
+	if (!player)
+		return LUA_ErrInvalid(L, "player_t");
+	P_DoSpinDashDust(player);
+	return 0;
+}
+
 static int lib_pSpawnThokMobj(lua_State *L)
 {
 	player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
@@ -4249,6 +4260,7 @@ static luaL_Reg lib[] = {
 	{"P_HomingAttack",lib_pHomingAttack},
 	{"P_SuperReady",lib_pSuperReady},
 	{"P_DoJump",lib_pDoJump},
+	{"P_DoSpinDashDust",lib_pDoSpinDashDust},
 	{"P_SpawnThokMobj",lib_pSpawnThokMobj},
 	{"P_SpawnSpinMobj",lib_pSpawnSpinMobj},
 	{"P_Telekinesis",lib_pTelekinesis},
diff --git a/src/p_local.h b/src/p_local.h
index f0c01e71c15175ff43e16208f4f0b2f5b01436a8..a6df3b7f24958cfc1933b51ec026c29064b964a5 100644
--- a/src/p_local.h
+++ b/src/p_local.h
@@ -204,6 +204,7 @@ void P_Earthquake(mobj_t *inflictor, mobj_t *source, fixed_t radius);
 boolean P_HomingAttack(mobj_t *source, mobj_t *enemy); /// \todo doesn't belong in p_user
 boolean P_SuperReady(player_t *player);
 void P_DoJump(player_t *player, boolean soundandstate);
+void P_DoSpinDashDust(player_t *player);
 #define P_AnalogMove(player) (P_ControlStyle(player) == CS_LMAOGALOG)
 boolean P_TransferToNextMare(player_t *player);
 UINT8 P_FindLowestMare(void);
diff --git a/src/p_user.c b/src/p_user.c
index 5004203da3103675449fa69babbdb2e6b3c463ea..3da9461c3379800f0f868388793bad269ce972c1 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -4601,7 +4601,7 @@ void P_DoJump(player_t *player, boolean soundandstate)
 	}
 }
 
-static void P_DoSpinDashDust(player_t *player)
+void P_DoSpinDashDust(player_t *player)
 {
 	UINT32 i;
 	mobj_t *particle;