Page 1 of 1

[ACS] Making ACS movement code work smoothly online?

Posted: Tue Jun 02, 2020 3:05 am
by TDRR
Is it at all possible to override movement with ACS and have clientside prediction behave mostly correctly online? Right now, this makes prediction go nuts and more often than not the camera will skip forward a lot. When turning, there's also this strange jitter where the character will switch between two angles rapidly, and it can last for a while (moving in any direction will always cancel it, though).

Code: Select all

//note: requires ACSUtils 1.8.2 or newer
#library "PAY_MOVE"
#include "zcommon.acs"
#include "acsutils.acs"

bool Camera_Mode[MAX_PLAYERS];
int PlayerState[MAX_PLAYERS];

#define CAMERA_ACTOR "SecurityCamera" //any non solid actor should work, better if it's +CLIENTSIDEONLY

function bool Puffy_CanMove (void)
{
	int p_num = PlayerNumber();
	int ret1 = ((PlayerState[p_num] == STATE_ATTACK) && (CheckInventory("Puffy_IASA")));
	return ret1 || (PlayerState[p_num] == STATE_NORMAL);
}

int TDRR_Functions_WarpActor[3];
Script "TDRR_Functions_WarpActor" (int tid, int tid2, int angle, int flags)
{
	SetActivator(tid);
	SetResultValue( Warp(tid2, 
					TDRR_Functions_WarpActor[0], 
					TDRR_Functions_WarpActor[1], 
					TDRR_Functions_WarpActor[2], angle, flags) );
}

function int WarpActor (int tid, int tid2, int xoff, int yoff, int zoff, int angle, int flags)
{
	TDRR_Functions_WarpActor[0] = xoff;
	TDRR_Functions_WarpActor[1] = yoff;
	TDRR_Functions_WarpActor[2] = zoff;
	return ACS_NamedExecuteWithResult("TDRR_Functions_WarpActor", tid, tid2, angle, flags);
}

function void SetActorVelX (int tid, int velx, int add)
{
	int velz;
	int angle = GetActorAngle(0);
	
	if(!add) {velz = GetActorVelZ(0);}
	
	SetActorVelocity(tid, FixedMul(cos(angle),velx), FixedMul(sin(angle),velx), velz, add, FALSE);
}

Script "HHPAY_Camera_Enable" ENTER
{
	int pnum = PlayerNumber();
	Camera_Mode[pnum] = TRUE;
	ACS_NamedExecuteAlways("HHPAY_Camera_Loop", 0, pnum, FALSE);
}

