PC에서는 잘됐는데 스마트폰에서 문제가 생겼다 — 《매스워》 오류 수정과 발열 최적화 기록

매스워 초기 화면의 겹친 HUD와 개선 후 분리된 전투 화면 비교

《매스워(Math War)》를 개발하면서 가장 많이 했던 일은 새로운 기능을 추가하는 것보다 이미 만든 기능을 다시 확인하고 수정하는 일이었다. Google Antigravity는 원하는 기능을 설명한 뒤 실제 게임 화면으로 확인하기까지의 과정이 빨랐다. 하지만 빠르게 만들어진 결과물이 항상 정상적으로 동작하는 것은 아니었다.

PC에서 잘 실행되던 게임이 스마트폰에서는 다르게 보였고, 기능 하나를 수정한 뒤 예상하지 못한 오류가 나타나기도 했다. 이번 글에서는 그 과정에서 부딪힌 문제와 수정 방향, 아직 확인이 필요한 부분을 정리해 보려고 한다.

앞선 이야기: 1편 — 개발을 시작한 이유 · 2편 — 전투와 보상 · 3편 — 개발 환경

브라우저 창을 줄였더니 게임 맵까지 작아졌다

초기 개발 기록에는 브라우저 창 크기를 바꾸면 캐릭터가 움직이는 게임 공간까지 영향을 받았던 문제가 남아 있다. 화면 표시 크기와 게임 내부 좌표를 분리할 필요가 있었다.

현재 프로젝트는 전투 영역의 논리 크기를 720×1040으로 두고, 실제 화면 크기에 맞춰 표시한다. 이것은 스마트폰의 실제 해상도가 아니라 게임 안에서 위치와 움직임을 계산하는 기준이다. 기기별 표시와 조작감은 별도로 테스트해야 한다.

첫 모바일 테스트에서 전투 화면이 가려졌다

개발 기록에 따르면 스마트폰에서 게임을 열었을 때 체력과 웨이브 정보를 표시하는 상단 HUD가 전투 영역 위에 겹쳤다. 정보창 뒤로 적과 공격이 가려지면 플레이어가 상황을 파악하기 어렵다.

수정 전

매스워 초기 모바일 전투 화면의 상단 HUD가 맵 위에 겹쳐진 모습
초기 모바일 테스트 화면. 상단 정보창이 전투 영역 위에 겹쳐 표시됐다.

초기에는 정보창과 조작 버튼을 게임 화면 위에 겹쳐 표시했다. 모바일에서는 작은 화면을 더 많이 가리는 문제가 있었다.

수정 후

화면을 상단 정보 영역, 중앙 전투 영역, 하단 조작 영역으로 나눴다. HTML과 CSS의 세로 배치를 이용해 전투 공간을 따로 확보하는 방식이다.

매스워의 모바일 HUD와 전투 영역, 하단 조작 버튼을 분리한 개선 화면
상단 HUD, 중앙 전투 화면, 하단 조작 버튼을 각각 분리한 이후의 화면.

단순히 정보를 많이 보여주는 것보다 플레이어가 실제로 게임을 조작할 공간을 확보하는 것이 중요하다는 점을 배웠다.

캐릭터와 몬스터가 충돌하자 화면이 멈췄다

개발 기록에는 초기 충돌 테스트 중 캐릭터가 몬스터와 맞닿았을 때 게임이 멈추거나 정상적으로 진행되지 않았다는 내용이 있다. 당시 사용한 AABB는 캐릭터와 몬스터를 둘러싼 직사각형 영역이 겹치는지 확인하는 방식이다.

기록에는 피격 후 무적 시간과 넉백 처리를 정리한 내용이 있다. 현재 코드에서도 AABB 판정과 피격 후 무적 타이머를 확인할 수 있다. 다만 지금 보관된 코드만으로 당시 멈춤의 정확한 원인을 독립적으로 재현한 것은 아니다.

수정한 코드가 바로 반영되지 않는 문제도 있었다. 개발 기록에는 브라우저 캐시가 관련 원인으로 언급된다. 현재 스크립트와 스타일에는 버전 쿼리가 붙어 있고 서비스 워커에도 캐시 버전이 있다. 충돌 오류와 캐시 문제는 서로 다른 현상으로 구분해서 살펴봐야 했다.

보스는 쓰러졌는데 플레이어도 죽어버렸다

보스를 처치한 뒤 퀴즈 화면으로 넘어가기 전에 짧은 슬로우모션을 넣었다. 개발 기록에는 이때 남아 있던 적의 공격 때문에 게임오버와 퀴즈 화면이 겹칠 수 있었던 사례가 나온다.

수정 기록은 보스 처치 시 남은 적과 공격을 정리하고 플레이어에게 무적 시간을 주는 방향을 설명한다. 현재 코드에서는 적 목록을 비우고 1.2초의 무적과 0.55초의 슬로우모션을 설정하는 부분을 확인할 수 있다. 화면 전환 순간의 게임 상태를 관리하는 일이 중요했다.

게임이 너무 쉬워지거나 진행이 막히는 문제도 있었다

