이 글은 Sandrop 시리즈의 6번째 기록입니다. (총 23개)

오늘 한 일

  • 도안 풀을 66종 → 236종으로 늘리고 소프트런칭 분량인 200레벨을 무반복으로 생성
    • 이유: 내가 보통 이런 게임을 기본 400레벨 이상을 클리어하기 때문에 50레벨은 너무 부족하다. 그래서 일단 200레벨정도를 테스트용으로 쓰기 위한 제작이 필요했고, 그 200개가 전부 다른 그림이려면 도안이 그만큼 필요했다
    • 티어 분포에 맞춰 도안을 나눠 담는 기준을 “고정 비율”에서 “티어별 수요 비례”로 바꿈
      • 이유: 고정 비율로는 200레벨에서 normal 난이도 수요(약 140개)가 배정 칸을 넘겨 같은 그림이 반복됐다. 실제로 몇 레벨을 뽑는지에 맞춰 칸을 나눠야 무반복이 유지된다
  • 기믹 2종 도입 — 로프(51레벨~)·물음표(101레벨~). 규칙 엔진(Dart·Python 양쪽)·화면·레벨 자동 배치까지 한 번에
    • 로프: 두 바스켓이 밧줄로 묶여 같이 움직인다. 레일에 2칸 이상 비면 둘 다, 1칸만 비면 밧줄을 풀고 탭한 것만 올린다
    • 물음표: 색을 가려둔 바스켓. 꺼낼 수 있게 되는 순간 색이 공개된다
    • 이유: 후반부에 난이도와 변화를 줄 장치가 필요했다. 51·101처럼 딱 떨어지는 지점에서 처음 하나만 단독으로 소개한 뒤 서서히 밀도를 올린다
  • 로프 규칙을 플레이 중 발견한 상황에 맞게 개정
    • 이유: 직접 해보니 A·B가 묶였는데 B의 길을 A가 막고 있으면, A만 치우면 B가 나올 수 있는데도 “둘 다 지금 꺼낼 수 있어야 함” 조건 때문에 탭이 거부돼 막힌 것처럼 굳었다. “탭한 게 먼저 나가면 짝이 풀리는 경우”도 탭을 허용하도록 고침 (판정 구현은 TIL 4)
  • 벽을 트레이 바탕과 같은 밝은 갈색으로 바꿈
    • 이유: 남편에게 플레이시켰더니 벽을 보고 “이게 뭐냐”고 물었다. 산 아이콘이 붙은 회색 블록이라 무슨 칸인지 안 읽혔다. “아직 파지 않은 땅”처럼 보이게 하니 못 지나가는 게 자연스러워졌다
  • 데드락(막힘)으로 끝날 때 화면 전체를 슬로우모션으로 서서히 멈춘 뒤 모달을 띄우게 함
    • 이유: 막히자마자 모달이 뜨면 “왜 막혔는지”를 볼 틈이 없었다. 1.1초에 걸쳐 벨트·모래가 같이 느려지다 멎으면 상황이 눈에 들어온다
  • 도안 양자화에서 연한 전경색이 배경에 묻히던 문제 수정 (사탕 포장재·눈사람 몸통 등)
    • 이유: 배경을 주조색의 옅은 틴트로 까는데, 흰색에 가까운 전경색이 그 틴트와 거의 같아 그림이 안 보였다. 배경과 충분히 대비될 때까지 전경색을 어둡게 당기게 함
  • 바스켓을 양동이 스프라이트로 교체
    • 밝은 크림색 원본 한 장에 모래색을 곱해 착색하는 방식 — 레벨마다 다른 색·이모지 전용 팔레트를 전부 커버한다 (구현은 TIL 5)
    • 양동이를 키우고 아래에 받침 자리를 깔아 어느 칸인지 또렷하게. 받침 바닥은 통로(빈칸)와 같은 파낸 굴 톤으로 통일
    • 잔량을 % 숫자 대신 개구부 안의 모래(원반+하이라이트+그레인)로. 벨트에서는 %를 남기되 “그 양동이가 처음 담은 양 = 100%” 기준으로, 보드에서는 % 숨김
    • 내보낼 수 있는 칸은 양동이 대신 바닥이 빛나게 (보드에선 바닥 타일이 신호)
    • 부을 수 있는 벨트 양동이는 상하로 뒤집혀 쏟는 연출 (라벨은 항상 정립), 오른쪽 대기 칩의 모래도 원형 채움으로
    • 바스켓이 통로를 걸어 나갈 때 짧은 잔상(트레일)
  • 물음표 공개 시점을 “선택 가능해지는 순간” → “보드를 떠나 엘리베이터에 오르는 순간”으로 변경
    • 이유: 물음표가 시작 시 선택 가능한 자리에 있으면 렌더 첫 프레임에 공개돼, 데뷔 레벨(101) 안내 배너는 뜨는데 정작 ?가 안 보였다. 보드에 있는 동안은 걸어 나가는 중에도 ?를 유지하도록
    • 규칙을 바꾸니 딸려온 버그: 보드 렌더가 옛 규칙(공개 전엔 조작 불가) 기준이라 미공개 ?가 항상 비활성이었다 — 길이 열려도 탭이 안 됨. 공개/미공개 분기를 합쳐 해결
  • 앱 아이콘 생성 — 도안(고래) 소스로 안드로이드 adaptive 아이콘 전 밀도 (flutter_launcher_icons)

