PallMark 타격감 조정기, 히트스톱은 넣는 것보다 줄이는 게 어려웠다
PallMark에서 타격감을 만드는 다섯 축(히트스톱·피격 플래시·피해 숫자·넉백·원소색)의 실제 수치와, 히트스톱이 오히려 화면 떨림으로 보였던 문제를 고친 과정을 적었다.

PallMark의 목표는 “멋진 스킬과 콤보로 몰려드는 적을 시원하게 쓸어버리는 사냥”이다. 시원하다는 느낌은 대부분 맞는 순간의 0.1초 안에서 결정된다. Unity로 옮기면서 원본 Godot판이 쓰던 타격감 수치를 하나씩 다시 확인했다. 그리고 가장 효과가 큰 장치인 히트스톱이 가장 큰 말썽을 일으켰다.
타격감의 다섯 축
기획서의 연출 장(C)은 타격감을 다섯 가지로 나눈다. 지금 클라이언트 코드에 들어 있는 값은 다음과 같다.
| 축 | 일반 | 치명타 | 메모 |
|---|---|---|---|
| 히트스톱 | 3/60초(50ms) | 6/60초(100ms) | 화면 표현만 0.04배속으로 늦춘다 |
| 피격 플래시 | 1.5프레임 | 3프레임 | 60fps에서도 확실히 한 프레임은 보이게 |
| 피해 숫자 크기 | 20px | 34px | 내가 맞은 숫자는 30px, 붉은색 |
| 피해 숫자 지속 | 1.35초 | 1.65초 | 마지막 0.35초 동안 사라진다 |
| 클라이언트 반동 | 6px | 보스는 0 |
화면 흔들림은 없다. 원본에서 8월 23일에 흔들림 기능을 코드째 지웠고, 흔들림 코드가 다시 들어오면 실패하는 검사까지 세워 두었다. 몰려드는 적을 수십 번 베는 게임이라 흔들림이 쌓이면 화면을 읽을 수 없었기 때문이다. Unity판에도 넣지 않았다.
피해 숫자의 지속 시간은 원본(0.85초/1.15초)과 다르다. 9월 2일에 “1초 정도 떠 있다가 사라지게” 하자고 정해서 유지 1.0초에 페이드 0.35초를 붙였다. 숫자는 처음에 0.35배 크기로 나타나 0.12초 동안 1.15배까지 커졌다가 1.0으로 돌아온다. 이 작은 팝 하나로 숫자가 “튀어나온다”는 느낌이 난다.
히트스톱은 시뮬레이션을 멈추지 않는다
Godot 원본은 엔진 전체 속도(time_scale)를 0.04로 내리는 방식으로 히트스톱을 만들었다. Unity에서 같은 방법(Time.timeScale)을 쓰면 물리와 오디오까지 함께 느려진다. 그보다 큰 문제는 PallMark의 전투 규칙이 20Hz 결정론 시뮬레이션이라는 점이었다. 화면 연출 때문에 규칙 계산이 늦어지면 안 된다.
그래서 히트스톱을 렌더 전용 채널로 분리했다. 캐릭터 위치 보간, 애니메이터, 이펙트만 “표현 배율”을 따라 느려진다. 시뮬레이션 틱과 소리는 그대로 흐른다. 해제 시점은 벽시계로 잰다. 배율이 걸린 시간으로 재면 느려진 시간 때문에 영원히 풀리지 않는다. 원본 코드 주석에 이미 이 함정이 적혀 있었다.
지속피해(화상·독)는 히트스톱에서 뺐다. 원본 측정 기록이 이유를 잘 보여 준다. 불 골렘이 적 무리를 태우자 히트스톱이 초당 127번 갱신됐고, 프레임의 99.8%가 느린 상태였다. 게임 전체가 25배 슬로우모션이 된 셈이다.
떨림의 진범이 히트스톱이었던 날
8월 31일, 이동 보간을 고친 뒤에도 “전투 중에 적이 떨린다”는 보고가 다시 들어왔다. 보간 문제는 렌더 보간 글에서 이미 두 번 고친 상태였다. 이번에는 녹화 영상에서 연속 프레임의 픽셀 차이를 시계열로 뽑았다. 전투 구간에서만 0.9, 0.9, 0.0이 반복됐다. 세 프레임마다 한 프레임씩 화면 전체가 멈추고 있었다. 전투가 없는 구간은 매 프레임 연속이었다.
멈춘 프레임이 촘촘하면 타격감이 아니라 끊김으로 보인다. 도식의 간격은 설명용이다.
원인은 세 가지가 겹친 데 있었다.
- 내가 때린 모든 피해 이벤트가 히트스톱을 걸었다. 광역기로 다섯 마리를 맞히면 다섯 번, 연타면 매번 걸렸다. 원본에 없던 “공중 추가타 때 히트스톱 재무장” 규칙도 하나 끼어 있었다.
- 히트스톱 동안 캐릭터는 멈추는데 카메라는 멈추지 않는 시간 기준으로 계속 따라갔다. 세계는 얼었는데 카메라만 미끄러지니 화면 기준으로는 떨림이 더 커 보였다.
- 멈춘 동안에도 시뮬레이션은 전진하므로, 해제 순간 화면이 따라잡으며 점프했다.
고친 규칙은 다음과 같다. 같은 틱에 들어온 여러 피해는 한 묶음으로 보고 히트스톱을 한 번만 건다. 묶음이 진행 중일 때는 일반에서 치명타로 올라가는 연장만 허용한다. 새 묶음은 직전 묶음 시작에서 0.2초가 지나야 걸 수 있다. 1초에 최대 다섯 번이다. 원본에 없던 공중 추가타 재무장은 지웠고, 카메라도 같은 표현 배율을 따르게 했다. 세계가 멈추면 카메라도 멈춘다.
반증 시험도 세 개 넣었다. 같은 틱에 다섯 대상이 맞았을 때 멈춘 시간의 합이 한 번 맞은 것과 같은지, 배율 0에서 카메라가 움직이지 않는지, 기존 3프레임 감각이 유지되는지를 본다. 같은 날 Windows 테스트 PC에서 세 클래스를 120초씩 녹화해 다시 셌다. 수정 직후 녹화는 히트스톱 20회, 한 번에 1~2프레임, 최소 간격 0.4초였다. 최종 녹화는 클래스별 19·11·4회, 최소 간격 0.23초 이상이었다.
맞는 순간을 모션에 맞추기
9월 2일에는 반대 방향의 문제를 다뤘다. 각인병이 검을 휘두르는 모션과 피해 숫자가 뜨는 시점이 어긋나 보였다. 평타의 피해 판정은 시전 8틱 뒤(0.4초)에 난다. 그런데 공격 클립의 타격 프레임은 클립마다 달랐다. 그래서 클립을 타격 전과 타격 후 두 구간으로 나누고, 구간마다 재생 속도를 따로 계산했다. 이렇게 하면 칼끝이 닿는 순간이 정확히 0.4초에 오고 모션은 0.8초에 끝난다. 판정이 끝나고 회복하는 동안에는 이동 입력을 보관했다가 회복이 끝나는 틱에 적용한다. 휘두르다가 미끄러지듯 걸어 나가는 모습을 없애기 위해서였다.
정리하며
타격감은 효과를 더할수록 좋아지다가 어느 순간부터 나빠진다. 히트스톱 하나만 봐도 한 번 걸 때는 손맛이지만 1초에 열 번 걸리면 끊김이다. 지금 PallMark는 “같은 틱은 한 번, 0.2초 간격, 지속피해 제외”라는 세 줄로 그 경계를 정해 두었다. 수치 하나를 바꾸면 녹화에서 멈춘 프레임을 세는 방법으로 확인한다.
타격감이 가장 크게 드러나는 곳은 적이 몰려드는 층이다. 적 무리 AI와 성능 글에 그 장면을 144fps로 유지하는 이야기가 있다. PallMark는 개발 중이며 Steam 출시를 준비하고 있다. PallMark 게임 페이지에서 게임을 더 볼 수 있다.


