목표: 서버에서의 셔틀콕의 위치 정보를 Client로 replication 해주자!

60 frames이면 대략 16ms이다. 어릴때 스타를 보면 김택용 apm이 400이 나와요~ 같은 말을 자주 들었는데, **APM(Actions Per Minute)**이다. 투신의 경우 910 APM이 나온 적 있지만 이는 신이기에 가능한 일. 사람이라면~ 400 미만으로 잡고, 초로 나눠보면 1초에 6~7번의 명령을 하고 있는 것. 60 FPS 기준 대략 10번의 frame update 동안 1번 명령이 발생한다. 30 FPS로 낮춰도 5번에 1번 발생하는 것. 정상적인 플레이라면? 하나의 명령이 발생할 때마다 패킷에 write 하도록 만들어도 낡은 데이터가 들어가지 않을 것 같다.

게임에서 주기와 관련된 용어 정리

서버에서 Update를 한다고 해서 지금 패킷에 담는 건 아니다. 패킷으로 보내는 상황은?

  1. RPC를 통해 클라이언트에서 요청이 왔을 때

  2. 패킷에 업데이트할 주기가 되어 클라이언트에게 주기적으로 replication 해줄 때

    PP를 설정해야 한다.

FixedUpdate 주기와 패킷에 데이터를 담는 주기는 서로 다르기 때문에, 이 과정을 구현해야 했다.

// Constant.h

	const float FIXED_UPDATE_TIMESTEP = 1.0f;	// 1Hz
	const float PACKET_PERIOD = 0.4f;	// 2.5Hz
system_clock::time_point currentTime = system_clock::now();
const local_time<system_clock::duration> now = zoned_time{ current_zone(), currentTime }.get_local_time();
std::chrono::duration<double> elapsedTime;

// 물리 Update
elapsedTime = currentTime - _lastFixedUpdateTime;
if (elapsedTime.count() >= Constant::FIXED_UPDATE_TIMESTEP)
{
	// ...
}

// Packet Add
elapsedTime = currentTime - _lastPacketUpdateTime;
if (elapsedTime.count() >= Constant::PACKET_PERIOD)
{
	// ...
}

지정된 주기보다 30~50ms 더 늦게 출력 로그가 찍힌다? 시간에 맞춰 Update를 수행하는 로직을 따로 스레드로 동작시켜야 할 조짐을 느낀다.

image.png

Update 이후, Packet에 Write 하기 전에 기록하는 queue를 만들자.

  1. 패킷에 동일한 객체는 1번만 담기 위해
  2. Update가 발생하는 것과 Packet에 담는 동작을 분리하기 위해