제이월드 팀이 찌올림의 도감 물고기 180마리를 부품 조합과 코드로 만들고 그리는 방법. 실제 수치, 겹치지 않게 하는 규칙, 이를 지키는 테스트까지 정리했어요.
찌올림의 도감에는 물고기가 180마리 있어요. 마리마다 생김새와 이름, 크기 범위, 릴 싸움의 당김 패턴이 달라요. 180마리를 일일이 그리면 시간이 오래 걸려요. 게임 용량 목표도 2.5MB 이하였어요. 그래서 제이월드 팀은 다른 길을 택했어요. 물고기 그림 파일이 아예 없고, 모든 물고기를 코드가 부품으로 그려요.
이 글은 게임의 실제 소스를 바탕으로 정리한 개발 노트예요. 부품 구성, 생성기, 비슷한 물고기가 나오지 않게 하는 규칙, 그리기를 가볍게 만든 방법을 차례로 볼게요.

부품 상자
물고기는 그림이 아니에요. 선택지를 적어 놓은 작은 기록이고, 그리기 코드는 그 기록을 읽어요. 그리기 코드가 아는 부품은 이렇게 있어요.
| 부품 | 종류 | 바뀌는 것 |
|---|---|---|
| 몸 | 12 | 날씬, 동글, 넓적, 납작, 쏜살, 길쭉(뱀장어형), 네모, 가시등, 큰머리, 뾰족주둥이, 초승달, 통통 |
| 꼬리 | 5 | 부채, 갈래, 초승달, 리본, 둥근 꼬리 |
| 지느러미 | 4세트 | 작은 것, 돛, 긴 것, 이중 |
| 무늬 | 8 | 민무늬, 줄무늬, 점, 띠, 비늘, 배 그러데이션, 안장, 깨알 |
| 색 팔레트 | 16 | 한 팔레트에 세 가지 색(몸, 무늬, 포인트) |
| 장신구 | 10 | 전설 등급만: 왕관, 수염, 빛무리, 조개껍데기, 뿔, 리본, 등불, 금별, 후광 등 |
몸도 저장된 이미지가 아니라 수식이에요. 12가지 몸은 저마다 숫자 7개로 이루어져 있어요. 깊이, 가장 두꺼운 위치, 둥근 정도, 위아래 배율, 꼬리 쪽 폭, 길이 비율이에요. 코드는 몸을 따라 28개 지점에서 윤곽을 찍고, 위쪽을 따라갔다가 아래쪽으로 돌아와 도형을 닫아요. 숫자 하나만 바꿔도 날씬한 물고기가 통통해져요. 꼬리와 지느러미도 비슷한 방식으로 그려요.
그 위에 모든 물고기에 똑같이 들어가는 마무리가 있어요. 2px 짙은 윤곽선 한 줄, 등에 흰 하이라이트 한 줄, 크고 동그란 눈이에요. 이 요소를 공유하니까 이상한 부품 조합이 나와도 찌올림 물고기처럼 보여요.
생성기: 씨앗 하나로 레시피 180개
레시피는 플레이 중에 뽑지 않아요. 빌드할 때 시드 생성기(시드는 fishing-v1이라는 글자)가 돌아가서 species.json을 써요. 게임은 이 파일만 읽어요. 장점이 둘 있어요. 모든 플레이어가 같은 도감을 보고, 업데이트해도 물고기 모습이 바뀌지 않아요.
한 종의 기록에는 연못, 등급, 부품 선택, 크기 범위, 이름 부품, 좋아하는 시간대와 자리, 당김 패턴이 들어 있어요. 연못별 등급별 마릿수는 설계로 정해 놓았어요.
| 등급 (게임 표기) | 마릿수 |
|---|---|
| 흔함 | 61 |
| 보통 | 52 |
| 희귀 | 37 |
| 영웅 | 20 |
| 전설 | 10 |
합치면 180마리, 6개 연못에 30마리씩이에요. 첫 번째 연못인 아침 연못에는 흔함 14, 보통 10, 희귀 6마리뿐이고 그 위 등급은 없어요. 마지막인 남해 섬은 흔함 6, 보통 7, 희귀 6, 영웅 6, 전설 5마리예요. 그래서 가장 귀한 물고기는 뒤쪽 물가에 모여 있어요.
생성기는 제약이 큰 등급부터 채워요. 전설, 영웅, 희귀 순이에요. 새 물고기 하나마다 무작위 부품 조합을 시도해서 규칙을 어기는 건 버리고, 통과한 후보 최대 48개 중 가장 좋은 것을 골라요. "가장 좋다"는 기준은 두 가지예요. 같은 연못의 이웃과 몸, 무늬, 색 계열이 모두 다를수록 좋고, 아직 덜 쓴 부품을 쓸수록 좋아요. 그래서 특정 몸이나 색이 도감에 몰리지 않아요. 레이아웃을 끝내지 못하면 다음 시도 번호로 처음부터 다시 해요. 최대 50번까지 해요.
"다르다"의 기준
물고기가 180마리면 무작위로는 비슷한 얼굴이 나와요. 생성기는 규칙 세 가지로 막아요.
| 규칙 | 적용 범위 |
|---|---|
| 어떤 두 마리든 3가지 중 2가지 이상 달라야 해요: 몸, 무늬, 색 계열 | 한 연못 안(도감 한 페이지 30마리) |
| 어떤 두 마리든 4가지 중 2가지 이상 달라야 해요: 몸, 무늬, 색 계열, 꼬리 | 전체 180마리 |
| 몸 + 무늬 + 팔레트가 완전히 같은 두 마리는 없어요 | 전체 180마리 |
색 계열은 8묶음(분홍빨강, 주황, 호박, 노랑, 초록, 청록, 파랑, 보라)이고 묶음마다 팔레트가 둘씩 있어요. 그래서 "초록이 살짝 다른 두 마리"는 다른 물고기로 치지 않아요.
처음에는 "180마리 모든 쌍이 3가지 중 2가지 이상 다르다"는 가장 강한 규칙을 원했어요. 그런데 불가능하다는 걸 알게 됐어요. 몸 12, 무늬 8, 색 계열 8로 만든 코드는 모든 쌍이 두 군데 이상 다르려면 최대 8 × 8 = 64개까지만 담을 수 있어요. 그래서 설계 문서를 고쳤어요. 한 연못 안은 엄격하게, 도감 전체는 꼬리까지 넣은 느슨한 4가지 규칙으로 갔어요. 한계도 솔직하게 적어 둘게요. 다른 연못의 두 마리가 몸과 무늬는 같아도 색 계열과 꼬리가 다르면 통과해요.
등급 규칙도 있어서 희귀도를 한눈에 알 수 있어요.
- 흔함은 민무늬, 줄무늬, 점무늬만 써요.
- 희귀, 영웅, 전설은 민무늬가 없어요.
- 영웅은 늘 돛이나 긴 지느러미 세트를 가져요.
- 전설 10마리는 마리마다 다른 장신구를 하나씩 달아요. 겹치는 건 없어요.
이름도 같은 방식이에요
이름도 부품으로 만들어요. 접두어(24가지)와 명사(12가지, 몸 하나에 하나)를 붙여요. 접두어는 색, 피부 무늬, 장소 단어예요. 한국어 이름은 "-몽"으로 끝나서 풀빛 통통몽, 분홍 날씬몽 같은 모양이에요. 생성기는 물고기의 색이나 무늬에 맞는 접두어를 먼저 고르고, 그 조합이 이미 쓰였을 때만 장소나 분위기 단어로 넘어가요. 명사는 몸에 맞춰서 "길쭉몽"이라면 늘 뱀장어처럼 긴 물고기예요. 이름은 지어낸 "주머니 물고기"일 뿐이고, 실제 어종을 말하지 않아요.

