Communitygithub.com

wlr2/toon-reel

9:16 (1080x1920, 30fps) 세로형 만화 스토리 릴을 제작합니다. Reels/TikTok/Shorts용, toon-reel-engine 기반: 스크립트, 에피소드 파일, Skia 툰 룩, 3레이어 조명, 카메라 연출, 연기, 필수 프레임 체크, 사운드, 믹싱, 최종 내보내기까지 모든 과정을 포함합니다. 누군가 새로운 릴, 에피소드, 짧은 스토리 영상, 전설 다시 말하기, 또는 이 엔진으로 애니메이션 단편을 요청하거나, 조명, 연출, 체크, 렌더링, 마무리를 요청할 때 사용하세요.

toon-reel란 무엇인가요?

이 스킬은 사용자가 빠르게 세로형(9:16, 1080x1920, 30fps) 만화 스토리 릴을 제작할 수 있도록 toon-reel-engine을 활용하는 완전한 파이프라인을 제공합니다. 스크립트 작성부터 최종 내보내기까지 모든 단계를 코드 기반으로 처리합니다. 캐릭터, 세트, 조명, 카메라는 모두 Python 코드로 정의되며, 모든 프레임은 시간 T의 순수 함수로 표현됩니다. 타임라인 에디터나 키프레임 UI가 없으며, 사용자는 데이터(키, 샷 테이블)를 작성하고 프레임을 확인하는 방식으로 작업합니다. 주요 단계는 스크립트 → 타임라인 → 캐스트 시트 + 세트 프레임 → 블로킹 → 체크(2회) → 프리뷰 → 마스터 → 사운드 → 마무리 → 포스트 순서로 진행되며, 각 단계마다 검증 절차가 포함되어 있습니다. 이 엔진은 Claude Code, Cursor, Codex와 같은 AI 에이전트와 함께 사용하도록 설계되었으며, 사용자와 AI가 협력하여 릴을 제작할 수 있습니다. 모든 에피소드는 `episodes/starter/toon` 템플릿을 복사하여 시작하며, `reel.py`, `build_tl.py`, `finalize.py`는 기본적으로 재사용 가능하고 `script.py`, `looks.py`, `scenes.py` 등 사용자 정의 파일을 교체합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/wlr2/toon-reel-engine/tree/HEAD/skills/toon-reel

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

툰 릴 (Toon reel)

당신은 toon-reel-engine으로 짧은 애니메이션 스토리를 연출하고 제작합니다. 모든 것은 Python입니다: 캐릭터, 세트, 조명, 카메라는 코드로, 모든 프레임은 시간 T의 순수 함수입니다. 타임라인 에디터나 키프레임 UI는 없습니다. 데이터(키, 샷 테이블)를 작성한 다음 프레임을 확인합니다.

엔진의 레이아웃 (유지하세요: 상대 임포트가 이것에 의존합니다):

tools/toon/            엔진: toon.py (렌더러), rig.py (캐릭터), anim.py (타이밍), cast/ props/ sets/ (키트)
tools/                 sound.py (큐에서 스템 생성), mix_check.py (음성 명료도), finish.py (-14 LUFS 내보내기),
                       thumb.py (커버), find_phrases.py (내레이션 테이크의 구절 시간)
episodes/starter/toon  템플릿: "The Lamp", 12.5초, 4개 샷, 방 1개, 1명. 이것을 복사하여 시작하세요.
episodes/window/toon   전체 예제: "The Man at the Window", 50초, 13개 샷, 두 세계와 반전.
episodes/jeff, episodes/smilingman   전체 예제와 키트가 임포트하는 지원 모듈 (실행 가능한 에피소드는 아님)

명령어. 아래 python은 requirements.txt가 설치된 인터프리터를 의미합니다 (Windows에서는 py). 에피소드 자체 스크립트(reel.py, build_tl.py, finalize.py)는 에피소드 폴더 episodes/<name>/toon에서 실행됩니다. 도구는 프로젝트 루트에서 실행합니다: python tools/sound.py episodes/<name>/toon.

첫 번째: 엔진 찾기 또는 설정

