Client getting kicked out after spawning

Whenever client car spawns the client is immediately kicked out to main menu. when checking logs I found out this error

LogNet: Warning: Closing connection. Can’t send function ‘ServerUpdateState’ on ‘ChaosWheeledVehicleMovementComponent /Game/Maps/1.1:PersistentLevel.BP_fast_C_2147482247.VehicleMovementComp’: Reliable buffer overflow.

Connection is closing because of buffer overflow . I don’t know anything about RPC.

According to:

This has been the case for a long time. The issue is that this Chaos component is sending a reliable RPC every tick, which is not desirable as it can very quickly overflow the limits, as you experienced.

At this point I think it’s worth reporting this as a bug. It’s unclear from the above link if this was ever logged: https://www.unrealengine.com/en-US/support/report-a-bug

I don’t think you will be able to fix it in Blueprint. I don’t know how comfortable you are with C++ but I think this is the only way to fix it yourself right now. Let us know if you want to do it, it should be fairly easy if we can guide you. You will need to download Visual Studio but otherwise your project won’t require any big change and you will still be able to use Blueprints and carry on as if nothing happened.

I’m going to assume you’re running on a listen server setup.
Lock the server to 30FPS tick and give it a go.

if there is no other way then I will try it. And my project is already set up with visual studio.

So this is not going to be a super elegant solution, but it should work.

Create a new C++ class for your project:

Base you class on the ChaosVehicleMovementComponent:

You can call it whatever. I called the one in the following code MyChaosVehicleMovementComponent. You end up with a MyChaosVehicleMovementComponent.h and a MyChaosVehicleMovementComponent.cpp files.

In the .h file, we override the UpdateState function (which is the one fired on Tick on the original component, which is then calling the ServerUpdateState RPC). We also declare a new RPC, which is basically a copy of the ServerUpdateState, but we mark it unreliable instead of reliable.

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

#pragma once

#include "CoreMinimal.h"
#include "ChaosVehicleMovementComponent.h"
#include "MyChaosVehicleMovementComponent.generated.h"

/**
 * 
 */
UCLASS()
class TESTPROJECT_API UMyChaosVehicleMovementComponent : public UChaosVehicleMovementComponent
{
	GENERATED_BODY()

protected:

	virtual void UpdateState(float DeltaTime) override;

	/** Unreliable version of the original RPC, to avoid reliable RPC overflow. */
	UFUNCTION(Unreliable, Server, WithValidation)
	void ServerUpdateStateUnreliable(float InSteeringInput, float InThrottleInput, float InBrakeInput
		, float InHandbrakeInput, int32 InCurrentGear, float InRollInput, float InPitchInput, float InYawInput);
	
};

Note: in the above, TESTPROJECT_API will be different for you, using the name of your project.

Then in the cpp file, we need to implement UpdateState. This is where this solution is a little bit dirty: we have to copy-paste the code from the original UpdateState function and just edit one line, to call our unreliable version of the RPC instead of the reliable one. If anyone has a better suggestion, please let us know, but here is the result:

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


#include "MyChaosVehicleMovementComponent.h"

void UMyChaosVehicleMovementComponent::UpdateState(float DeltaTime)
{
	// update input values
	AController* Controller = GetController();
	VehicleState.CaptureState(GetBodyInstance(), GetGravityZ(), DeltaTime);
	VehicleState.NumWheelsOnGround = 0;
	VehicleState.bVehicleInAir = false;
	int NumWheels = 0;
	if (PVehicleOutput)
	{
		for (int WheelIdx = 0; WheelIdx < PVehicleOutput->Wheels.Num(); WheelIdx++)
		{
			if (PVehicleOutput->Wheels[WheelIdx].InContact)
			{
				VehicleState.NumWheelsOnGround++;
			}
			else
			{
				VehicleState.bVehicleInAir = true;
			}
			NumWheels++;
		}
	}
	VehicleState.bAllWheelsOnGround = (VehicleState.NumWheelsOnGround == NumWheels);

	bool bProcessLocally = bRequiresControllerForInputs ? (Controller && Controller->IsLocalController()) : true;

	// IsLocallyControlled will fail if the owner is unpossessed (i.e. Controller == nullptr);
	// Should we remove input instead of relying on replicated state in that case?
	if (bProcessLocally && PVehicleOutput)
	{
		if (bReverseAsBrake)
		{
			//for reverse as state we want to automatically shift between reverse and first gear
			// Note: Removed this condition to support wheel spinning when rolling backwards with accelerator pressed, rather than braking
			//if (FMath::Abs(GetForwardSpeed()) < WrongDirectionThreshold)	//we only shift between reverse and first if the car is slow enough.
			{
				if (RawBrakeInput > KINDA_SMALL_NUMBER && GetCurrentGear() >= 0 && GetTargetGear() >= 0)
				{
					SetTargetGear(-1, true);
				}
				else if (RawThrottleInput > KINDA_SMALL_NUMBER && GetCurrentGear() <= 0 && GetTargetGear() <= 0)
				{
					SetTargetGear(1, true);
				}
			}
		}
		else
		{
			if (TransmissionType == Chaos::ETransmissionType::Automatic)
			{
				if (RawThrottleInput > KINDA_SMALL_NUMBER
					&& GetCurrentGear() == 0
					&& GetTargetGear() == 0)
				{
					SetTargetGear(1, true);
				}
			}

		}

		float ModifiedThrottle = 0.f;
		float ModifiedBrake = 0.f;
		CalcThrottleBrakeInput(ModifiedThrottle, ModifiedBrake);

		// Apply Inputs locally
		SteeringInput = SteeringInputRate.InterpInputValue(DeltaTime, SteeringInput, CalcSteeringInput());
		ThrottleInput = ThrottleInputRate.InterpInputValue(DeltaTime, ThrottleInput, ModifiedThrottle);
		BrakeInput = BrakeInputRate.InterpInputValue(DeltaTime, BrakeInput, ModifiedBrake);
		PitchInput = PitchInputRate.InterpInputValue(DeltaTime, PitchInput, CalcPitchInput());
		RollInput = RollInputRate.InterpInputValue(DeltaTime, RollInput, CalcRollInput());
		YawInput = YawInputRate.InterpInputValue(DeltaTime, YawInput, CalcYawInput());
		HandbrakeInput = HandbrakeInputRate.InterpInputValue(DeltaTime, HandbrakeInput, CalcHandbrakeInput());

		if (!bUsingNetworkPhysicsPrediction)
		{
			// and send to server - (ServerUpdateState_Implementation below)
			//ServerUpdateState(SteeringInput, ThrottleInput, BrakeInput, HandbrakeInput, GetCurrentGear(), RollInput, PitchInput, YawInput);
			ServerUpdateStateUnreliable(SteeringInput, ThrottleInput, BrakeInput, HandbrakeInput, GetCurrentGear(), RollInput, PitchInput, YawInput);
		}

		if (PawnOwner && PawnOwner->IsNetMode(NM_Client))
		{
			MarkForClientCameraUpdate();
		}
	}
	else if (!bUsingNetworkPhysicsPrediction)
	{
		// use replicated values for remote pawns
		SteeringInput = ReplicatedState.SteeringInput;
		ThrottleInput = ReplicatedState.ThrottleInput;
		BrakeInput = ReplicatedState.BrakeInput;
		PitchInput = ReplicatedState.PitchInput;
		RollInput = ReplicatedState.RollInput;
		YawInput = ReplicatedState.YawInput;
		HandbrakeInput = ReplicatedState.HandbrakeInput;
		SetTargetGear(ReplicatedState.TargetGear, true);
	}
}

