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

오늘 한 일

  • v1.3.0 준비 — 별점 요청, 클라우드 저장 안내 시점 조정
  • 게임 화면 버벅임을 재서 고침 (한 프레임 30.5 → 20.6ms)
  • 다시하기가 계측에서 빠지던 문제 수정

막힌 부분

별점은 직접 못 받는다 — 스토어 카드를 부르는 게 전부다

앱 안에 별점 요청(인앱 리뷰)을 넣으려다 알았다. 앱이 자기 화면으로 별점을 받는 건 안 된다. 스토어가 자기 별점 카드를 대신 띄우고 점수도 스토어가 가져가기 때문에, 앱은 그 카드가 떴는지도 몇 점이 매겨졌는지도 알 수 없다. 부르는 횟수도 스토어가 제한해서, 불러도 조용히 아무것도 안 뜰 수 있다.

게다가 “재밌으셨나요?”로 먼저 걸러 좋다는 사람만 별점 카드로 보내는 것은 정책 위반이다.

그래서 앱이 할 수 있는 건 하나뿐이었다 — 좋은 순간에, 조건 없이, 스토어 카드를 한 번 부른다.

  • 제약이 셋이면(화면 못 만듦·결과 못 봄·선별 금지) 설계가 하나로 정해진다. 고를 게 없으면 고민할 것도 없다
  • 불러도 안 뜰 수 있으니 설정에 언제든 리뷰를 쓸 수 있는 통로를 따로 뒀다. 막힐 수 있는 길이 유일하면 안 되니까

물어볼 시점은 도달 분포가 정했다

처음엔 50탄으로 잡았다. 충분히 해 본 사람에게 묻는 게 맞아 보였다.

그런데 어제 본 도달 분포가 29·38·150이었다. 50탄 기준이면 셋 중 하나에게만 묻는다. 30탄이면 둘이고 곧 셋이다.

  • 리뷰는 물어볼 수 있는 사람 수가 기준을 정한다. “충분히 해 본 사람”은 그다음 조건이다
  • 어제 데이터를 안 봤으면 50으로 냈을 것이다

재는 도구가 앱을 못 보고 있었다

버벅인다는 이야기가 있어 프레임을 쟀다. 30초를 플레이했는데 25프레임으로 나왔다. 초당 한 장이라는 소리라 말이 안 된다.

원인은 도구였다. 이 게임은 화면에 직접 그려서 안드로이드 기본 렌더러를 거치지 않는데, 쓰던 도구는 그 렌더러만 본다.

그럼 앞서 몇천 프레임이 잡힌 건 뭐였나. 하단 배너가 떠 있을 때만 화면 합성 방식이 바뀌어 집계됐던 것이다. 배너가 떴냐 안 떴냐에 따라 재는 대상 자체가 달랐다.

앞서 잰 것을 전부 버리고, 앱이 직접 알려주는 프레임 시간을 쓰기로 했다.

  • 숫자가 상식과 어긋나면 대상이 아니라 도구를 의심한다
  • 도구가 무엇을 보고 무엇을 못 보는지 모르면 그 숫자로 판단하면 안 된다

프레임 수를 줄였더니 더 끊겼다

120Hz 화면이라 초당 120번 다시 그리고 있었다. 모래 게임에 그만큼 필요 없으니 60번으로 걸렀다.

평균은 좋아졌는데 튀는 프레임이 더 나빠졌다. 상위 10%가 28ms에서 48ms가 됐고, 화면은 뚝뚝 끊겨 보였다.

일을 절반으로 나눈 게 아니라, 안 하는 프레임과 두 배로 몰아서 하는 프레임으로 갈라놓은 것이었다.

  • 되돌렸다. 횟수를 줄이는 건 값을 옮기는 것이지 없애는 게 아니다
  • 한 프레임에 30ms가 들면 초당 몇 번을 그리든 매끄러울 수 없다

다른 판끼리 비교하고 결론 낼 뻔했다

고친 것과 안 고친 것을 나란히 쟀다. 새 방식이 이겼다.

그런데 두 번의 플레이가 서로 다른 판이었다. 하나는 어려움, 하나는 보통이었다. 판마다 통과 색의 개수가 달라 비용이 다르다.

지나간 판을 다시 할 수 있게 열고, 같은 74탄으로 다시 쟀다. 그제야 비교가 됐다.

  • 조건이 다른 둘을 비교하면 숫자가 아무리 예뻐도 아무 말도 안 하는 것이다
  • 조건이 다른 걸 놓쳤으면 그대로 기록에 남길 뻔했다

