게임 엔진 없이 React와 Lottie만으로 모바일 게임을 만든 뱅크샐러드의 삽질기

썸네일

기획안에 게임이 있었어요. 캐릭터를 키우고, 옷을 갈아입히고, 복권도 긁는 인터랙션이 필요했죠. Phaser.js나 Pixi.js 같은 웹 게임 엔진을 검토했지만 러닝 커브와 일정을 고려하면 리스크가 너무 컸어요. 그래서 뱅크샐러드 팀은 익숙한 React와 DOM으로 승부하기로 결심했어요.

"일해라 김뱅샐"은 웹뷰 환경에서 게임 엔진 없이 React, DOM, Lottie 조합으로 만든 게이미피케이션 서비스예요. 금융 앱 안에 게임을 넣는다는 발상 자체가 도전적인데, 기술 선택까지 파격적이었죠.

Lottie JSON을 런타임에 조작해서 캐릭터 조합을 표현했다

첫 번째 난관은 캐릭터 커스터마이징이었어요. 유저가 머리, 옷, 안경 등을 자유롭게 조합할 수 있어야 했는데 조합 수가 상당했거든요. Lottie는 JSON 기반 포맷이라 런타임에 데이터를 조작할 수 있다는 점을 활용했어요. 이미지 에셋 경로를 동적으로 교체하면 하나의 Lottie 파일로 다양한 조합을 표현할 수 있었죠.

그런데 iOS 웹뷰에서 헤어스타일 목록 버튼을 누를 때마다 화면 전체가 리로드되는 현상이 터졌어요. `absolute inset-0 object-cover`로 이미지를 쌓아올리는 방식이 일부 iOS 디바이스에서 성능 문제를 일으킨 거예요. 해결책은 `img` 태그 대신 `background-image`를 쓰는 것이었어요. 이미지가 바뀌어도 DOM 트리가 아닌 스타일만 변경되니까 훨씬 안정적이었죠.

CSS 애니메이션이 Framer Motion보다 나은 순간이 있다

모바일 웹뷰에서 애니메이션을 많이 쓰면 배터리 소모와 발열까지 고려해야 해요. 타이핑 효과는 글자를 처음부터 모두 렌더링해두고 `opacity`만 변경하는 방식으로 최적화했어요. 레이아웃은 최초 한 번만 계산하고, 이후에는 GPU가 처리하는 opacity 변경만 일어나는 구조죠.

Framer Motion 같은 라이브러리 대신 가능한 한 CSS 애니메이션을 선택한 것도 의도적이에요. CSS 애니메이션은 브라우저의 컴포지터 스레드에서 처리되어 메인 스레드에 영향을 주지 않거든요. 탭이 백그라운드로 전환되면 브라우저가 자동으로 프레임을 낮추는 것도 덤이죠. 게임 엔진이 정답이 아닌 순간도 있다는 걸 이 프로젝트가 증명한 셈이에요.