diff -r f46ab13b972a docs/zandronum-history.txt
--- a/docs/zandronum-history.txt	Fri Sep 29 08:23:34 2023 -0400
+++ b/docs/zandronum-history.txt	Sat Jan 27 20:03:28 2024 -0600
@@ -114,6 +114,7 @@
 -	- Fixed: the coop info wasn't getting drawn in clientside demos. [Kaminsky]
 -	- Fixed: Floatbob items having incorrect z-height after a map reset and glitchy GL floor clipping (addresses 2361). [Ru5tK1ng]
 -	- Fixed: Monsters spawned by BossBrain cubes would move before being spawned on the clients therefore triggering warning messages (addresses 2655). [Ru5tK1ng]
+-   - Fixed: ArcOfDeath did not lock onto targets on the clients end (addresses 723). [Ru5tK1ng].
 !	- The result value of GAMEEVENT_MEDALS event scripts can now be used to determine whether or not the player receives the medal. [Kaminsky]
 !	- GAMEMODE flags are now validated after all GAMEMODE lumps have been parsed instead of after each one. The internal game mode name (e.g. "TeamLMS") is now printed with the error message instead of the actual name. [Kaminsky]
 !	- Added an extra check to ensure that game modes have a (short) name. [Kaminsky]
diff -r f46ab13b972a src/g_hexen/a_magelightning.cpp
--- a/src/g_hexen/a_magelightning.cpp	Fri Sep 29 08:23:34 2023 -0400
+++ b/src/g_hexen/a_magelightning.cpp	Sat Jan 27 20:03:28 2024 -0600
@@ -149,6 +149,10 @@
 	AActor *target = NULL;
 	int zigZag;
 
+	// [RK] The server will handle the target lock on.
+	if (NETWORK_InClientMode())
+		return;
+
 	if (self->flags3 & MF3_FLOORHUGGER)
 	{
 		if (self->lastenemy == NULL)
@@ -185,6 +189,9 @@
 			}
 			self->special1--;
 		}
+		// [RK] Update the thrusts to the clients.
+		if( NETWORK_GetState() == NETSTATE_SERVER )
+			SERVERCOMMANDS_MoveThingExact( cMo, CM_ANGLE|CM_VELX|CM_VELY );
 	}
 	if(target)
 	{
@@ -199,6 +206,11 @@
 			self->vely = 0;
 			P_ThrustMobj (self, self->angle, self->Speed>>1);
 		}
+		if (NETWORK_GetState() == NETSTATE_SERVER)
+		{
+			SERVERCOMMANDS_MoveThing( self, CM_X|CM_Y );
+			SERVERCOMMANDS_MoveThingExact( self, CM_ANGLE|CM_VELX|CM_VELY );
+		}
 	}
 }
 
@@ -216,6 +228,10 @@
 	AActor *mo;
 	fixed_t deltaZ;
 
+	// [RK] The server will handle the spawning of lightning projectiles.
+	if( NETWORK_InClientMode() )
+		return;
+
 	CALL_ACTION(A_LightningClip, self);
 
 	self->health -= 8;
@@ -249,10 +265,14 @@
 		{
 			mo->velz = -20*FRACUNIT;
 		}
+
+		// [RK] Spwn the projectile on the clients.
+		if( NETWORK_GetState() == NETSTATE_SERVER )
+			SERVERCOMMANDS_SpawnMissile(mo);
 	}
 	if ((self->flags3 & MF3_FLOORHUGGER) && pr_zapf() < 160)
 	{
-		S_Sound (self, CHAN_BODY, self->ActiveSound, 1, ATTN_NORM);
+		S_Sound (self, CHAN_BODY, self->ActiveSound, 1, ATTN_NORM, true); // [RK] Inform clients.
 	}
 }
 
@@ -354,6 +374,10 @@
 {
 	AActor *mo;
 
+	// [RK] The server will move the lightning projectile.
+	if (NETWORK_InClientMode())
+		return;
+
 	mo = self->lastenemy;
 	if (mo)
 	{
@@ -365,6 +389,10 @@
 		{
 			self->velx = mo->velx;
 			self->vely = mo->vely;
+
+			// [RK] Update the lightning position.
+			if ( NETWORK_GetState() == NETSTATE_SERVER )
+				SERVERCOMMANDS_MoveThingExact( self, CM_VELX | CM_VELY );
 		}
 	}
 }
@@ -377,6 +405,10 @@
 
 DEFINE_ACTION_FUNCTION(AActor, A_LastZap)
 {
+	// [RK] The server will handle projectile spawning.
+	if( NETWORK_InClientMode() )
+		return;
+	
 	const PClass *lightning=PClass::FindClass((ENamedName) self->GetClass()->Meta.GetMetaInt (ACMETA_MissileName, NAME_LightningZap));
 
 	AActor *mo;
@@ -387,6 +419,10 @@
 		mo->SetState (mo->FindState (NAME_Death));
 		mo->velz = 40*FRACUNIT;
 		mo->Damage = 0;
+
+		// [RK] Spawn the lightning projectile on the clients.
+		if( NETWORK_GetState() == NETSTATE_SERVER )
+			SERVERCOMMANDS_SpawnMissile(mo);
 	}
 }
 