캔버스를 미리 구워 두고 잘라 붙였다

그림 영역을 칸마다 하나씩 그리고 있었다. 64×64니까 프레임마다 4096번이다.

완성된 그림은 판이 끝날 때까지 안 변한다. 변하는 건 어디까지 찼나뿐이다. 그리고 한 열의 채움은 바닥부터 연속이라, 한 열이 “안 찬 위 한 덩어리 + 찬 아래 한 덩어리”로 끝난다.

그래서 판에 들어올 때 완성본을 한 장 만들어 두고, 프레임마다 열별로 잘라 붙이게 바꿨다. 4096번이 130번쯤이 됐다.

한 프레임이 30.5 → 20.6ms가 됐다.

  • 변하지 않는 것을 매번 다시 만들고 있지 않은지 본다
  • 데이터의 구조가 방법을 정해 준다. 열이 연속이라는 사실이 없었으면 이 방법이 안 나온다

배너 하나가 8ms였다

남은 값을 더 찾으려고 배너를 꺼 봤다. 20.6ms가 10~15ms로 떨어졌다.

배너는 앱이 아니라 시스템이 그리는 화면이라, 그게 떠 있으면 게임 화면을 한 번 더 베껴야 한다. 그 값이 매 프레임 든다.

오늘 하루 종일 캔버스를 뜯어고쳐 번 것이 10ms인데, 배너 하나가 8ms를 먹고 있었다.

  • 남기기로 했다. 광고 수익과 부드러움을 저울에 올리는 문제고, 기술로 정할 것이 아니다
  • 큰 값이 예상 밖에 있을 수 있다. 고칠 곳부터 정하고 재면 그걸 못 본다

다음 최적화는 할 게 없었다

안 변하는 부분은 다시 안 만들게 하자는 안이 있었다. 손대기 전에 대상을 세어 봤다.

캔버스도, 아이템 바도, 튜토리얼 표시도 매 프레임 값에 의존했다. 상단 표시줄까지 그랬다 — 벨트가 꽉 찼는지에 따라 버튼이 생겼다 없어진다.

프레임과 무관한 건 배너뿐인데 그건 이미 다시 안 만들고 있었다.

  • 접었다. 다 구독해야 하면 지금과 같은 범위가 다시 만들어진다
  • 세어 보기 전에 “저긴 안 변할 것”이라고 말한 게 오늘 두 번째 헛짚음이다

다음에 할 일

  • v1.3.0 내부 테스트에 올리고 확인 뒤 승격
  • 남은 그리기 비용이 어디서 나는지 하나씩 꺼보며 재기
  • 100탄씩 추가 배포 — 다음 주 착수
  • 며칠 뒤 레벨별 도달 분포 확인
  • 클라우드 저장 연동률 확인
  • 크래시·ANR, 광고 노출 수 확인
  • 도안 추가 검토
  • 광고 제거 상품 — 리텐션 보고 판단

Series: Sandrop

1 모래게임 Sandrop 0 2 모래게임 Sandrop 1 3 모래게임 Sandrop 2 4 모래게임 Sandrop 3 5 모래게임 Sandrop 4 6 모래게임 Sandrop 5 7 모래게임 Sandrop 6 8 모래게임 Sandrop 7 9 모래게임 Sandrop 8 10 모래게임 Sandrop 9 11 모래게임 Sandrop 10 12 모래게임 Sandrop 11 13 모래게임 Sandrop 12 14 모래게임 Sandrop 13 15 모래게임 Sandrop 14 16 모래게임 Sandrop 15 17 모래게임 Sandrop 16 18 모래게임 Sandrop 17 19 모래게임 Sandrop 18 20 모래게임 Sandrop 19 21 모래게임 Sandrop 20 22 모래게임 Sandrop 21 23 모래게임 Sandrop 22 24 모래게임 Sandrop 23 25 모래게임 Sandrop 24 26 모래게임 Sandrop 25 27 모래게임 Sandrop 26 28 모래게임 Sandrop 27 29 모래게임 Sandrop 28 30 모래게임 Sandrop 29 31 모래게임 Sandrop 30 32 모래게임 Sandrop 31 33 모래게임 Sandrop 32 34 모래게임 Sandrop 33 35 모래게임 Sandrop 34 36 모래게임 Sandrop 35 37 모래게임 Sandrop 36 38 모래게임 Sandrop 37 읽는 중

Suggested Posts