diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 2cfc251ff42467511e479423c746a7329c51d56c..58c7c80a3c1e50cd62b0c82bde80a6363d635e08 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -924,6 +924,17 @@ static int lib_pXYMovement(lua_State *L)
 	return 0;
 }
 
+static int lib_pRingXYMovement(lua_State *L)
+{
+	mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
+	NOHUD
+	INLEVEL
+	if (!actor)
+		return LUA_ErrInvalid(L, "mobj_t");
+	P_RingXYMovement(actor);
+	return 0;
+}
+
 // P_USER
 ////////////
 
@@ -3283,6 +3294,7 @@ static luaL_Reg lib[] = {
 	{"P_MaceRotate",lib_pMaceRotate},
 	{"P_RailThinker",lib_pRailThinker},
 	{"P_XYMovement",lib_pXYMovement},
+	{"P_RingXYMovement",lib_pRingXYMovement},
 
 	// p_user
 	{"P_GetPlayerHeight",lib_pGetPlayerHeight},
diff --git a/src/p_mobj.c b/src/p_mobj.c
index c26308a59d653353ecb324e24c2a0f26070815de..9d6efd950ad7a49c27633a62c49268790390d2ad 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -2102,7 +2102,7 @@ void P_XYMovement(mobj_t *mo)
 	P_XYFriction(mo, oldx, oldy);
 }
 
-static void P_RingXYMovement(mobj_t *mo)
+void P_RingXYMovement(mobj_t *mo)
 {
 	I_Assert(mo != NULL);
 	I_Assert(!P_MobjWasRemoved(mo));
diff --git a/src/p_mobj.h b/src/p_mobj.h
index c94dbd650310a2393ae3129bf028f8e5757c48c3..d874ffe09c5f1011b5efc97a3744df17a541a8d2 100644
--- a/src/p_mobj.h
+++ b/src/p_mobj.h
@@ -471,6 +471,7 @@ void P_NullPrecipThinker(precipmobj_t *mobj);
 void P_RemovePrecipMobj(precipmobj_t *mobj);
 void P_SetScale(mobj_t *mobj, fixed_t newscale);
 void P_XYMovement(mobj_t *mo);
+void P_RingXYMovement(mobj_t *mo);
 void P_EmeraldManager(void);
 
 extern INT32 modulothing;