캐릭터 이미지를 Codex에서 움직이는 펫으로 만들어 봤다. 이미지 생성보다 손이 많이 간 부분은 동작의 의미, 시선 방향, 프레임 사이의 크기를 맞추는 일이었다.

별무늬 보라색 모자와 망토를 두른 작은 마법사 이미지를 Codex 펫으로 만들고 싶었다. 이름은 별이(Byeori)로 정했다.
원본의 금발 단발머리, 갈색 눈, 크림색 옷, 별 지팡이와 부드러운 그림책 느낌을 유지하는 것이 목표였다. 가만히 있는 이미지에 그치지 않고, 대기하거나 작업하는 상황에 맞춰 움직이고 마우스 방향을 바라보는 펫을 만들기로 했다.
제작에는 hatch-pet 스킬과 내장 imagegen을 사용했다. 이미지는 생성 모델이 만들고, 프레임 추출·배치·투명 배경 처리·규격 검사는 Python 스크립트로 진행했다.
이번에 만든 v2 펫의 핵심 파일은 두 개다.
byeori/
├── pet.json
└── spritesheet.webp
pet.json에는 펫의 이름과 설명, 이미지 파일 경로, 스프라이트 버전을 기록한다. 실제로 사용한 내용은 다음과 같다.
{
"id": "byeori",
"displayName": "Byeori",
"description": "별무늬 보라색 모자와 망토를 두른 작은 마법사 별이.",
"spriteVersionNumber": 2,
"spritesheetPath": "spritesheet.webp"
}
spritesheet.webp는 여러 동작의 프레임을 한 이미지 안에 모아 놓은 스프라이트 시트다. 이번 제작에서 사용한 v2 규격은 다음과 같다.
| 항목 | 규격 |
|---|---|
| 프레임 한 칸 | 192 × 208px |
| 전체 배치 | 8열 × 11행 |
| 전체 이미지 | 1536 × 2288px |
| 기본 동작 | 9종 |
| 추가 시선 | 16방향 |
| 이미지 형식 | 투명 배경 WebP |
전체 이미지가 크더라도, 실제 캐릭터 한 자세가 들어가는 공간은 192×208픽셀이다. 이 차이가 나중에 해상도를 이해하는 중요한 단서가 됐다.
먼저 캐릭터의 기준 모습을 정하고, 같은 캐릭터로 다음 동작들을 만들었다.
| 상태 | 표현할 동작 |
|---|---|
idle | 조용히 쉬며 숨 쉬거나 눈 깜빡이기 |
running-right | 오른쪽으로 달리는 이동 동작 |
running-left | 왼쪽으로 달리는 이동 동작 |
waving | 손 흔들기 |
jumping | 점프하기 |
failed | 실패하거나 막혔을 때의 풀이 죽은 반응 |
waiting | 사용자의 도움이나 승인을 기다리기 |
running | 작업 중 생각하거나 집중하는 모습 |
review | 결과를 검토하는 모습 |
여기서 running은 이름과 달리 발로 달리는 동작이 아니다. 작업이 실행 중인 상태를 표현한다. 실제 이동 동작은 running-right, running-left로 구분했다.
첫 결과를 그대로 쓰지는 못했다. idle의 팔이 너무 벌어져 인사하는 모습처럼 보였고, 오른쪽 달리기에서는 얼굴이 반대쪽을 향하는 문제가 있었다. 작업 중 동작에는 몸에서 떨어진 장식이 생기기도 했다.
그래서 팔을 내리고 지팡이를 낮게 든 대기 자세, 코가 오른쪽을 향하는 달리기 자세처럼 화면에서 확인할 수 있는 구체적인 조건으로 수정했다.
기본 동작 다음에는 마우스 방향에 맞춰 바라보는 자세를 만들었다.
시선은 위쪽에서 시작해 시계 방향으로 22.5도씩 나뉜다.
0° : 위
90° : 화면 오른쪽
180° : 아래
270° : 화면 왼쪽
먼저 위·오른쪽·아래·왼쪽의 네 기준 자세를 만든 뒤, 중간 방향을 포함한 8개짜리 묶음 두 개로 확장했다.
눈동자만 움직이면 캐릭터가 계속 정면을 보는 것처럼 느껴질 수 있었다. 별이는 머리와 몸이 구분되는 사람형 캐릭터라서, 눈과 눈꺼풀뿐 아니라 고개와 목, 모자도 함께 움직이도록 했다. 발과 하체는 안정적으로 유지하고, 지팡이는 손에 붙어 있어야 했다.
생성 모델은 방향 지시를 항상 정확하게 따르지 않았다. 마지막 시선 묶음의 한 생성본은 왼쪽 대신 오른쪽을 바라봤다.
이때 단순히 “왼쪽”을 반복하는 것보다 다음처럼 설명하는 편이 검수 기준을 명확하게 만드는 데 도움이 됐다.
수정은 문제가 있는 시선 묶음 전체를 다시 생성하는 방식으로 진행했다. 한 칸만 다른 생성본으로 바꾸면 얼굴이나 몸집이 그 칸에서 갑자기 달라질 수 있기 때문이다.
시선 방향을 수정한 뒤에는 크기 문제가 남았다.
승인된 첫 묶음의 추출 높이는 약 403~414픽셀이었는데, 새 묶음은 440~444픽셀이었다. 같은 축소 비율로 배치하니 모자 끝이 최종 프레임 가장자리에 너무 가까워졌다.
작게 다시 생성한 결과는 약 343~352픽셀로, 이번에는 너무 작았다. 잘리지는 않더라도 시선이 바뀔 때 몸집이 줄어드는 문제가 생길 수 있었다.
결국 방향과 함께 기준 묶음의 크기도 맞춰 다시 생성했고, 최종 배치 검사를 통과했다.
이 과정에서 느낀 점은 개별 이미지가 잘 나오는 것과 애니메이션의 한 프레임으로 잘 맞는 것은 다르다는 것이다.
제작 도중 사용량 제한으로 작업이 멈췄다. 다른 대화에서 기존 작업을 찾아 저장된 이미지와 검수 기록을 확인한 다음 이어서 진행했다.
처음부터 전부 다시 만들 필요는 없었다. 이미 승인된 기본 동작과 첫 시선 묶음을 보존하고, 수정이 필요한 마지막 시선 묶음부터 작업했다.
완료한 단계, 실패한 이유, 선택한 이미지가 파일로 남아 있었기 때문에 가능한 일이었다. 이미지 생성처럼 반복 작업이 많은 경우에도 중간 결과와 검수 기록을 저장하는 것이 중요했다.
검수는 파일 규격 검사와 시각 검수로 나눴다.
최종 WebP는 이 검사를 통과했다. 약 2.7MB이며 무손실 방식으로 저장했다.
“이 칸은 왼쪽”이라는 정답을 보면서 판단하면 잘못된 방향도 맞게 보일 수 있다. 이를 줄이기 위해 방향 표시를 가린 A/B 비교 이미지를 만들고, 세 개의 독립 검수 에이전트가 좌우 또는 상하를 판별하게 했다.
위·아래·왼쪽·오른쪽의 네 기준 방향은 모두 통과했다. 다만 아래쪽에 가까운 135°, 157.5°, 202.5°에서는 좌우 차이가 작아 모호하다는 결과가 나왔다.
이 부분은 방향 순서대로 놓은 이미지와 연속성 검토에서 다시 확인했다. 잘못된 방향으로 돌아가거나 순서가 역전되는 문제는 없어, 미세한 표현 차이에 대한 경고로 남겼다.
최종적으로 기본 동작 9종과 시선 16방향은 검수를 통과했다. 단, 검수 도구가 GIF를 정지 프레임으로 보여주는 한계가 있어, 실제 Codex 앱에서의 애니메이션 재생까지 확인한 것은 아니다.