수학 퀴즈의 연승 보상으로 캐릭터가 지나치게 빨리 강해지거나, 특정 배율에 도달하지 못하면 진행이 끊기는 문제도 개발 기록에 남아 있다. 적의 성장 구조와 골드 상점을 조정하고 퀴즈에 실패해도 다음 단계로 진행할 수 있도록 규칙을 바꿨다. 구체적인 전투와 보상은 2편에서 다뤘다.

스마트폰 테스트에서 확인이 필요했던 발열 문제

개발 기록에는 지인 테스트 과정에서 스마트폰 발열에 관한 피드백이 있었다고 남아 있다. 보관된 대화 화면에는 모바일 웹게임의 발열과 성능에 관한 설명이 보인다. 다만 그 화면만으로 제보 날짜나 실제 기기 측정 결과까지 확인할 수는 없었다.

스마트폰 웹게임의 발열과 프레임 저하 원인을 설명하는 대화 화면
스마트폰 웹게임에서 발열이 발생할 수 있는 원인을 논의한 대화 일부. 실제 기기 온도나 성능을 측정한 자료는 아니다.

PC와 스마트폰은 화면 크기와 발열 환경이 다르다. 계속 실행되더라도 기기가 뜨거워지거나 움직임이 느려진다면 편하게 플레이하기 어렵다. 그래서 반복되는 렌더링 작업과 모바일 화면 효과를 점검했다.

당시 기기 온도나 장시간 FPS 측정 결과는 확인하지 못했다. 발열이 얼마나 줄었는지, 서멀 스로틀링이 실제로 발생했는지 또는 문제가 완전히 해결됐는지는 단정할 수 없다.

발열을 줄이기 위해 렌더링 방식을 수정했다

공격과 보스 탄막, 마법진, 빛나는 효과는 게임을 풍부하게 보이게 하지만 화면을 그리는 작업도 늘린다. 모바일에서 반복되는 렌더링 부담을 줄이기 위해 몇 가지 방법을 적용했다.

빛 효과를 미리 만들고 재사용하기

자주 사용하는 빛 효과를 매 프레임 새로 계산하는 대신 별도의 캔버스에 만들어 재사용했다. 현재 RenderPerf.js의 GlowCache와 GlowSprites에서 이 구조를 확인할 수 있다. 일부 효과에는 기존 shadowBlur 처리도 남아 있다.

높은 주사율에서 계산 횟수 조절하기

개발 기록과 코드 주석에는 120Hz 이상 환경에서 60FPS를 목표로 제한하는 내용이 있다. 코드는 프레임 간격을 추정해 일부 프레임을 건너뛰는 방식이다. 모든 기기에서 정확히 60FPS가 보장된다는 뜻은 아니다.

화면 픽셀 밀도와 유휴 렌더링 관리

DPR은 CSS상 크기와 실제 픽셀 크기 사이의 비율이다. 현재 기본 설정에서는 모바일 Canvas의 DPR 상한을 1.5로 두며, 테스트 설정에 따라 달라질 수 있다. 선명도와 처리량 사이의 차이도 고려해야 한다.

로비와 퀴즈, 게임오버처럼 전투가 진행되지 않는 상태에서는 불필요한 전투 화면 렌더링을 줄이도록 했다. 모달의 실시간 배경 블러를 어두운 레이어로 바꾸는 처리도 코드에서 확인된다. 이런 수정이 모든 기기의 발열을 해결했다는 뜻은 아니다. 정확한 개선 정도는 같은 기기에서 수정 전후를 비교하고 장시간 플레이하며 확인해야 한다.

Google Antigravity로 빠르게 고쳤지만, 검수는 별개의 일이었다

문제와 수정 방향을 설명하면 Antigravity가 실제 코드와 파일을 빠르게 바꾸는 점은 편리했다. 하지만 결과가 프로젝트 전체에서 정상적으로 작동하는지와 실제 스마트폰에서 사용하기 편한지는 별도로 확인해야 했다.

모바일 HUD 문제와 발열 관련 개발 기록은 코드가 실행된다는 사실만으로 충분하지 않다는 점을 보여준다. 앞으로 Codex와 Claude Code도 비슷한 작업에 사용하면서 수정 후 검수와 프로젝트 이해도, 기능 사이의 영향 분석을 비교해 볼 생각이다.

이번 시행착오에서 배운 점

게임은 PC에서 실행된다는 이유만으로 완성됐다고 볼 수 없었다. 모바일에서는 버튼과 정보창의 위치가 중요했고, 스마트폰에서 오래 플레이할 수 있는지도 고려해야 했다. 기술적인 오류가 없어도 게임 규칙이 재미를 방해할 수 있었다.

새로운 기능을 추가하는 일만큼 직접 플레이하고, 다른 사람에게 테스트받고, 다시 수정하는 과정이 중요했다. 모든 문제가 완벽하게 해결됐다고 말할 단계는 아니지만, 실제 모바일 테스트와 수정 과정을 통해 게임 구조를 발전시킬 수 있었다.

다음 편: “게임이 아니라 설명서 같아” — 《매스워》 UI 개편과 WEEDSGAMES 로고 제작기

응답

  1. […] 4편에서는 스마트폰 오류 수정과 발열 최적화 과정을 […]

답글 남기기