Need help understanding networking code(Shooter Demo)

I came across a code pattern many times while going through the shooter project. But I am not sure yet what exactly does it do.

void AShooterWeapon::StartFire()
{
	if (Role < ROLE_Authority)
	{
		ServerStartFire();
	}

	if (!bWantsToFire)
	{
		bWantsToFire = true;
		DetermineWeaponState();
	}
}



bool AShooterWeapon::ServerStartFire_Validate()
{
	return true;
}

void AShooterWeapon::ServerStartFire_Implementation()
{
	StartFire();
}

Basically a as much as I could understand, this functions verifies from the server and calls a server version of that function.

But after a chain of functions, it calls this

void AShooterWeapon::HandleFiring()
{
	if ((CurrentAmmoInClip > 0 || HasInfiniteClip() || HasInfiniteAmmo()) && CanFire())
	{
		if (GetNetMode() != NM_DedicatedServer)
		{
			SimulateWeaponFire();
		}

		if (MyPawn && MyPawn->IsLocallyControlled())
		{
			FireWeapon();

			UseAmmo();
			
			// update firing FX on remote clients if function was called on server
			BurstCounter++;
		}
	}
	else if (CanReload())
	{
		StartReload();
	}
	else if (MyPawn && MyPawn->IsLocallyControlled())
	{
		if (GetCurrentAmmo() == 0 && !bRefiring)
		{
			PlayWeaponSound(OutOfAmmoSound);
			AShooterPlayerController* MyPC = Cast<AShooterPlayerController>(MyPawn->Controller);
			AShooterHUD* MyHUD = MyPC ? Cast<AShooterHUD>(MyPC->GetHUD()) : NULL;
			if (MyHUD)
			{
				MyHUD->NotifyOutOfAmmo();
			}
		}
		
		// stop weapon fire FX, but stay in Firing state
		if (BurstCounter > 0)
		{
			OnBurstFinished();
		}
	}

	if (MyPawn && MyPawn->IsLocallyControlled())
	{
		// local client will notify server
		if (Role < ROLE_Authority)
		{
			ServerHandleFiring();
		}

		// reload after firing last round
		if (CurrentAmmoInClip <= 0 && CanReload())
		{
			StartReload();
		}

		// setup refire timer
		bRefiring = (CurrentState == EWeaponState::Firing && WeaponConfig.TimeBetweenShots > 0.0f);
		if (bRefiring)
		{
			GetWorldTimerManager().SetTimer(this, &AShooterWeapon::HandleFiring, WeaponConfig.TimeBetweenShots, false);
		}
	}

	LastFireTime = GetWorld()->GetTimeSeconds();
}

bool AShooterWeapon::ServerHandleFiring_Validate()
{
	return true;
}

void AShooterWeapon::ServerHandleFiring_Implementation()
{
	const bool bShouldUpdateAmmo = (CurrentAmmoInClip > 0 && CanFire());

	HandleFiring();

	if (bShouldUpdateAmmo)
	{
		// update ammo
		UseAmmo();

		// update firing FX on remote clients
		BurstCounter++;
	}
}

I am really confused about what exactly does this do.

Whay does the ServerHandleFiring_Implementation() change the ammo and burst counter?

Hi Envenger,

1.	 if (Role < ROLE_Authority)
2.	{
3.	ServerStartFire();
4.	}

Role==ROLE_Autority means that this code executing on server, otherwise on client. Therefore, when you press fire (on client) you execute StartFire function on client that call ServerStartFire. ServerStartFire initiate remote procedure calling of ServerStartFire_Implementation on server part.
If you want to spawn actor on all clients you should spawn it on server. (If you spawn on client, you will have instance of this actor only on this client). That why all projectiles spawns on server.
What about HandleFiring it is function to start all firing effects (animation, muzzles, etc.)

Replication is a very large question and it cannot been covered in answer. If you would like to know a little more about replication, please take a look at the post below.

Hope it helps!

Thank you… After studying the shooter codes some more, I found out why it is used like that.

But I have a small question to ask.

If a normal function is called on the server(not multicast or anything) will that function be also called on the clients automatically?

No, it is not call.