chorock.page
소개글시리즈프로젝트
© 2026 chorock.page
← 프로젝트 목록

Project

부 키우기

한국외대 마스코트 '부'를 학식·퀴즈·미니게임으로 키우는 육성형 캠퍼스 앱 (캡스톤디자인)

작업 기간

2026.03 — 2026.06

프로젝트 정보

팀 구성

캡스톤 팀 6명 — 프론트엔드 1명(본인) · 백엔드 2명 · 기획 3명

담당 역할

프론트엔드 개발

GitHub

목차

맡은 일성과와 한계주요 기능문제 해결검증발표 슬라이드
목차
맡은 일성과와 한계주요 기능문제 해결검증발표 슬라이드

사용 기술

앱

React NativeExpo (SDK 56)Expo RouterTypeScriptReact 19

상태·데이터

Zustand (persist)Tanstack QueryAsyncStorageAxios

연출·에셋

Reanimatedexpo-imageexpo-audioreact-native-svgmatter-js

프로젝트 개요

한국외대 마스코트 캐릭터 부를 펫처럼 키우는 육성형 캠퍼스 앱입니다. 학식·퀴즈·미니게임·마이룸·친구 같은 학교 생활 요소를 캐릭터 성장에 연결해서, 정보를 "찾아보는" 대신 게임 안에서 자연스럽게 소비하게 만드는 것이 목표였습니다. 캡스톤디자인 팀 프로젝트이고, 저는 앱(프론트엔드) 전체를 맡았습니다.

맡은 일

Expo(React Native) 앱 전체입니다. 6명 팀에서 프론트엔드는 저 혼자였습니다(백엔드 2명, 기획 3명). 화면과 게임 로직, 상태 설계, 서버 API 연동, 실기기 빌드/테스트를 담당했습니다. 백엔드는 FastAPI(JWT, 9자리 학번 로그인, @hufs.ac.kr 메일 인증으로 외대 구성원만 가입)였고, 프론트를 붙이면서 계약이 어긋나는 지점을 문서로 정리해 백엔드에 넘겼습니다.

성과와 한계

  • 학식 데이터는 제가 외대종강시계에서 만들어 운영 중이던 크롤링 API를 그대로 가져다 썼습니다. 덕분에 빠르게 붙었지만, 그 API가 학교 페이지 구조 변경에 취약하다는 한계도 같이 물려받았습니다.
  • 부하 테스트 대상은 로그인이 필요 없는 조회(GET) API 3종이었습니다. 인증 경로와 쓰기 작업은 포함되지 않았으므로 실패율 0%를 서비스 전체의 안정성으로 읽으면 안 됩니다.
  • 스토어에 배포하지 않았습니다. 유료 애플 개발자 계정이 없어 iOS는 유선 설치만 가능했고, Android도 오류 하나를 고칠 때마다 APK를 다시 빌드해야 해서 테스트 사이클이 길었습니다. 실제 사용자에게 전달된 적은 없습니다.
  • 수업이 끝나면서 백엔드 서버가 내려갔습니다(확인 시점 기준 응답 없음). 로그인이 필요한 기능은 지금 동작하지 않습니다.

주요 기능

접속 → 부 상태 확인 → 학식/퀴즈 → XP 성장 → 진화 → 마이룸 확장이라는 하루 루프를 먼저 설계하고 그 위에 기능을 붙였습니다.

  • 성장 루프 — 학식과 퀴즈로 XP를 쌓아 새내기부터 졸업까지 진화하고, 임계치 아래로 떨어지면 유급됩니다. 학년별 XP를 따로 저장하지 않고 누적 XP 하나만 두고 학년과 진행률은 클라이언트에서 계산합니다.
  • 학식·퀴즈 — 시간대별 먹이기 제한과 끼니를 거르면 XP가 깎이는 공복 시스템, 학사·캠퍼스 정보를 내는 O/X·객관식 퀴즈.
  • 미니게임 3종 — 전공책 받기, 부 잡기, 자유투 넣기. 하트를 소모해 시작하고 성공하면 코인을 받으며 랭킹은 전체/친구로 나뉩니다.
  • 마이룸·친구·업적·졸업 리포트, 게스트 모드, 픽셀 아트 UI(팀에서 Figma로 제작).

문제 해결

화면만 있는 앱이 아니라 성장 게임이라, 행동 하나가 여러 도메인으로 연쇄됩니다. 퀴즈 정답 하나가 XP → 학년 상승 → 진화 화면 → 서버 통계까지 번지고, 미니게임 성공은 하트 차감 검증 → 결과 저장 → 코인 보상 → 랭킹으로 이어집니다. 초기에는 로컬 데이터 중심으로 빠르게 만들었는데, 서버가 붙으면서 이 연쇄의 단계마다 무엇을 권위 있는 값으로 볼 것인가를 다시 정해야 했습니다.