플러그인의 설치 폴더 내부가 아닌, 사용자 자신의 프로젝트 폴더에서 작업하세요 (업데이트 시 교체됨).

  1. 작업 폴더에 이미 tools/toon/toon.py가 있으면 사용하세요.
  2. 그렇지 않으면 엔진이 이 스킬과 함께 제공됩니다. 그 루트는 이 스킬의 기본 디렉토리보다 두 폴더 위에 있습니다 (<skill dir>/../..: tools/, episodes/, requirements.txt 및 .gitignore를 포함합니다). 그 네 개를 작업 폴더에 복사하고 레이아웃을 유지한 후, 사용자에게 알리세요. 해당 폴더에 tools/가 없으면 (스킬이 단독으로 복사된 경우) 대신 https://github.com/wlr2/toon-reel-engine을 클론하세요.
  3. pip install -r requirements.txt를 실행하고 ffmpeg -version이 작동하는지 확인하세요 (5.1 이상). 자막은 Arial Black이 필요하거나, TOON_FONT를 두꺼운 산세리프 .ttf로 설정하세요.
  4. 무엇이든 만들기 전에 설정을 증명하세요. episodes/starter/toon에서: python build_tl.py, 그런 다음 python reel.py --frame 5.0을 실행하면 review/_f5.00.png가 생성되어야 합니다.

순서는 고정됨

스크립트 -> 타임라인 -> 캐스트 시트 + 세트 프레임 -> 블로킹 -> 체크 (2회) -> 프리뷰 -> 마스터 -> 사운드 -> 마무리 -> 포스트.

마스터 렌더는 체크를 통과하고 기록되기 전에 절대 시작되지 않습니다. 애니메이션을 시작하기 전에 사용자에게 캐릭터 시트와 세트 프레임 하나를 보여주고, 풀 해상도 프레뷰 전에 레이블이 지정된 키프레임 시트를 보여주세요. 무엇이든 돈을 쓰기 전에 (유료 TTS, 유료 SFX, 클라우드 렌더) 물어보세요.

1. 스크립트 (references/script.md)

10단계 방법: 가장 구체적인 모순으로 시작, 하나의 주요 질문, 결과의 연쇄, 몇 초마다 변화, 말하기 및 애니메이션을 위해 작성, 움직이는 중간, 마지막 시그니처 대사로 얻은 결말, 정직한 프레이밍 (크리피파스타의 경우 "AN INTERNET HORROR STORY"), 시간이 지정된 샷 테이블, 그 다음 보존 편집. 사용자가 스크립트나 비트 시트를 건네주면, 그들의 단어와 그들의 사양이 여기의 하우스 룰보다 우선합니다: 그들의 대사를 다시 쓰지 말고, 변경 사항을 제안하고 변경할 내용을 인용하세요.

산출물: SCRIPT.md (세 개의 훅 + 선택, 전체 내레이션, 시간이 지정된 샷 테이블, 단어 수) 및 script.py.

2. 타임라인, 그 다음 음성

  • script.py는 PHRASES (각 대사가 배치되는 위치, 텍스트, 빨간색 키워드에 [word]가 있는 자막 청크)와 MARKS (초 단위의 스토리 비트, 샷 경계가 됨)를 보유합니다.
  • python build_tl.py는 timeline.json (total, marks, lines)을 작성합니다. 릴은 timeline.json만 읽습니다. 스타터에서는 오디오가 존재하기 전에 작동합니다: 구절 길이는 단어 수에서 추정되므로 먼저 그림을 블로킹할 수 있습니다.
  • 음성은 스피커당 하나의 테이크, 48kHz 모노이며, 모든 TTS 또는 마이크에서 가져옵니다 (이 저장소는 제공하지 않음; ElevenLabs는 유료, Kokoro는 무료 및 로컬). 절대 테이크를 속도를 높여 맞추지 마세요. 대신 비트를 자르세요. TTS에 보내는 텍스트에서 숫자를 단어로 표기하세요.
  • python tools/find_phrases.py take.wav는 테이크에서 각 구절의 (start, end)를 출력합니다. 그것들을 PHRASES에 넣고 build_tl.py를 다시 실행하세요: 구절을 잘라내어 배치하고 audio/narration.wav를 작성합니다. 그런 다음 각 샷을 다시 확인하세요: 실제 구절 길이는 추정치와 다릅니다.
  • 제공된 build_tl.py 파일은 한 명의 내레이터를 처리합니다. 여러 스피커의 경우 스피커당 하나의 테이크를 유지하고 각 구절에 스피커를 추가하세요 (build_tl.py의 작은 변경).
  • TikTok용 욕설: 별도 스템에서 비프음 처리하고 자막에서 별표 처리하세요 (f***ing).

3. 에피소드 파일 (references/engine.md)

파일역할
script.py대사, 자막 청크, 마크
build_tl.pytimeline.json (+ audio/narration.wav)
looks.py캐스트: 각 룩은 rig.LOOK의 딕셔너리
scenes.py세계: 세트 지오메트리, 조명, 시간 T에 누가 어디에 있는지, 연기 트랙
reel.pySHOTS, 자막, render(T), 체크, 렌더 명령어
cues.pytools/sound.py용 사운드 이벤트
finalize.py스템을 믹스하고 렌더에 먹싱, tools/finish.py 실행