막힌 부분

  • 로프가 데드락처럼 굳는 케이스 — 묶인 짝(B)의 유일한 걸림돌이 탭한 바스켓(A) 자신일 때, “둘 다 지금 꺼낼 수 있어야 함” 조건이 정당한 수를 막았다.
    • 해결: A가 빠지면 B가 꺼낼 수 있게 되는지 가정해서 확인하고, 그러면 탭을 허용하도록(A 먼저 나가고 B가 따라 나감) 규칙을 넓혔다 (구현은 TIL 4)
  • 두 언어 엔진이 조용히 어긋나 있던 버그 — 빈 레일 슬롯을 채우는 방향이 Dart는 오른쪽부터, Python은 왼쪽부터였다.
    • 원인: 붓기가 “왼쪽 슬롯부터” 소진되는 규칙과 겹치면서, 같은 색 통이 여러 개일 때 소진 순서가 두 엔진에서 갈렸다. 레벨 99·200에서야 봇 궤적이 어긋나며 드러남
    • 해결: Python을 Dart에 맞춰 오른쪽부터로 통일하고, 이 방향을 규칙 문서에 파리티 필수 항목으로 못 박음
  • 200레벨 무반복이 도안 배정에서 깨짐 — 티어 칸을 고정 비율로 나눠서.
    • 해결: 실제 레벨 수요에 비례해 칸 경계를 잡도록 바꿈

시도했다 되돌린 방향: 보드를 2.5D로 돌출(벽은 윗면+앞면 블록, 통로는 움푹, 바스켓은 받침 위)시켜 봤지만 과하고 산만해서 되돌렸다. 벽 시인성은 결국 바탕색 하나로 해결.

스프라이트 교체의 파장: 양동이 그림을 넣자 예전에 쓰던 사각 타일이 사라져 맵이 허전해졌다. 그림 한 장 바꾸면 바닥·강조·라벨 위치까지 딸려 손봐야 한다 — 받침 자리·바닥 글로우·라벨 정책 재조정이 전부 이 여파.


다음에 할 일

  • UX 개선 — 실기기에서 양동이 크기·바닥 글로우·거꾸로 붓기·트레일 체감 다듬기
  • 물음표 공개 흐름·기믹 온보딩 배너 점검, 새 도안 200종 시인성 확인
  • 잠금·frozen basket 기믹(v1.1, 201레벨~ — frozen은 색도 얼었다 이웃 이탈로 깨질 때 공개)

Series: Sandrop


Suggested Posts