로컬 더미에 가려진 장애를 드러낸 일

로그인 상태인데도 로컬 더미가 화면에 보이면, 서버가 데이터를 안 주고 있는 건지 잘 주고 있는 건지 구분할 수가 없습니다. 장애가 더미에 가려집니다. 그래서 로그인 상태에서는 로컬 fallback을 대부분 차단하고, 핵심 데이터가 비면 화면이 의도적으로 실패를 드러내도록 뒀습니다. 대신 서버 없이 넓게 테스트해야 하는 기능을 위해 로컬과 서버를 완전히 분리한 게스트 모드를 따로 만들었습니다.

이 원칙 덕분에 실제 장애가 드러났습니다. 마이룸 가구 구매가 안 되던 건은 프론트 버튼 문제가 아니라 서버 /shop/items가 200으로 빈 배열을 주고 있었던 것이었고, 로그를 근거로 백엔드에 전달했습니다. 신규 유저의 캐릭터 동기화 403도 같은 방식으로 잡았습니다.

같은 기준으로 낙관적 업데이트의 범위도 정했습니다. 친구 요청 수락이나 가구 장착처럼 단순한 동작은 성공을 가정하고 화면을 먼저 바꾼 뒤 실패하면 되돌리지만, 하트 차감·상점 구매처럼 코인과 소유권이 걸린 작업은 그렇게 하면 실패를 숨기게 됩니다. 이런 경로는 로딩 오버레이로 진행 상황을 보여주고 서버 성공을 권위값으로 삼았습니다.

기기를 바꾸면 무엇이 사라지는지 먼저 적어보고 고친 일

로컬에 쌓이는 값이 늘면서, 새 기기에서 로그인하면 무엇이 어긋나는지 불안해졌습니다. 증상을 기다리는 대신 저장 상태를 전부 나열하고 서버에서 복구 가능한 것과 아닌 것으로 갈라 문서로 정리했습니다.

위험한 항목이 분명해졌습니다. 끼니 누락 횟수와 이미 적용한 XP 패널티가 로컬에만 있어서, 기존 기기에서는 배고픈 상태였는데 새 기기에서는 멀쩡해 보이고 패널티도 기기마다 다르게 적용될 수 있었습니다. 퀴즈 일일 카운터도 마찬가지였고, 둘 다 XP·코인이 걸린 값이라 경제 밸런스로 이어집니다. 로그인 상태에서는 서버 값만 기준으로 삼고 로컬 값은 비로그인 fallback 전용으로 격리했습니다.

게임 라이브러리가 아닌 도구로 미니게임을 만든 일

React Native는 게임 엔진이 아닙니다. 전공책 받기나 부 잡기는 수월했지만, 자유투는 물리적 상호작용이 필요해서 애를 먹었습니다. 물리 엔진을 도입했는데 공이 의도대로 움직이지 않았습니다.

추측 대신 시간별 궤적 지점을 화면에 찍어 시각화하면서 디버깅했습니다. 그러자 눈으로 바로 보였습니다 — 던지기도 전에 이미 중력이 작용하고 있었습니다. 결국 궤적은 시간별 이동 경로를 좌표로 직접 지정하는 방식으로 만들었습니다. 물리 엔진을 제대로 다루지 못해 택한 우회였고, 자연스러운 느낌을 내는 게 끝까지 가장 어려웠습니다.

검증

기능이 도는지가 아니라 목표를 달성했는지를 확인하는 쪽으로 테스트를 짰습니다.

  • 기능 테스트 — 54개 시나리오를 판정해 51 Pass, Unstable 3, Fail 0. Unstable 3건은 전부 로딩 지연이었고 감추지 않고 남겼습니다.
  • 사용성 테스트 — 한국외대 재학생·휴학생·졸업생 20명 설문. 평균 만족도 4.6, 정보 습득에 도움 93%, 학교 생활 흥미 상승 65%.
  • 성능 테스트 — Locust 부하 테스트. 동시 50명까지 총 3,546건 요청에 평균 응답 342.74ms, 실패율 0%.

발표 슬라이드

프로젝트 소개 — 성장 루프와 학년별 XP 임계치

캠퍼스 미니게임 3종 — 전공책 받기 · 부 잡기 · 자유투 넣기

마이룸 — 가구 · 벽지 변경, 상점, 친구 방 방문과 방명록

업적 달성과 캐릭터 디자인 해금