Script "HHPAY_Camera_Loop" (int p_num)
{
	ConsoleCommand("cl_identifytarget 0");
		
	//Input variables.
	int yawinput, fwinput, sideinput;
	int moveangle;
	
	//Camera-related variables.
	int a,p,x,y,z,xyr;
	int r = MAX_R;
	int angle = GetActorAngle(0); //Camera angle, not player angle!
	
	//Other things.
	int speed = 8.0;
	int velx, vely, velz;
	bool OnGround;
		
	while (Camera_Mode[p_num] == TRUE)
	{	
		a = GetActorAngle (0);
		p = GetActorPitch (0);
		x = GetActorX (0);
		y = GetActorY (0);
		z = GetActorZ (0) + VIEW_HEIGHT;
		xyr = r * cos (p) >> 16;
		
		velx = GetActorVelX(0);
		vely = GetActorVelY(0);
		velz = GetActorVelZ(0);
		
		yawinput = GetPlayerInput(-1, INPUT_YAW);
		fwinput = GetPlayerInput(-1, INPUT_FORWARDMOVE);
		sideinput = GetPlayerInput(-1, INPUT_SIDEMOVE);
		
		angle += yawinput;
		SetActorAngle(0,a-yawinput);
		SetActorSpeed(0, 0);
		
		//If player is on ground, execute all grounded movement related stuff.
		if( (GetActorFloorZ(0) >= z) && (GetActorVelZ(0) == 0) )
		{
			if(Puffy_CanMove())
			{
				//Movement code. This thing doesn't work smoothly online, help me pls.
				if( (fwinput != 0) || (sideinput != 0) )
				{
					moveangle = VectorAngle(fwinput,-sideinput);
					
					SetActorAngle(0,angle+moveangle);
					SetActorVelX(0, speed, FALSE);
				}
				//Just here for increased friction, might make this less slippery later.
				else if(PlayerState[p_num] == STATE_NORMAL)
				{
					SetActorVelocity(0, FixedMul(velx,0.9), FixedMul(vely,0.9), 0, FALSE, TRUE);
				}
			}
		}
		
		//Camera doesn't exist? Something's probably wrong, try to fix it!
		if(!ThingCountName (CAMERA_ACTOR, C_TID+p_num))
		{
			SpawnForced(CAMERA_ACTOR, x-cos(angle)*xyr, y-sin(angle)*xyr, z+sin(p)*r, C_TID+p_num, a >> 8);
			SpawnForced(CAMERA_ACTOR, x-cos(angle)*xyr, y-sin(angle)*xyr, z+sin(p)*r, I_TID+p_num, a >> 8);
			
			if(ThingCountName(CAMERA_ACTOR, C_TID + p_num))
				{ChangeCamera (C_TID + p_num, 0, 0);}
			else
			{
				Camera_Mode[p_num] = FALSE;
				Log(s:CAMERA_FAIL_MSG);
			}
		}
		
		//Camera is alright, let's just update the position, pitch and angle.
		while(!SetActorPosition(I_TID+p_num, x-cos(angle)*xyr, y-sin(angle)*xyr, z+sin(p)*r, 0) && r > 0)
		{
			r -= ADJUST_R;
			xyr = cos (p) * r >> 16;
		}
			
		SetActorAngle (I_TID + p_num, angle);
		SetActorPitch (C_TID + p_num, p);
			
		if(WarpActor(C_TID+p_num, I_TID+p_num, 0.0, 0.0, 0.0, 0, WARPF_NOCHECKPOSITION) == FALSE)
		{Print(s:"ERROR");}
			
		if(r < MAX_R) 
			r += ADJUST_R;
		
		delay(1);
		if(Camera_Mode[p_num] == TRUE)
			ChangeCamera (C_TID + p_num, 0, 0);
	}
}

[ACS] Re: Making ACS movement code work smoothly online?

Posted: Thu Jul 02, 2020 11:23 am
by Ænima
It will probably never be possible to get it to look 100% smooth.


If TheMisterCat still lurked here, i’d refer you to him. He did a lot of work with WormsDoom to try to get the ACS-controlled player movement to look half-decent online. Even then, desync and input lag would still flare up every time pings rose.

[ACS] Re: Making ACS movement code work smoothly online?

Posted: Fri Jul 03, 2020 5:08 pm
by TDRR
Ænima wrote:
Thu Jul 02, 2020 11:23 am
It will probably never be possible to get it to look 100% smooth.


If TheMisterCat still lurked here, i’d refer you to him. He did a lot of work with WormsDoom to try to get the ACS-controlled player movement to look half-decent online. Even then, desync and input lag would still flare up every time pings rose.
I know it's not really possible to get it super smooth online, but it's REALLY annoying to press a direction, then your character moves and the camera is left behind, then snaps again to the character's position after a moment, then rinse and repeat for as long as the player moves. At least smoothing that a bit or eliminating it completely would be perfect, after all, it's pretty much the reason I'm going for Zandronum compatibility!

I already asked him if he could take a look, but he wasn't quite up to reading my frankly ugly code (or something like that, it's been a while), though he did give a couple tips so I could improve some things a bit (unrelated to online play though). Does anyone happen to know of a mod that overrides movement code in a similar way? I really want to see if this is fixable in any way.