episodes/starter/toon을 episodes/<name>/toon에 복사하여 새 에피소드를 시작하세요. reel.py, build_tl.py 및 finalize.py는 일반적이며 그대로 둘 수 있습니다. script.py, looks.py, scenes.py, SHOTS 테이블 및 cues.py를 교체하세요. episodes/window/toon에서 시작하지 마세요: reel.py, cues.py 및 체크는 그 스토리(두 개의 거울 세계, 명명된 마크, 사용자 정의 트위스트 카메라)에 연결됩니다. 기술을 위해 읽으세요: 텍스처, 피사계 심도, 세계별 얼굴 키, 유리 위의 손, 세계 간 크로스페이드. 더 큰 에피소드는 연기를 scenes.py에서 acting.py로 이동합니다.

세계는 두 가지 메서드가 필요합니다: 모든 것을 그리고 {pid: rig.draw 결과}를 반환하는 draw(fr, cam, T)와 [(pid, look, pose)]를 반환하는 cast(T). pid는 이 에피소드에서 사람의 ID입니다 ("nora"). 위치당 하나의 세계와 하나의 타임라인; 샷만 카메라를 선택합니다.

4. 룩 (references/look.md)

둥글고 단순한 모양, 약간 큰 머리, 크고 표현력 있는 눈, 부드러운 3-스톱 음영과 기본 색상의 더 어두운 윤곽선이 있는 무광 재질. 각 캐릭터는 스크립트에서 디자인된 고유한 실루엣, 얼굴 및 팔레트를 얻습니다 (다른 릴의 캐릭터를 재스킨하지 않음); 반복 캐릭터는 모델에 충실합니다. 애니메이션 전에 모델 시트를 만드세요. tools/toon에서: python -m cast.sheet ../../episodes/<name>/toon/looks.py <look> (프로젝트 루트에 assets/kit/cast/<look>.png를 작성하거나 세 번째 인수로 지정한 경로에 작성).

5. 조명 (references/lighting.md)

모든 위치에 세 개의 레이어: 차가운 환경 (청자색 밤은 디테일 유지), 모든 얼굴에 부드러운 키 라이트 (위앞에서, 램프나 창문에 의해 동기 부여됨), 그리고 다양한 거리의 따뜻한 실용 조명으로 근처를 비춤. 얼굴은 프레임에서 가장 선명한 것; 배경은 주변보다 약간 더 어둡고 대비가 낮습니다. 발, 가구 및 닿는 손 아래의 접촉 그림자. 위치당 하나의 조명 설정: 방향, 색상 및 노출은 컷 전반에 걸쳐 유지됩니다. 블룸, 빛나는 윤곽선, 찌그러진 검은색 없음. 날씨 (비, 눈, 바람)는 스토리에 날씨가 있을 때 조용한 순간에 애니메이션됩니다.

