diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt
index 8395d9945..a7d3bf73b 100644
--- a/source/CMakeLists.txt
+++ b/source/CMakeLists.txt
@@ -702,6 +702,7 @@ set( NOT_COMPILED_SOURCE_FILES
 	games/duke/src/actors_d.cpp
 	games/duke/src/actors_lava.cpp
 	games/duke/src/actors_r.cpp
+	games/duke/src/animatesprites.cpp
 	games/duke/src/animatesprites_d.cpp
 	games/duke/src/animatesprites_r.cpp
 	games/duke/src/bowling.cpp
diff --git a/source/games/duke/src/actors.cpp b/source/games/duke/src/actors.cpp
index 98202f7d6..586c2116e 100644
--- a/source/games/duke/src/actors.cpp
+++ b/source/games/duke/src/actors.cpp
@@ -92,12 +92,12 @@ void TickActor(DDukeActor* self)
 			self->spr.lotag += TICSPERFRAME;
 			if (self->spr.lotag > delay)
 			{
-				self->temp_data[2]++;
+				self->actioncounter++;
 				self->spr.lotag = 0;
-				self->temp_data[3] += increment;
+				self->curframe += increment;
 			}
-			if (abs(self->temp_data[3]) >= abs(numframes * increment))
-				self->temp_data[3] = 0;
+			if (abs(self->curframe) >= abs(numframes * increment))
+				self->curframe = 0;
 		}
 
 		if (!execute(self, p, pdist))
diff --git a/source/games/duke/src/animatesprites.cpp b/source/games/duke/src/animatesprites.cpp
index cbb7b598a..896b1f569 100644
--- a/source/games/duke/src/animatesprites.cpp
+++ b/source/games/duke/src/animatesprites.cpp
@@ -186,7 +186,7 @@ void applyanimations(tspritetype* t, DDukeActor* h, const DVector2& viewVec, DAn
 				}
 			}
 
-			k += action->offset + l * h->temp_data[3];
+			k += action->offset + l * h->curframe;
 			t->picnum += k;
 
 			if (isRRRA() && RRRAFullbrightHack(t, k)) t->shade = -127;
diff --git a/source/games/duke/src/cheats.cpp b/source/games/duke/src/cheats.cpp
index 0ceb2ee4e..21f23d95c 100644
--- a/source/games/duke/src/cheats.cpp
+++ b/source/games/duke/src/cheats.cpp
@@ -74,11 +74,11 @@ static const char *cheatGod(int myconnectindex, int state)
 		act->spr.cstat = CSTAT_SPRITE_BLOCK_ALL;
 
 		act->temp_data[0] = 0;
-		act->temp_data[1] = 0;
-		act->temp_data[2] = 0;
 		act->temp_data[3] = 0;
-		act->temp_data[4] = 0;
-		act->temp_data[5] = 0;
+		act->curAction = &actions[0];
+		act->curMove = &moves[0];
+		act->curAI = NAME_None;
+		act->actioncounter = 0;
 
 		act->spr.hitag = 0;
 		act->spr.lotag = 0;
diff --git a/source/games/duke/src/gameexec.cpp b/source/games/duke/src/gameexec.cpp
index 072890e31..2089bc760 100644
--- a/source/games/duke/src/gameexec.cpp
+++ b/source/games/duke/src/gameexec.cpp
@@ -1559,7 +1559,8 @@ int ParseState::parse(void)
 		g_ac->curAction = &actions[ai->action];
 		g_ac->curMove = &moves[ai->move];
 		g_ac->spr.hitag = ai->moveflags;
-		g_t[0] = g_t[2] = g_t[3] = 0;
+		g_ac->actioncounter = g_ac->curframe = 0;
+		g_t[0] = 0;
 		if (g_ac->spr.hitag & random_angle)
 			g_ac->spr.Angles.Yaw = randomAngle();
 		insptr++;
@@ -1567,8 +1568,7 @@ int ParseState::parse(void)
 	}
 	case concmd_action:
 		insptr++;
-		g_t[2] = 0;
-		g_t[3] = 0;
+		g_ac->actioncounter = g_ac->curframe = 0;
 		g_ac->curAction = &actions[*insptr];
 		insptr++;
 		break;
@@ -1919,11 +1919,11 @@ int ParseState::parse(void)
 		break;
 	case concmd_ifactioncount:
 		insptr++;
-		parseifelse(g_t[2] >= *insptr);
+		parseifelse(g_ac->actioncounter >= *insptr);
 		break;
 	case concmd_resetactioncount:
 		insptr++;
-		g_t[2] = 0;
+		g_ac->actioncounter = 0;
 		break;
 	case concmd_debris:
 		insptr++;
diff --git a/source/games/duke/src/savegame.cpp b/source/games/duke/src/savegame.cpp
index a63bf525e..22e380b30 100644
--- a/source/games/duke/src/savegame.cpp
+++ b/source/games/duke/src/savegame.cpp
@@ -320,7 +320,10 @@ void DDukeActor::Serialize(FSerializer& arc)
 		("flags3", flags3)
 		("curmove", curMove)
 		("curaction", curAction)
-		("curai", curAI);
+		("curai", curAI)
+		("curframe", curframe)
+		("counter", counter)
+		("actioncounter", actioncounter);
 }
 
 
diff --git a/source/games/duke/src/spawn.cpp b/source/games/duke/src/spawn.cpp
index 7923bde1b..f762829db 100644
--- a/source/games/duke/src/spawn.cpp
+++ b/source/games/duke/src/spawn.cpp
@@ -39,6 +39,7 @@ source as it is released.
 #include "automap.h"
 #include "dukeactor.h"
 #include "interpolate.h"
+#include "vm.h"
 
 BEGIN_DUKE_NS
 
diff --git a/source/games/duke/src/types.h b/source/games/duke/src/types.h
index 0c6890b5c..bfb81fde6 100644
--- a/source/games/duke/src/types.h
+++ b/source/games/duke/src/types.h
@@ -101,15 +101,15 @@ public:
 	ActorMove* curMove;
 	ActorAction* curAction;
 	FName curAI;	// no need to store the pointer here.
-
-	TObjPtr<DDukeActor*> temp_actor, seek_actor;
-
-	TArray<GameVarValue> uservars;
+	int16_t counter, actioncounter, curframe;	// sprite animation counters - were previously stored in temp_data.
 
 	EDukeFlags1 flags1;
 	EDukeFlags2 flags2;
 	EDukeFlags3 flags3;
 
+	TObjPtr<DDukeActor*> temp_actor, seek_actor;
+	TArray<GameVarValue> uservars;
+
 	// these two variables are only valid while RunState is executed. They are explicitly nulled right afterward and only accessible throgh the CON emulation interface.
 	struct player_struct* state_player;
 	double state_dist;