AppOrbit
← blog

토스 앱 안에서 주식 차트 예측 게임을 만들어봤다 — 1편: 기획과 시작

React, TypeScript, 앱인토스, 토스, 사이드프로젝트, 게임개발

1. 들어가며: 토스 앱 안에 게임을 넣는다고?

토스를 쓰다 보면 '만보기', '행운퀴즈' 같은 미니 콘텐츠들이 눈에 들어옵니다. 금융 앱인데 이런 게 왜 있을까 싶다가도, 매일 한 번은 꼭 열어보게 되는 자신을 발견하게 됩니다. 그러다 문득 이런 생각이 들었습니다.

"토스에 주식 차트 예측 게임이 있으면 재밌지 않을까?"

토스 증권을 쓰는 사람이라면 누구나 한 번쯤 "이 차트, 다음에 오를까 내릴까?" 하고 감으로 판단해본 경험이 있을 겁니다. 그 직감을 게임으로 만들면 어떨까. 맞히면 점수를 주고, 틀리면 하트가 줄어들고, 콤보가 쌓이면 보너스 점수를 주는 — 단순하지만 중독성 있는 그런 게임을 구상했습니다.

마침 토스에는 **앱인토스(Apps in Toss)**라는 미니앱 플랫폼이 있었고, 이 플랫폼 위에서 WebView 기반의 앱을 만들어 토스 사용자들에게 직접 서비스할 수 있다는 사실을 알게 되었습니다. 사이드 프로젝트로 이보다 매력적인 놀이터가 또 있을까 싶었습니다.

2. 핵심 기능과 UX

게임의 이름은 **"차트예측게임"**입니다. 규칙은 정말 단순합니다.

게임 플로우

  1. 실제 한국 주식 데이터에서 랜덤으로 90개의 캔들스틱을 보여줍니다
  2. 플레이어는 다음 10개 캔들이 **상승(LONG)**할지 **하락(SHORT)**할지 예측합니다
  3. 맞히면 점수를 얻고, 틀리면 하트를 잃습니다
  4. 하트가 0이 되면 게임 오버입니다

UX에서 신경 쓴 부분

금융 데이터를 다루는 게임이지만, 진입 장벽은 최대한 낮추고 싶었습니다. 차트를 읽을 줄 모르는 사람도 "올라갈 것 같다 / 내려갈 것 같다" 정도의 직감만으로 즐길 수 있어야 했습니다.

하트 시스템은 2개로 설정했습니다. 너무 많으면 긴장감이 없고, 1개면 첫 실수에 바로 끝나서 이탈률이 높아질 거라 판단했습니다. 2개는 "한 번은 실수해도 괜찮지만, 두 번째는 조심해야 한다"는 적절한 긴장감을 줍니다.

콤보 시스템도 넣었습니다. 연속으로 맞히면 콤보가 쌓이고, 3콤보마다 보너스 점수를 받을 수 있습니다. 이 장치가 있어야 "한 판만 더" 하는 동기가 생기기 때문입니다.

결과를 공개할 때는 나머지 10개 캔들이 순차적으로 드러나면서, 예측이 맞았는지 시각적으로 확인할 수 있게 했습니다. 맞혔을 때는 화면 전체에 짧은 플래시 효과와 점수 팝업이 뜨고, 콤보가 높아지면 confetti 애니메이션이 터지도록 했습니다. 이런 마이크로 인터랙션이 게임의 재미를 만드는 핵심이라고 생각합니다.

3. 기술 스택 선정 이유

React + TypeScript + Vite

앱인토스 플랫폼 자체가 WebView 기반이므로 웹 기술 스택이 필수입니다. React를 선택한 이유는 단순합니다 — 가장 익숙하고, 앱인토스 SDK가 React를 1순위로 지원하기 때문입니다.

Vite는 개발 서버 시작 속도와 HMR(Hot Module Replacement) 성능이 압도적이었습니다. 특히 이 프로젝트처럼 빈번하게 UI를 수정하며 실시간으로 확인해야 하는 게임 개발에서는 빌드 도구의 반응 속도가 생산성에 직접적인 영향을 줍니다.

TypeScript는 게임 상태 관리에서 빛을 발했습니다. 게임 페이즈(idle, playing, revealing, gameover)에 따라 UI가 완전히 달라지는 구조에서, 타입 시스템 없이 상태를 관리했다면 꽤 많은 런타임 에러를 겪었을 겁니다.