bool UMyChaosVehicleMovementComponent::ServerUpdateStateUnreliable_Validate(float InSteeringInput, float InThrottleInput, float InBrakeInput, float InHandbrakeInput, int32 InCurrentGear, float InRollInput, float InPitchInput, float InYawInput)
{
	return ServerUpdateState_Validate(InSteeringInput, InThrottleInput, InBrakeInput, InHandbrakeInput, InCurrentGear, InRollInput, InPitchInput, InYawInput);
}

void UMyChaosVehicleMovementComponent::ServerUpdateStateUnreliable_Implementation(float InSteeringInput, float InThrottleInput, float InBrakeInput
	, float InHandbrakeInput, int32 InCurrentGear, float InRollInput, float InPitchInput, float InYawInput)
{
	ServerUpdateState_Implementation(InSteeringInput, InThrottleInput, InBrakeInput, InHandbrakeInput, InCurrentGear, InRollInput, InPitchInput, InYawInput);
}

The unreliable RPC is called on line 84.
We also implement our unreliable RPC, which is just calling the reliable RPC implementations under the hood. Compile and replace the vehicle component in Blueprints by your custom one.

This fix means that if the Chaos Vehicle plugin gets updated in the future (and you care about this update), the original UpdateState method code might change. So you may need to re-copy-paste the content in your override. You can find the source code here:

…\UE_5.4\Engine\Plugins\Experimental\ChaosVehiclesPlugin\Source\ChaosVehicles\Private\ChaosVehicleMovementComponent.cpp

In any case, whether you use this fix or not, as @Rev0verDrive mentioned, reducing the rate at which server updates occur is going to help.
I don’t have any experience with vehicle and physics replication, so I don’t know if the RPC being marked reliable is a requirement of this workflow. I guess you can just give the fix a go and see if things work as expected. In the code, the original reliable ServerUpdateState RPC is called only when you are not using the Network Physics Prediction plugin. My guess is that Epic assumes that for physics replication everyone is going to use this plugin, and the reliable RPC overflow isn’t really a concern, but I might be wrong.

Hay, i am confused. After compiling where should I replace vehicle component?

These steps will have created a new component (MyChaosVehicleMovementComponent in my case, but you might have picked a different name). Now, in Blueprints, instead of using the default ChaosVehicleMovementComponent on your actors, you should use the new custom one that you created.

Actually I forgot to do a couple of things in cp++, apologies:

  • you need to tag the UCLASS as available to Blueprints,
  • assuming you are using the ChaosWheeledVehicleMovementComponent (I just realised ChaosVehicleMovementComponent is abstract and so you are probably using the Wheeled movement component), you actually need to inherit from UChaosWheeledVehicleMovementComponent

Here is how the new .h file looks like:

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

#pragma once

#include "CoreMinimal.h"
#include "ChaosWheeledVehicleMovementComponent.h"
#include "MyChaosVehicleMovementComponent.generated.h"

/**
 * 
 */
UCLASS(meta = (BlueprintSpawnableComponent))
class TESTPROJECT_API UMyChaosVehicleMovementComponent : public UChaosWheeledVehicleMovementComponent
{
	GENERATED_BODY()

protected:

	virtual void UpdateState(float DeltaTime) override;

	/** Unreliable version of the original RPC, to avoid reliable RPC overflow. */
	UFUNCTION(Unreliable, Server, WithValidation)
	void ServerUpdateStateUnreliable(float InSteeringInput, float InThrottleInput, float InBrakeInput
		, float InHandbrakeInput, int32 InCurrentGear, float InRollInput, float InPitchInput, float InYawInput);
	
};

Lines 6, 12 and 13 have changed.

Recompile and try again.
I assume you have a vehicle pawn actor in BP, this is where you should swap the default component for the new one.

That did it, Thanks