완성된 미리보기를 보고 가장 먼저 든 질문은 “용량 제한 때문에 화질이 낮아진 걸까?”였다.
이번 파일은 무손실 WebP로 저장했으므로, 용량을 줄이려고 손실 압축을 강하게 적용한 결과는 아니다. 직접적인 이유는 한 프레임이 192×208픽셀이라는 제작 규격에 있다. 공개한 GIF 미리보기도 같은 크기다.
처음에는 이것이 제작 스킬만의 제한인지, 앱 자체의 제약인지 구분할 필요가 있었다. 웹에서 찾아보니 OpenAI Codex 저장소에 관련 기능 요청이 있었다.
Support resolution-independent custom Pet spritesheets — openai/codex #36700
이 이슈는 고정된 프레임 크기로 인해 일러스트 캐릭터의 디테일이 손실된다며, 다양한 해상도와 화면 밀도에 맞춘 표시를 요청한다. 2026년 9월 7일 확인 당시 Open 상태였다. 다만 OpenAI 개발팀이 작성한 공식 규격 문서가 아니라 사용자 기능 요청이라는 점은 구분해야 한다.
실제로 공개된 v2 커스텀 펫 제작 프로젝트에서도 한 칸 192×208, 전체 1536×2288 규격을 사용하고 있다.
현재 확인한 자료는 고정 해상도가 제약이라는 설명을 뒷받침한다. 하지만 더 큰 이미지를 현재 앱에 넣어 동작을 실험한 것은 아니며, 별도의 파일 용량 상한도 확인하지 못했다.
별이의 최종 결과는 다음과 같다.
| 항목 | 결과 |
|---|---|
| 이름 | 별이 / Byeori |
| 스타일 | 부드러운 그림책풍 작은 마법사 |
| 동작 | 기본 9종 + 시선 16방향 |
| 파일 | pet.json, spritesheet.webp |
| 버전 | spriteVersionNumber: 2 |
| 이미지 | 1536×2288, 무손실 WebP, 약 2.7MB |
| 검수 | 규격·투명 배경·방향 검수 통과 |
이번 작업에서는 다음 위치에 두 파일을 함께 설치했다.
~/.codex/pets/byeori/
├── pet.json
└── spritesheet.webp
{
"id": "byeori",
"displayName": "Byeori",
"description": "별무늬 보라색 모자와 망토를 두른 작은 마법사 별이.",
"spriteVersionNumber": 2,
"spritesheetPath": "spritesheet.webp"
}