Zustand — 가볍고 직관적인 상태 관리

게임의 전체 상태를 하나의 스토어로 관리해야 했는데, Redux는 보일러플레이트가 과하고, Context API는 리렌더링 최적화가 까다로웠습니다. Zustand는 단 하나의 파일에 상태와 액션을 모두 정의할 수 있고, 선택적 구독(selective subscription) 패턴을 적용하기도 수월했습니다. 이 부분은 3편에서 자세히 다루겠습니다.

lightweight-charts — 전문가 수준의 캔들스틱 차트

차트 라이브러리 선택에는 꽤 고민이 있었습니다. Chart.js나 Recharts는 범용적이지만, 금융 차트에 특화된 라이브러리가 필요했습니다. lightweight-charts는 TradingView에서 만든 라이브러리로, 캔들스틱 차트를 네이티브에 가까운 성능으로 렌더링합니다. Canvas 기반이라 100개의 캔들을 그려도 프레임 드랍 없이 부드럽게 동작했습니다.

framer-motion — 애니메이션의 품질을 결정하는 도구

게임에서 애니메이션은 선택이 아니라 필수입니다. 점수가 올라갈 때의 팝업, 하트가 사라질 때의 떨림, 결과 배너가 나타날 때의 스프링 효과 — 이런 것들이 없으면 게임이 밋밋해집니다. framer-motion은 선언적인 API로 복잡한 애니메이션을 간결하게 표현할 수 있었고, 특히 spring 물리 엔진이 자연스러운 느낌을 주는 데 큰 역할을 했습니다.

앱인토스 SDK — 토스 네이티브 기능 연동

@apps-in-toss/web-framework@toss/tds-mobile은 앱인토스 개발에 있어 핵심 의존성입니다. 전자는 WebView와 네이티브 앱 사이의 브릿지 역할을 하고, 후자는 토스의 디자인 시스템을 그대로 사용할 수 있게 해줍니다. 버튼, 바텀시트, 토스트 같은 UI 컴포넌트를 토스 앱의 네이티브 느낌 그대로 쓸 수 있다는 점이 가장 큰 장점이었습니다.

4. 앱인토스 플랫폼이란?

앱인토스는 쉽게 말해 **"토스 안의 앱스토어"**입니다. 개발자가 웹 기술로 미니앱을 만들고, 토스 앱 내에서 유저에게 직접 서비스할 수 있는 플랫폼입니다.

기술적으로는 WebView 위에서 동작하되, 토스 네이티브 기능(결제, 로그인, 광고, 푸시 알림 등)에 접근할 수 있는 브릿지 API를 제공합니다. 즉, 웹 개발자가 네이티브 앱에 가까운 경험을 만들 수 있는 환경입니다.

개발 프로세스는 이렇습니다:

  1. Granite CLI로 프로젝트를 생성하고 로컬에서 개발합니다
  2. granite.config.ts에 앱 메타데이터(이름, 아이콘, 네비게이션 설정 등)를 정의합니다
  3. 개발이 끝나면 빌드 후 앱인토스에 제출합니다
  4. 심사를 거쳐 승인되면 토스 앱에 노출됩니다

이 과정에서 겪은 심사 반려 이야기는 5편에서 자세히 다루겠습니다.

5. 마치며

이번 1편에서는 프로젝트의 기획 배경, 핵심 게임 메커니즘, 그리고 기술 스택을 왜 그렇게 선택했는지를 정리했습니다.

사실 사이드 프로젝트에서 가장 어려운 건 기술적인 문제가 아니라, **"이걸 정말 만들어야 하나?"**라는 확신을 갖는 것이라고 생각합니다. 이 프로젝트의 경우, 토스라는 대규모 플랫폼 위에서 바로 유저를 만날 수 있다는 점이 그 확신을 만들어줬습니다.

다음 편에서는 게임의 핵심인 주식 데이터 처리와 게임 로직 설계에 대해 이야기하겠습니다. 실제 한국 주식 데이터를 어떻게 가공해서 게임에 활용했는지, 승패 판정 로직은 어떤 고민 끝에 나왔는지를 다룹니다.

👉 차트예측게임 바로가기