(TIL) 2024-12-31
(TIL) 2024-12-31
트러블 슈팅
배경
타워가 몬스터를 공격 했을 때의 핸들러 기능을 테스트 하던 중 타워의 공격 사거리가 유효한지 검증 하기 위해 몬스터의 위치 값을 확인하는 부분에서 클라이언트의 몬스터 x 값과 서버의 몬스터 x 값의 차이가 많이 나는 문제가 확인되었다.
원인 / 분석
- 서버 코드
1
2
3
4
5
6
7
xport const calculateMonsterMove = (monsterId, monsterIndex, timestamp) => {
//몬스터의 Asset 조회
const { monsters } = getGameAssets();
let x = 0; // 초기 x 값 설정
const speed = monsters.data.find((monster) => monster.id === monsterId).speed; // assets파일에서 speed 가져오기
x = speed * (Date.now() - timestamp) * 0.29
};
timestamp 는 해당 몬스터가 생성된 시간의 값을 받고 있으며 x의 값은 속도 * (현재시간 - 소환시간(ms)) * 0.29 로 계산된다.
- 클라이언트 코드
1
2
3
move(deltaTime) {
this.x += this.speed;
}
클라이언트는 프레임 단위로 몬스터의 이동속도 만큼 증가되고 있다. 클라이언트와 서버의 계산 공식이 동일하지 않은 것이 확인 할 수 있었다.
결과
- 서버 코드
1
2
3
4
5
6
7
8
export const calculateMonsterMove = (monsterId, monsterIndex, timestamp) => {
//몬스터의 Asset 조회
const { monsters } = getGameAssets();
let x = 0; // 초기 x 값 설정
const speed = monsters.data.find((monster) => monster.id === monsterId).speed; // assets파일에서 speed 가져오기
x = speed * (Date.now() - timestamp); //속도 * (현재시간 - 소환시간(ms))
return x;
};
- 클라이언트 코드
1
2
3
move(deltaTime) {
this.x += this.speed * deltaTime;
}
문제의 원인은 서버와 클라이언트에서 프레임 시간 기준으로 계산처리를 안해서 해당 문제가 발생했던 것. 웹소켓 통신으로 주고 받기에 약간의 오차 범위가 있긴하지만 오차 범위가 2~3배 나던 것이 1~5 로 줄어들었다.
추가로 알게 된 사실은 이렇게 서버와 클라에서 각각 같은 기준으로 처리를 하게되면 별도로 클라이언트의 값과 서버의 값에 대한 검증을 굳이 안해도 된다고 한다.
그 이유는 시간이라는 것은 동일 하게 흘러가기에 그 기준만 동일하다면 오차 허용 범위 내의 값이면 문제가 없다는 것이다.
This post is licensed under CC BY 4.0 by the author.