캐릭터 이미지를 펫으로 바꾸는 작업은 예상보다 세밀한 조정이 필요했다. 원본의 분위기를 유지하면서 각 동작의 의미를 살리고, 시선이 바뀔 때 크기나 위치가 튀지 않게 해야 했다.
특히 다음 세 가지가 중요했다.
작은 마법사 하나를 만드는 과정이었지만, 생성형 이미지와 정해진 프로그램 규격을 연결할 때 어떤 검증이 필요한지 경험할 수 있었다.
첨부 캐릭터로 Codex v2 펫을 만들어줘.
[목표]
- 원본의 얼굴, 색상, 의상, 소품을 유지한다.
- 기본 동작 9종과 시선 16방향을 완성한다.
- 검수 후 설치하고 ZIP과 미리보기를 제공한다.
[작업 방식]
- 시작 전에 기존 파일과 완료 기록을 확인하고 재사용한다.
- 생성 전에 필요한 규격과 도구의 입력 제한을 확인한다.
- 긴 공통 지침을 매번 반복하지 말고, 기준 이미지와
해당 동작에 필요한 짧은 지시를 사용한다.
- 중간 결과와 실패 이유를 저장해 중단 후 이어갈 수 있게 한다.
[정확도]
- 좌우는 보는 사람의 화면 기준이다.
- 시선은 코, 눈, 고개 방향으로 확인한다.
- 모든 시선 프레임의 몸 크기와 발 위치를 일정하게 유지한다.
- 최종 표시 크기에서 검수한다.
- 검수는 필요한 단계에서 한 번씩 수행하고,
수정된 부분만 다시 검사한다.
[재시도와 비용]
- 같은 원인으로 두 번 실패하면 같은 요청을 반복하지 말고
원인과 접근 방식을 바꾼다.
- 기본 방향 오류, 잘림, 뚜렷한 크기 변화는 수정한다.
- 미세한 대각선 차이는 전체 움직임이 자연스러우면 허용한다.
- 진행 보고는 단계 완료, 실패 원인, 중요한 변경 위주로 짧게 한다.
- 불필요한 추가 버전과 요청하지 않은 산출물은 만들지 않는다.