그리기: 함수 하나로 어떤 크기든
모든 화면은 drawFish 함수 하나로 물고기를 그려요. 레시피, 위치, 가로 픽셀을 받아서 꼬리까지 포함한 물고기 전체를 그 너비와 높이 0.75배의 상자에 맞춰 넣어요. 작은 도감 칸과 큰 포획 카드가 같은 코드를 써요. 어느 종이든 화면에서는 같은 크기로 보이고, cm 크기는 숫자만 바꿔요.
가볍고 또렷하게 만든 장치가 몇 가지 있어요.
- 범위는 한 번만 재요. 캔버스 대신 기록만 하는 대역이 그리기를 그려 보지 않고 모든 점의 범위만 적어 둬요. 결과는 몸, 꼬리, 지느러미, 장신구 조합별로 캐시해요.
- 작은 크기에서는 피부를 단순하게 해요. 56px 아래에서는 비늘과 깨알 같은 잔무늬를 한 가지 색 톤으로 바꿔요. 안 그러면 노이즈로 보여요.
- 점은 종 id로 시드해요. 점박이 물고기의 점 위치는 id를 시드로 한 작은 난수로 정해요. 도감을 몇 번을 열어도 같은 물고기는 같은 점이에요.
- 잠긴 칸도 같은 그림이에요. 아직 못 만난 물고기는 실루엣 모드로 그려요. 채우기와 윤곽선을 옅은 어두운 색으로 바꾸고 디테일을 빼요. 모양은 보이니까 어느 연못에 있을지 짐작할 수 있어요.
- 효과는 옵션이에요. 전설의 빛무리, 밤 물가의 테두리, 폭발 당김 경고의 밝아짐은 같은 함수의 옵션이에요.
180마리를 지키는 테스트
도감 전체가 데이터라서 테스트로 검사할 수 있어요. 저장소의 종 테스트는 이런 걸 확인해요.
- 시드로 전부 다시 생성해서 저장된
species.json과 비교해요. 생성기나 파일 중 한쪽만 바뀌면 실패해요. - id가 정확히 180개인지, 연못마다 등급별 마릿수가 맞는지 봐요.
- 모든 쌍, 즉 16,110쌍을 "다름" 규칙에 비교해요.
- 등급 규칙과 "장신구는 전설만, 모두 다르게"를 확인해요.
- 모든 몸, 꼬리, 지느러미, 무늬, 팔레트가 한 번 이상 쓰였는지, 크기 범위가 등급 범위 안에 있는지 확인해요.
핵심 로직이 난수나 시계 함수를 부르지 않는지 확인하는 검사도 따로 있어요. 같은 시드는 언제나 같은 결과를 내요.
플레이어에게는 어떤 의미일까요
뒤에서는 계산이 많지만 화면에서는 약속이 하나예요. 도감의 칸마다 다른 물고기이고, 귀한 물고기일수록 더 특별해 보인다는 거예요. 도감을 채우는 중이라면 이렇게 읽어 보세요.
- 잠긴 칸의 실루엣은 진짜 모양이에요. 어느 연못 물고기인지 짐작하는 데 써요.
- 장신구가 있는 물고기는 전설뿐이에요. 왕관, 후광, 등불이 보이면 전설을 만난 거예요.
- 크기에 따라 칸마다 별을 최대 3개까지 얻어요. 한 번 잡았다고 그 칸이 끝난 건 아니에요.
도감은 찌올림에서 직접 확인해 보세요. 릴 싸움과 장비 순서는 앞선 릴 가이드 글에서 볼 수 있어요.
정리
- 물고기는 전부 코드가 부품으로 그려요: 몸 12, 꼬리 5, 지느러미 4세트, 무늬 8, 팔레트 16, 전설 장신구 10.
- 시드 생성기(
fishing-v1)가 빌드할 때 레시피 180개를 쓰고, 플레이 중에는 물고기 모습에 무작위가 없어요. - 규칙으로 서로 다르게 만들어요: 한 연못 안은 3가지 중 2가지, 도감 전체는 4가지 중 2가지, 몸 + 무늬 + 팔레트 중복 금지.
- 이 부품으로는 180마리 모든 쌍에 엄격한 규칙을 적용하는 것이 수학적으로 불가능해서(64개 한계) 규칙을 둘로 나눴어요.
- 그리기 함수 하나가 모든 크기를 맡고, 작은 칸에서는 잔무늬를 단순화하고, 잠긴 물고기는 실루엣으로 그려요.
- 테스트가 16,110쌍을 모두 검사해서, 새 물고기가 슬쩍 쌍둥이가 되는 일은 없어요.
이 글은 제이월드 팀이 게임 설계 문서와 실제 플레이 수치를 바탕으로 썼고, 글을 다듬을 때 AI 도구를 함께 썼어요.