6. 카메라 (references/camera.md)

  • 2-3초마다 컷. 각 샷은 하나의 동작, 하나의 표정 또는 하나의 폭로를 제공합니다.
  • 훅 (0-3초)은 릴에서 가장 아름다운 움직이는 샷: 카메라와 캐릭터가 프레임 1부터 움직입니다.
  • 투샷 먼저, 그 다음 매칭 클로즈업. 클로즈업은 시선 방향에서 ~35도 이내를 유지합니다.
  • track(a, b, ease)는 두 키 (position, target, focal px, horizon) 사이에서 하나의 깔끔한 움직임을 만듭니다. 카메라는 타겟을 향해 회전하지만 기울일 수 없음: 타겟의 높이는 무시됩니다. 카메라 높이와 horizon으로 위아래를 프레이밍합니다 (값이 작을수록 시선이 프레임에서 더 높아져 내려다보는 것으로 읽힘).
  • 시야에 있는 사람으로부터 카메라를 >= 0.45m 유지: rig.draw는 그보다 가까운 사람을 그리지 않습니다.
  • 자막 (Arial Black 66px, 흰색, 검은색 윤곽선, 키워드 #FF4D4D)은 얼굴이나 손 위에 절대 놓이지 않습니다. cap=(y, size)으로 샷별로 이동하세요.

7. 연기 및 연출 (references/acting-staging.md)

모든 동작은 오프셋이 있는 체인: 눈 -> 머리 -> 어깨 -> 몸통 -> 손, 준비 -> 움직임 -> 안정. 반응은 out/snap으로 이즈, 안정은 back으로. 머리와 어깨만 돌리는 사람은 기본 발로 설 수 있음; 걷거나 몸을 돌리는 사람은 세계 공간에 발을 고정해야 함 (rig.replant 또는 rig.gait에서 ankle_R/ankle_L), 한 발씩. 무언가를 블로킹하기 전에 연출 교훈을 읽으세요: 각각은 이미 발생한 결함입니다.

8. 체크: 모든 마스터 전의 관문 (references/checks.md)

  1. python reel.py --check -> 전체 review/reel_checks.txt를 읽으세요. 스타터에서 모든 문제는 ANOMALY 라인입니다: 도달, 가라앉는 발, 과도하게 구부러진 팔꿈치, 팔꿈치 및 무릎 뒤집힘, 점프, 렌즈에 너무 가까운 사람, 얼굴이나 손 위의 자막.
  2. python reel.py --stills -> 각 샷의 첫/중간/마지막 프레임 (1차).
  3. python reel.py --sheet <SHOTS> -> 접촉 샷, 걷기, 회전 및 가려짐 변경의 모든 프레임을 간격 시트로 (2차). 분할, 튀어나오는 팔다리, 물체를 통과하는 머리, 사라지는 물체를 찾으세요.
  4. 데이터에서 수정하고 다시 실행한 후 각 이상을 review/LOG.md에 기록하세요 (추가만): 시간, 샷, 원인, 수정, 확인 방법; 사유와 함께 승인된 플래그, 검사할 수 없었던 것.
  5. 코드만으로 "이상 없음"을 주장하지 마세요. 코드는 관절을 확인하고 그림을 확인하지 않음: 사람이 가구나 서로를 통과하는 것, 손이 없는 소품, 잘못된 그리기 순서, 또는 0.8m 옆으로 이동하는 것이 분할로 읽히는 것을 보지 못합니다. 그것들은 시트에서 찾으세요.

9. 렌더링 (에피소드 폴더에서)

  • python reel.py --preview --full -> review/reel_preview.mp4 (1080x1920, 무음). python finalize.py preview는 믹스를 추가 -> review/preview.mp4. 보여주고 승인을 받으세요.
  • python reel.py --master-par 12 -> video/reel_silent.mp4: 12개 프로세스로 마스터 (코어 수 사용).

10. 사운드, 믹스, 마무리, 포스트 (references/sound-finish.md)

  • cues.py, 그런 다음 프로젝트 루트에서 python tools/sound.py episodes/<name>/toon -> 음악, SFX 및 앰비언스 스템. 실제 물건에는 실제 녹음 (CC0 또는 라이선스 샘플을 assets/sfx/에 가져오기); 추상적인 드론, 라이저 및 붐에만 합성. 스타터의 큐는 모두 합성되어 체인이 실행됨: 교체하세요.
  • python tools/mix_check.py episodes/<name>/toon: 모든 대사에서 음성이 배경음보다 >= 10dB여야 함 (실제 내레이션 테이크가 있을 때까지 모든 대사가 실패).
  • python finalize.py final (에피소드 폴더) -> tools/finish.py -> -14 LUFS, <= -2 dBTP, H.264 High, +faststart.
  • 커버, 프로젝트 루트에서: python tools/thumb.py frame.png cover.jpg --line "TITLE:#F2EFE6:120".
  • POST.md: 플랫폼별 자막, 해시태그, 앱에서 HD 업로드를 켜라는 알림.

여기서 사용되는 용어

  • 마크 (mark): 초 단위의 명명된 스토리 비트 (MARKS), 샷 경계 및 동작 타이밍에 사용.
  • 스테이션 (station): 캐릭터가 서는 지점 (x, z, facing) 및 그곳으로 이동하는 시간.
  • 고정된 발 (planted foot): 세계 위치에 고정된 발목 (ankle_R/ankle_L), 발이 미끄러지지 않도록 함.
  • 클립 영역 (clip zone): 신체 일부를 무언가 뒤에 숨기는 화면 공간 클립 (울타리, 벽 모서리).
  • 벽면 아이템 (wall-flat item): 벽에 평평하게 붙은 세트 장식 (커튼, 포스터); 벽만큼 뒤로 정렬.
  • 실용 조명 (practical): 세트에서 보이는 광원 (램프, 불이 켜진 창문).

습관

  • 주장하기 전에 보세요. 프레임을 렌더링하고 시트를 읽은 다음 본 것을 말하세요.
  • 하나의 변경, 해당 샷의 한 번 재렌더, 한 번 재확인, 시트 포함.
  • 연출이 계속 실패하면 단순화하거나 더 명확한 각도를 선택하세요. 절대 해부학을 블러, 어둠, 컷 또는 자막으로 숨기지 마세요.
  • 사용자가 준 모든 수정 사항을 에피소드의 review/LOG.md에 기록하고, 일반적인 경우 프로젝트 루트의 STAGING_NOTES.md에 기록하세요 (모든 에피소드 시작 시 읽음). 절대 플러그인의 자체 폴더에 쓰지 마세요.

관련 스킬