본문으로 건너뛰기

사주고사 제작기 07. 힌트-정답 겹침 수정과 캐릭터 20명 확장

·12 min read·7 / 13

추리 모드를 며칠 굴려보니 콘텐츠 쪽 문제가 드러났다. 힌트가 정답을 알려주고 있었고, 선택지가 서로 구별이 안 됐다. 아이콘 정리부터 시작해서 하루 종일 콘텐츠를 손봤다.

이모지가 106곳에 박혀 있었다

오행 힌트, 등급 표시, 랜딩 피처, 모드 선택, 공유 텍스트에 유니코드 이모지가 흩어져 있었다. OS와 브라우저마다 다르게 그려지고, aria-label이 없어서 스크린리더가 읽을 게 없고, 크기와 색을 CSS로 못 잡는다.

lucide-react도 네 파일에서 쓰고 있어서 Phosphor Icons 하나로 통일했다. 랜딩 피처와 온보딩 슬라이드, 모드 선택기, 타임라인 등급 표시가 전부 아이콘 컴포넌트로 바뀌었고, 토스트와 잠금 표시, 새로고침, 로딩 스피너도 같이 넘어갔다.

시나리오 데이터에서는 오행 앞에 붙어 있던 이모지 96건을 걷어냈다. 물방울 기호가 붙은 (水)가 그냥 (水)가 되면서 element 필드가 순수 텍스트가 됐다. 데이터에 표현 요소가 섞여 있으면 나중에 화면에서 다르게 그리고 싶을 때 데이터를 고쳐야 한다.

랜딩 카드 8개를 3스텝으로 줄였다

히어로 아래로 피처 카드 5개와 진행 방식 카드, 모드 선택, CTA가 줄줄이 있었다. 스크롤이 길고 뭘 봐야 하는지 안 잡혔다.

피처 카드와 진행 방식을 타임라인 레일 3스텝으로 압축했다. 아이콘과 세로 연결선으로 순서를 보이게 했다.

占 문자 뒤에는 CSS만으로 오라 효과를 넣었다. 바깥 원뿔 그라디언트가 25초 주기로 정방향, 안쪽이 14초로 역방향 회전하고, 파문 링 세 개가 3.5초 주기에 1.2초씩 시차를 두고 퍼지고, 중심이 3초로 밝기를 오간다. 회전 방향과 주기를 다르게 두면 겹치는 지점이 계속 달라져서 같은 패턴이 반복되는 느낌이 덜하다.

힌트를 읽으면 답이 보였다

가장 큰 문제였다.

힌트: "수(水) 부족 — 감정의 유연성이 없어 몸이 먼저 경고를 보낸다"
정답: "몸이 먼저 신호를 보냈다"

"몸이 먼저"가 힌트와 정답에 그대로 들어 있다. 추리할 게 없다.

겹치는 정답 44건을 전부 갈아엎었다. 그런데 고친 정답이 너무 시적이었다. "쌓아올린 탑이 모래 위에 있었다" 같은 문장이 나왔는데, 오답들은 구체적인 서술이라 정답만 톤이 달라서 오히려 더 잘 보였다. 겹침을 없앴더니 문체가 정답을 알려주게 된 것이다.

37건을 다시 고치면서 원칙을 하나로 잡았다. 네 선택지의 톤이 같아야 한다.

수정 전: "쌓아올린 탑이 모래 위에 있었다"        (시적 — 정답이 튄다)
수정 후: "퇴근길 지하철에서 공황장애가 찾아왔다"  (구체적 — 오답과 같은 톤)

3차로 남은 추상적 표현을 일상어로 바꿨다.

힌트가 "몸"을 언급하면 몸 관련 정답을 고르는 건 자연스럽다. 그걸 완전히 막을 수는 없고 막을 필요도 없다. 읽자마자 답이 보이는 수준만 없애면 됐다. 지금 체감으로는 쉬움 30%, 보통 50%, 어려움 20% 정도인데 실제 사용자 반응을 봐야 안다.

8명이면 세 번째 판에 아는 캐릭터가 나왔다

리플레이 가치가 떨어져서 20명으로 늘렸다. 12명을 한 번에 만들면 컨텍스트가 감당이 안 돼서 4명씩 세 배치로 나눠 병렬 생성했다.

c9부터 c18까지는 문제 데이터에 캐릭터 프로필이 이미 있어서 시나리오만 붙이면 됐다. 조현우(1955년생 산업화세대)와 나은빈(1975년생 도예가 싱글맘)은 캐릭터부터 새로 만들었다.

detective-scenarios.ts        — c1-c8 + batch import
detective-scenarios-batch1.ts — c9-c12
detective-scenarios-batch2.ts — c13-c16
detective-scenarios-batch3.ts — c17-c20

