System Design · Retention
연속 출석(단기) · 누적 출석(장기) 2종을 한 시스템으로 묶어 리텐션을 설계
출석 시스템은 만들기는 쉽지만 "왜 이 숫자인가"를 설명하기 어려운 시스템입니다. 이 문서는 연속 7일 · 누적 10일 간격 · 3개 보상 그룹 같은 값 하나하나에 벤치마킹과 판단 근거를 붙이고(Design Note), 만든 뒤에도 어느 일차에서 이탈하는지 · 보상이 실제 재접속 동기가 되는지 확인할 수 있도록 지표 로그까지 함께 설계했습니다.
재직 중 직접 작성한 사내 기획서를 포트폴리오용으로 재구성한 것입니다. 회사 로고 · 대외비 표기 · 편집자 메모는 제거했고, 테이블 · 컬럼명 · 지표 이벤트명은 실제 스키마와 다르게 표기했습니다(구조 · 의미는 동일). 화면 이미지는 당시 와이어프레임을 그대로 사용했으며, 데이터 테이블은 핵심 로직 설명용으로 축약되었습니다.
이슈
출석 시스템 = 유저의 게임 접속 여부와 빈도에 따라 보상을 주는 시스템. 하루에 한 번 출석 시 일일 보상을 지급하고, 출석의 종류를 연속 출석과 누적 출석 두 가지로 나눕니다.
출석 시스템 흐름
출석 (하루 1회)
미출석 상태에서 최초 접속 시 출석 상태로 전환
연속 출석
연속해서 출석한 횟수에 맞는 일일 보상 지급 — 미접속 시 초기화
누적 출석
총 출석한 횟수가 목표 수준에 도달하면 보상 지급 — 초기화 없음
설계 의도
연속 출석 하나만 두면, 하루라도 놓쳐 초기화됐을 때 실패에 대한 스트레스가 큽니다. 출석 일수가 커진 유저일수록 이 스트레스도 커져서, 오히려 이탈 사유가 될 수 있습니다.
그래서 초기화되지 않는 누적 출석을 별개 트랙으로 둡니다. 연속 출석은 단기 연속 접속을 유도하고, 누적 출석은 실패 부담을 상쇄하며 장기 리텐션을 담당합니다. 두 트랙은 완전히 독립적이지 않아서, 연속 출석에 데이터가 없으면 누적 출석까지 오류가 날 수 있어 디폴트 값 처리를 함께 설계했습니다.
출석 체크 — 상태와 전환
미출석 상태
계정 생성 시 최초 상태. UTC 00시가 되면 이 상태로 초기화
→ 출석 상태
하루 동안 게임에 최초 접속 시 미출석 → 출석 상태로 전환
출석 횟수를 계산해 연속으로 출석한 횟수와 총 누적 출석 횟수를 각각 관리하고, 그에 따라 보상이 지급됩니다. 유저 출석 상태는 출석 시스템이 활성화된 이후부터 체크합니다.
기본 규칙
Design Note — 연속 출석부 길이를 7일로 정한 이유
출석부가 너무 길거나 짧으면 유저가 목표로 삼기 어렵다고 판단했습니다. 벤치마킹한 캐주얼 게임(모노폴리 고 · 코인 마스터 · 트리플 매치 등)이 대부분 7일로 설정되어 있었고, 사회적으로 1주일(7일)이 기본 생활 주기라 유저가 이해하고 적응하기 쉬울 것이라 판단해 7일로 정했습니다.
ContinuousRewardTable
연속 출석 일차별 보상 정의
| 컬럼 | 자료형 | 설명 |
|---|---|---|
PatternId | Integer | 일일 보상 세트(패턴)를 구분하는 값 |
DayIndex | Integer | 패턴 내 일차 (1~7) |
RewardId | Integer |
|
Design Note — 연속 출석 보상 운영을 Constant 값으로 관리
초기엔 운영 웹에서 출석 스케줄을 관리하려 했으나 개발을 중지했습니다. 운영 웹 구현·유지 비용이 콘텐츠 볼륨에 비해 크고, 연속 출석 보상을 자주 교체하지 않을 것이며, 월 1회 패치 때 Constant 테이블의 '기본 연속 출석부 ID' 값만 바꿔주면 보상 교체가 가능하다고 판단했기 때문입니다. 정의되지 않은 기간엔 이 기본값을 불러와 오류를 방지합니다.
기본 규칙
Design Note — 누적 출석 보상이 10일 간격인 이유
자주 지급하면 보상으로 줄 수 있는 아이템이 금방 고갈됩니다. "월에 몇 번 보상을 지급할 것인가"를 기준으로 세웠을 때, 2번은 장기 접속 동기로 부족하고, 4번은 연속 출석 지급과 겹칠 것으로 판단해 3번(10일 · 20일 · 30일)으로 선정했습니다.
누적 출석 보상 그룹 — 3개씩 묶음
Group 001
보상 A(10일) · B(20일) · C(30일)
Group 002
보상 A(40일) · B(50일) · C(60일) — 이전 그룹 전부 수령 시 '갱신'
Group 003 …
동일 구조로 반복. 누적 출석일은 그룹 갱신과 별도로 계속 증가
Design Note — 보상을 3개씩 그룹으로 묶은 이유
유저에게 보이는 화면은 한정적이라 모든 보상을 한 화면에 보여줄 수 없습니다. 유저가 월 단위로 보상을 인지하고 목표를 세울 수 있도록 3개(≈30일) 단위로 구분했고, 그룹별로 동일 컨셉의 코스튬을 연달아 지급하면 "세트를 다 모으는 것"이 출석 동기가 됩니다.
Design Note — 누적 출석부 길이를 뒤에 계속 늘리지 않은 이유
새 보상을 출석부 뒤에 계속 추가하는 방식은 ① 리소스 제작 속도가 업데이트 속도를 못 따라가고 ② 장기 유지 유저 일부만을 위한 업데이트가 된다는 문제가 있습니다. 현재 출석부를 다 진행한 유저에게는 동일한 보상을 반복 지급하는 방식을 도입해, 누적 보상 데이터가 없어 생기는 오류를 막고 새 리소스를 제작할 시간을 벌 수 있게 했습니다.
그룹 진행도 — 프로그레스 바
GroupProgress
현재 그룹의 총 길이(30일) 대비 유저의 출석일을 수치로 (0 ~ 30). 예: 24/30 = 80%
표시
보상 A·B·C 획득 지점에 마커. 그룹이 갱신될 때 0으로 초기화
Design Note — 그룹 진행도가 필요한 이유
보상까지 남은 수치가 안 보이면 유저가 직관적으로 받아들이기 어렵습니다. 전체 출석일이 아니라 그룹별 진행도를 프로그레스 바로 보여줘, 출석할 때마다 바가 눈에 띄게 차서 성취감을 느끼고 '이 그룹을 다 채우는 것'을 단기 목표로 삼도록 했습니다.
CumulativeRewardTable
누적 출석 그룹별 보상 정의
| 컬럼 | 자료형 | 설명 |
|---|---|---|
GroupKey | Integer | 그룹을 구분하는 값 |
TargetDay | Integer |
|
RewardId | Integer | 누적 보상 패키지 ID (아이템 ID · 수량 · 리소스 포함, RewardData 참조) |
GroupImage | String | 그룹 이미지 파일명 (컨테이너로 관리) |
팝업 창 호출 조건
출석 시스템 활성화
게임 시작
비활성화 상태 — 출석 처리 안 됨, 알림 아이콘 미표시
트로피 점수 달성
트로피 점수가 기준치를 넘으면 활성화
출석 시스템 활성화
활성화된 날부터 출석 처리 · 연속/누적 출석 · 로비/옵션 아이콘 활성화
Design Note — 활성화 시점에 대한 고민
출석 시스템을 언제부터 유저에게 학습시키고 보상을 지급할지 고민했습니다. 빨리 하면 초기 리텐션은 올릴 수 있지만 아직 언락되지 않은 아이템이 보상으로 지급될 수 있고, 늦게 하면 초기 리텐션을 못 올립니다. 기본 튜토리얼이 끝나고, 글러브 종류에 따라 효과가 다르다는 것을 학습했을 것으로 판단되는 트로피 점수를 활성화 시점으로 결정했습니다.
팝업 창 영역
보상 수령 화면
리워드 팝업창
수령할 보상 이미지 · GET 버튼
박스 개봉 연출
보상이 랜덤 박스인 경우 — 글러브 박스 → 서브 스킬 박스 → 스티커 박스 순 개봉 (기존 연출 재사용)
출석 연출 자체는 팝업창의 컨셉을 정한 뒤 파트 담당자와 협의하도록 열어두고, 보상 수령 연출은 별도 구현 없이 현재 게임에 도입된 연출을 재사용했습니다.
"만들고 끝"이 아니라, 출석부가 실제로 리텐션에 기여하는지 확인할 수 있도록 로그를 함께 설계했습니다.
공통 추적자 속성 (모든 출석 이벤트에서 수집)
이벤트 로그
출석부 도입에 따른 지표 변화를 판단하기 위한 4개 이벤트
| 컬럼 | 자료형 | 설명 |
|---|---|---|
attendance_info_checked | 로비 진입 전 |
|
continuous_reward_claimed | 연속 보상 수령 시 |
|
cumulative_reward_claimed | 누적 보상 수령 시 |
|
attendance_popup_opened | 팝업 호출 시 |
|
회고
출석 시스템은 기능 구현보다 "이 숫자가 왜 이 값인가"를 팀에 설득하는 게 어렵습니다. 7일 · 10일 · 3그룹 같은 값에 벤치마킹과 판단 근거를 붙여 문서화했고, 만든 뒤에도 지표 로그로 검증·개선할 수 있게 한 것이 이 설계의 핵심입니다.