2026-06-02·Sanchez

재설계 방향 — 귀여움과 손맛을 기준으로

리빌드의 기준을 딱 하나만 고르라면 "귀엽고, 디자인된 느낌"이었다.
구버전이 호러 톤으로 흘러간 건 무드를 끝까지 정하지 않고 에셋부터 붙였기 때문이다.
이번엔 무드를 먼저 글로 박았다.

모험가 토끼 모카 — 되살리려 한 귀여운 무드

무드를 문장으로 먼저 정한다

무드는 "아늑한 황혼 굴"로 정했다.
포근하고 차분한 저녁녘 동화책.
흙은 따뜻한 밀크초콜릿(#8a5a3c), 안개는 복숭아에서 깊은 앰버로 녹아드는 그라데이션.
온도감의 레퍼런스는 Alto's Adventure와 Monument Valley였다.

문장으로 먼저 적어두면 나중에 판단이 빨라진다.
새 에셋이나 효과를 넣을지 말지 고민될 때 "아늑한 황혼 굴에 어울리나"만 물어보면 되기 때문이다.
구버전에는 이 문장이 없어서, 각 요소가 개별로는 다 그럴듯한데 합치면 방향이 없었다.

"귀여움" 같은 말도 그대로 두면 아무 판단도 못 한다.
그래서 실행 가능한 결정으로 쪼갰다.
머리를 몸통만큼 키운 2등신 비례, 분홍 속귀와 볼터치와 눈 하이라이트 세 가지.
이렇게 적어두면 취향 논쟁이 아니라 확인 가능한 항목이 된다.

색은 한 곳에 모은다

문제는 색을 아무 데서나 즉흥으로 뽑으면 곧장 프로그래머 아트가 된다는 것이다.
그래서 제한 팔레트를 만들고 constants.ts 한 곳에 전부 박았다.
토끼 털, 분홍, 흙, 안개, 앰버 글로우까지 — 컴포넌트 안에 색 리터럴을 쓰는 걸 금지했다.

export const PALETTE = {
  TUNNEL_DIRT: "#8a5a3c", // 따뜻한 밀크초콜릿 흙
  FOG: "#e89b6d",         // 복숭아→앰버 안개
  CRYSTAL: "#ffc46b",     // 앰버 글로우 (블룸 대상)
  RABBIT_FUR: "#fff4e0",
  RABBIT_PINK: "#ff9eb0",
} as const;

색을 몇 개로 제한한 것 자체가 디자인이다.
고를 수 있는 색이 많으면 상황마다 조금씩 다른 색을 쓰게 되고, 그 미세한 불일치가 쌓여 "대충 만든 느낌"이 된다.
팔레트가 좁으면 어디를 봐도 같은 색이 반복되니 저절로 한 덩어리로 읽힌다.

이 규칙은 한참 뒤에 값을 했다.
굴 테마를 세 종류로 늘릴 때, 색이 전부 한곳에 모여 있었던 덕에 팔레트 객체만 바꿔 끼우는 것으로 새 굴이 나왔다.
컴포넌트마다 색 문자열이 흩어져 있었다면 테마 자체를 포기했을 것이다.
당장은 귀찮은 규칙이 나중에 기능이 됐다.

물리 엔진을 뺀다

두 번째 결정은 물리 엔진을 빼는 것이었다.
구버전엔 rapier 의존성이 선언만 돼 있었는데, 이번엔 아예 의존성에서 지웠다.
이 장르에 필요한 건 정확한 강체 시뮬레이션이 아니라 손맛이다.
가속이 어떻게 붙고 점프가 어떤 곡선을 그리는지를 내가 숫자로 직접 쥐고 있어야 한다.
시뮬레이터에 맡기면 오히려 그 통제권을 잃는다.

엔진을 쓰면 원하는 느낌을 만들 때 마찰·반발·질량 같은 간접 손잡이를 돌려가며 역산하게 된다.
직접 짜면 점프 정점을 몇 미터로 할지 정하고 거기서 속도와 중력을 맞추면 끝이다.
원하는 결과에서 값으로 내려가는 길이 훨씬 짧다.

부수 효과도 있었다.
계산이 전부 내 코드 안에 있으니 결과가 완전히 결정적이다.
나중에 매일 모두에게 같은 지형을 주는 데일리 런을 만들 때, 이 결정성이 그대로 전제가 됐다.
엔진의 내부 적분에 결과가 걸려 있었다면 "같은 맵"을 장담하기 어려웠을 것이다.

기준이 서면 그릴 게 분명해진다

세 가지 결정 — 무드를 문장으로, 색을 한 곳으로, 물리를 직접 — 은 전부 같은 이야기다.
나중에 판단할 일을 앞당겨 한 번에 정해두는 것.
구버전에서 방향이 흐트러진 건 매번 그 자리에서 즉흥으로 정했기 때문이었다.

방향이 서니 그릴 게 분명해졌다.
다음 편은 실제로 바뀐 결과를 Before/After로 본다.

다음 편: Before / After →