메인 파일에서 배치를 가져와 펼친다.

import { batch1Scenarios } from './detective-scenarios-batch1';
import { batch2Scenarios } from './detective-scenarios-batch2';
import { batch3Scenarios } from './detective-scenarios-batch3';
 
export const detectiveScenarios: DetectiveScenario[] = [
  // c1-c8 인라인
  ...batch1Scenarios,
  ...batch2Scenarios,
  ...batch3Scenarios,
];

캐릭터를 만들 때 시대와 직업, 성별, 사주 구성을 의도적으로 흩어놨다. 1955년생부터 2005년생까지 있고, 산업화세대 가부장부터 Z세대 투자청년까지 들어간다. 같은 오행이라도 시대와 환경이 다르면 전혀 다른 이야기가 나온다. 오행 조합만 바꾸고 배경이 비슷하면 캐릭터 수만 늘고 체감은 그대로다.

캐릭터 데이터가 두 파일에 나뉘어 있었다

수작업으로 만든 c1과 c2는 mock-questions.ts에, 생성한 c3부터는 generated-questions.json에 있었다. 런타임에 둘을 합치는 구조였는데 c1과 c2가 따로 있을 이유가 없었다.

JSON 한 곳으로 합치고 mock-questions.ts는 타입 캐스팅해서 내보내는 역할만 남겼다.

import { type Character, type Question } from '../types';
import generatedData from './generated-questions.json';
 
export const mockCharacters: Character[] = generatedData.characters as Character[];
export const mockQuestions: Question[] = generatedData.questions as Question[];

합치는 건 손으로 하지 않고 Node.js 스크립트로 돌렸다. 캐릭터 20명에 문제 102개를 손으로 옮기면 반드시 하나가 틀어진다.

선택지 네 개가 전부 같은 얘기였다

찍기 영역이라는 피드백을 받고 20캐릭터의 라운드를 전부 훑었다. 22개 라운드에서 변별력이 없었다.

유형설명예시
동의어 쌍표현만 다른 같은 의미"교직 선택" vs "다른 직업 고민했지만 교직"
주제 독점서너 개가 같은 주제의 변주네 개 다 리더십 유형
대칭 중복둘씩 짝이 묶임"성공 후 공허" vs "성공 후 고독"
메타·추상구체적 행동이 아닌 서술"변화를 받아들였다"

원칙은 하나로 정했다. 각 선택지가 서로 다른 심리와 행동 차원을 대표해야 한다. 힌트가 물의 기운이 강한 사람이라고 알려줬으면, 네 선택지가 각각 건강과 재정, 관계, 감정처럼 다른 영역을 건드려야 힌트로 추릴 수 있다. 같은 영역 안에서 표현만 다르면 힌트가 아무 역할을 못 한다.

수정 전:
  "학교 축제 기획단에서 리더로 뛰었다"      (리더십-이벤트)
  "체육대회 응원단장을 자처했다"             (리더십-체육)
  "학급 반장으로 매 학기 반을 이끌었다"       (리더십-학급)
  "교내 봉사 동아리를 직접 만들었다"          (리더십-봉사)
 
수정 후:
  "학교 축제 기획단에서 리더로 뛰었다"        (행동)
  "체육대회 응원단장을 자처했다"              (신체)
  "전교 1등을 놓치지 않으며 학업에 올인했다"   (학업)
  "밴드부에서 기타를 치며 무대에 섰다"         (예술)

가장 많이 고친 건 송미래였다. 대기업 커리어 캐릭터라 선택지가 전부 일과 가정의 갈등 안에 갇혀 있었다. 네 라운드를 신체 건강과 커리어 전략, 인간관계, 가족 역할로 흩었다.

막힌 지점과 원인

문제원인해결
힌트만 읽어도 정답이 보임힌트와 정답에 같은 키워드가 들어감겹치는 정답 44건 교체
고친 정답이 오히려 더 눈에 띔정답만 시적이라 문체가 단서가 됨37건을 오답과 같은 구체적 톤으로 재작성
선택지 네 개가 구별 안 됨같은 주제의 표현 변주22개 라운드를 서로 다른 차원으로 재구성
캐릭터 데이터가 두 파일에 분산수작업 분과 생성분을 런타임에 병합JSON 한 곳으로 통합, 스크립트로 이관
이모지가 화면마다 다르게 보임106곳에 유니코드 이모지 사용Phosphor Icons로 통일

힌트와 정답이 겹치는지 자동으로 검사하는 스크립트가 없어서 이번엔 전부 눈으로 봤다. 캐릭터가 더 늘면 같은 방식으로는 못 잡는다. 내 사주보기 챗봇과 추리 결과 저장, 결과 전용 URL도 남아 있다.