Unable to debug some RPC calls

Today I spent several hours with a RPC that I thought didn’t work. As it turns out only the break point wasn’t triggered.

Here is some code


	UFUNCTION(Server, WithValidation, Unreliable)
	void ServerMoveTo(const FVector Dest);
	void ServerMoveTo_Implementation(const FVector Dest);
	bool ServerMoveTo_Validate(const FVector Dest);

	UFUNCTION(Server, WithValidation, Unreliable)
	void ServerSetTarget1();
	void ServerSetTarget1_Implementation();
	bool ServerSetTarget1_Validate();


void AArenaCharacterProxy::ServerMoveTo_Implementation(const FVector Dest)
{

	APawn* const Pawn = Cast<APawn>(ServerCharacter);
	if (Pawn)
	{
		UNavigationSystem* const NavSys = UNavigationSystem::GetCurrent(this);
		float const Distance = FVector::Dist(Dest, Pawn->GetActorLocation());

		// We need to issue move command only if far enough in order for walk animation to play correctly
		if (NavSys && (Distance > 120.0f))
		{
			if (PlayerAI){
				PlayerAI->MoveToLocation(Dest);
			}
		}
	}
}

bool AArenaCharacterProxy::ServerMoveTo_Validate(const FVector Dest)
{
	return true;
}

bool AArenaCharacterProxy::ServerSetTarget1_Validate()
{
	return true;
}

void AArenaCharacterProxy::ServerSetTarget1_Implementation()
{
	Test();
}
void AArenaCharacterProxy::Test()
{
	GEngine->AddOnScreenDebugMessage(-1, 5, FColor::Blue, *GetName());
}


And is called like this


void AArenaCharacterProxy::PrimaryAction()
{
	FHitResult Hit;
	GetArenaPlayerController()->GetHitResultUnderCursor(ECC_WorldDynamic, false, Hit);
	if (Hit.bBlockingHit)
	{
		ServerSetTarget1();
		ServerMoveTo(Hit.ImpactPoint);
	}
}

Now the strange part, if I set a break point at


ServerMoveTo_Implementation

it will stop at the break point as expected. But if I set breakpoint at


ServerSetTarget1_Implementation

VS didn’t stop at the break point.

I was very close to insanity and I usually never use print functions but in this case I just created a simple on screen message


void AArenaCharacterProxy::Test()
{
	GEngine->AddOnScreenDebugMessage(-1, 5, FColor::Blue, *GetName());
}

which is triggered as expected. Any idea why this is happening?

Here are my break points

Okay I made a mistake. I always developed with ‘Development Editor’ but I now switched to ‘DebugGame Editor’. It seems the Dev Editor doesn’t include all the debug symbols.

Yeah, I’ve made that mistake several times. The key is to look at the order of execution for your program counter (PC). If you’re running through an optimized binary in the debugger, you’ll see the PC jump around a code block in what looks like a “JIT” access mode. Example:

Line 1: int32 MyVar1 = 5;
Line 2: int32 MyVar2 = 2;
Line 3: int32 MyResult = MyVar1 + MyVar2;

Lines 1 and 2 will not be processed until line 3 gets executed. When the PC gets to line 3, it realizes it needs lines 1 and 2, so then it goes back and evaluates them. If you see your codes program counter jumping backwards in the flow of execution like this, check your build configuration!