레이턴시 구하기
// 레이턴시
ping() {
const now = Date.now();
this.socket.write(makePingPacket(now));
}
handlePong(milliseconds) {
const now = Date.now();
this.lastPong = now;
this.latency = (now - milliseconds) / 2; // 왕복이니까
}
핑퐁함수(setInterval)을 구현해서 레이턴시를 주기적으로 저장한다.
추측항법
function predictPosition(socket, player, transform, latency) {
// 직전 좌표와 transform의 좌표를 빼서 방향벡터를 구하고 노말라이즈
const prevPosition = player.getPosition();
const velocity = {
posX: transform.posX - prevPosition.x,
posY: transform.posY - prevPosition.y,
posZ: transform.posZ - prevPosition.z,
};
// 속도 벡터 크기(속력) 계산 및 검증
let magnitude = Math.sqrt(
velocity.posX ** 2 + velocity.posY ** 2 + velocity.posZ ** 2,
);
if (magnitude > 7) {
magnitude = 10;
return socket.emit(
'error',
new CustomError(
ErrorCodes.INVALID_SPEED,
'플레이어의 이동 속도가 올바르지 않습니다.',
),
);
}
// 초당 속도 벡터 구하기(노말라이즈)
const normalizedVelocity =
magnitude > 0
? {
posX: velocity.posX / magnitude,
posY: velocity.posY / magnitude,
posZ: velocity.posZ / magnitude,
}
: { posX: 0, posY: 0, posZ: 0 };
// 예측한 위치 = 현재 transform 위치 + (속도 벡터 * 레이턴시)
const predictedPosition = {
posX: transform.posX + normalizedVelocity.posX * latency,
posY: transform.posY + normalizedVelocity.posY * latency,
posZ: transform.posZ + normalizedVelocity.posZ * latency,
rot: transform.rot,
};
return predictedPosition;
}
버그리포트
int 64 프로토버프에 Date.now()를 저장했더니 이렇게 나왔다.
이유를 gpt에 물어봤더니, 아래와 같이 답을 줬다.
JavaScript는 number
타입이 53비트 정밀도를 가지므로, 64비트 정수를 다룰 때 보통 low
(하위 32비트)와 high
(상위 32비트)로 분리해 저장하는 방식을 사용한다. Date.now()
처럼 밀리초 단위의 타임스탬프로 변환하려면, 다음과 같이 low
와 high
값을 조합하면 된다:
function timestampToMillis(timestamp) {
return (timestamp.high * 2 ** 32) + timestamp.low;
}
'개발일지 > TIL(Today I Learned)' 카테고리의 다른 글
2025-03-05 <최종 프로젝트 D-9> (2) | 2025.03.05 |
---|---|
2025-03-04 <최종프로젝트 D-10> (0) | 2025.03.04 |
2025-02-25 <최종 프로젝트 D-14> MVP(Minimum Viable Product) 발표회 (0) | 2025.02.28 |
2025-02-27 <최종 프로젝트 D-15> EC2에서 도커 컨테이너 여러 개 생성하기 (0) | 2025.02.27 |
2025-02-26 (0) | 2025.02.26 |
댓글