Queue Constantly Increasing

My queue keeps on increasing even after adding the ClearAcknowledgedMoves (FGoKartMove LastMove) method.

For some reason LastMove.Time is always returning a value of 0 in the log.

Here is an excerpt from the log (not in the code shown):

Here are the changed methods in the cpp I made for this lecture:

void AGoKart::ClearAcknowledgedMoves(FGoKartMove LastMove)
{
	TArray<FGoKartMove> NewMoves;

	for (const FGoKartMove& Move : UnacknowledgedMoves)
	{
		if (Move.Time > LastMove.Time)
		{
			NewMoves.Add(Move);
		}
	}

	UnacknowledgedMoves = NewMoves;
} 
FGoKartMove AGoKart::CreateMove(float DeltaTime)
{
	FGoKartMove Move;
	Move.DeltaTime = DeltaTime;
	Move.SteeringThrow = SteeringThrow;
	Move.Throttle = Throttle;
	Move.Time = GetWorld()->TimeSeconds;

	return Move;
}
void AGoKart::OnRep_ServerState()
{
	SetActorTransform(ServerState.Transform);
	Velocity = ServerState.Velocity;

	ClearAcknowledgedMoves(ServerState.LastMove);
}
void AGoKart::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	if (IsLocallyControlled())
	{
		FGoKartMove Move = CreateMove(DeltaTime);

		if (!HasAuthority())
		{
			UnacknowledgedMoves.Add(Move);
			UE_LOG(LogTemp, Warning, TEXT("Queue length: %d"), UnacknowledgedMoves.Num());
		}

		Server_SendMove(Move);

		SimulateMove(Move); // introduces a bug but fixed in lecture 100. Fixing SimulatedProxy Prediction
	}

	DrawDebugString(GetWorld(), FVector(0, 0, 100), GetEnumText(GetLocalRole()), this, FColor::White, DeltaTime);
}

I checked against the provided repository for the lecture, and everything looks fine to me. Not sure if I’m missing something?

It appears as if the last move time is not being updated correctly. Where do you replace the last move?

Thanks for the quick reply. It gets initially set in the Server_SendMove_Implementation method, which is the only other place it is present, that I haven’t shown above. This sends a FGoKartMove Move to the server reliably and with validation. The Server_SendMove_Validate method simply returns true at this point.

Server_SendMove_Implementation method:

void AGoKart::Server_SendMove_Implementation(FGoKartMove Move)
{
	SimulateMove(Move);

	ServerState.LastMove = Move;
	ServerState.Transform = GetActorTransform();
	ServerState.Velocity = Velocity;
}

Here is the whole header file too. The main declarations of interest are the two structs FGoKartMove and FGoKartState (which holds the state of the struct FGoKartMove in LastMove), as well as the array of FGoKartMoves UnacknowledgedMoves. Also the FGoKartState ServerState, which is replicated using the OnRep_ServerState method which is shown in the first post.

GoKart.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "GoKart.generated.h"

USTRUCT()
struct FGoKartMove
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY()
	float Throttle;

	UPROPERTY()
	float SteeringThrow;

	UPROPERTY()
	float DeltaTime;

	UPROPERTY()
	float Time;
};

USTRUCT()
struct FGoKartState
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY()
	FTransform Transform;
	
	UPROPERTY()
	FVector Velocity;

	FGoKartMove LastMove;
};

UCLASS()
class KRAZYKARTS_API AGoKart : public APawn
{
	GENERATED_BODY()

public:
	// Sets default values for this pawn's properties
	AGoKart();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

	// Called to bind functionality to input
	virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

private:

	// The mass of the car (kg)
	UPROPERTY(EditAnywhere)
	float Mass = 1000;

	// The force applied to the car when the throttle is fully down (Newton (N))
	UPROPERTY(EditAnywhere)
	float MaxDrivingForce = 10000;

	// Higher means more drag (kg/m)
	UPROPERTY(EditAnywhere)
	float DragCoefficient = 16;

	// Higher means more rolling resistance
	UPROPERTY(EditAnywhere)
	float RollingResistanceCoefficient = 0.015;

	// Minimum radius of the car turning circle at full lock (m)
	UPROPERTY(EditAnywhere)
	float MinTurningRadius = 10;

	float Throttle;
	float SteeringThrow;

	FVector Velocity;

	TArray<FGoKartMove> UnacknowledgedMoves;

	UPROPERTY(ReplicatedUsing=OnRep_ServerState)
	FGoKartState ServerState;

	UFUNCTION()
	void OnRep_ServerState();

	void MoveForward(float Value);
	void MoveRight(float Value);

	UFUNCTION(Server, Reliable, WithValidation) // Server RPC function which is Reliable (always execute)
	void Server_SendMove(FGoKartMove Move);

	FGoKartMove CreateMove(float DeltaTime);

	void SimulateMove(const FGoKartMove Move);

	void ClearAcknowledgedMoves(FGoKartMove LastMove);

	void UpdateLocationFromVelocity(float DeltaTime);

	void ApplyRotation(float DeltaTime, float SteeringThrowInput);

	FVector GetAirResistance();

	FVector GetRollingResistance();
};

The other method of interest is ClearAcknowledgedMoves which takes a FGoKartState LastMove and then checks all the unacknowledged moves. If the unacknowledged Move’s Time field has a higher time than the LastMove’s Time field, this means it hasn’t been processed by the server yet. Therefore adding the Move to the NewMoves array of FGoKartMoves. After all the Moves have been processed in the UnacknowledgedMoves array, this array is set to the contents of the NewMoves array.

P.S. I’ve done a check of the ServerState LastMove’s Time field before it gets passed to the ClearAcknowledgedMoves method, and it’s 0 as well. So not to do with any incorrect passing to the method in OnRep_ServerState.

P.P.S. Checked the ServerState LastMove’s Time field in Server_SendMove_Implementation and its giving actual values. So must be somewhere after this it is getting not passed correctly.

TLDR: The ServerState is getting sent to the server correctly, but isn’t correct (Time field missing) when replicated.

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.