~/Library/Application Support/im.vora.vivi/characters/CHARACTER STUDIO / 커스텀 가이드
나만의 VIVI를
만드는 방법.
투명한 원화, 몇 개의 JSON 파일. 앱을 다시 빌드하지 않고 나만의 캐릭터와 움직임을 추가해 보세요.
VORA VIVI는 데스크톱 전용입니다. 설치 앱은 첫 릴리스를 준비 중이며, 아래는 실제 앱 검증기를 기준으로 한 제작 규격입니다.
YOUR VIVIYOUR STYLE ✦
01 / START
빈 종이 대신, 작동하는 샘플부터.
샘플은 투명 원화 12장으로 만든 타이핑과 정지 대기 자세가 들어 있는 .vivipack 파일입니다. ZIP으로 풀어 구조를 확인하고, 나만의 원화로 바꾸세요. 전체 동작 모음은 아닙니다.
02 / YOUR FOLDER
이 폴더에 넣으면 됩니다.
VIVI 우클릭 → 캐릭터 → 캐릭터 폴더 열기로 현재 PC의 정확한 경로를 확인할 수 있습니다. 아래 경로 안에 <packId>/<packVersion>/ 폴더를 만들어 넣으세요.
%APPDATA%\im.vora.vivi\characters\~/.local/share/im.vora.vivi/characters/Windows에서는 탐색기 주소창에 붙여 넣고, macOS에서는 Finder → 이동 → 폴더로 이동을 사용하세요. Linux에서 XDG_DATA_HOME을 지정했다면 그 경로가 우선합니다.
<packId>/<packVersion>/character.json03 / THE FILES
캐릭터 한 개 = 폴더 한 개.
character.json은 캐릭터 설명과 동작 연결표, frames.json은 실제 프레임의 순서·재생 시간입니다. 모든 파일 경로는 캐릭터 팩 루트 기준입니다.
my-vivi.starter/
└── 1.0.0/
├── character.json
├── checksums.json
└── clips/
├── idle/frames.json
└── typing/
├── frames.json
├── typing-01.png
└── … typing-12.pngcharacter.json — 캐릭터와 이벤트
{
"schemaVersion": 1,
"packId": "my-vivi.starter",
"packVersion": "1.0.0",
"canvas": {
"width": 1024,
"height": 896
},
"defaultDisplayHeight": 160,
"clips": {
"typing": {
"frameCount": 12,
"sequence": "clips/typing/frames.json",
"entryPose": "typing.ready",
"exitPose": "typing.ready",
"loop": true
}
},
"eventBindings": {
"idle": [
"typing"
],
"chat.waiting": [
"typing"
]
}
}frames.json — 프레임 순서
{
"frames": [
{
"file": "clips/typing/typing-01.png",
"durationMs": 100,
"marker": "rest"
},
{
"file": "clips/typing/typing-02.png",
"durationMs": 100
}
]
}아래는 샘플의 핵심 부분입니다. 샘플 팩에는 12장 전체와 전체 JSON이 들어 있습니다.
04 / MAKE IT MOVE
움직임은 전신 원화로.
한 장을 흔들거나 팔다리만 회전하는 대신, 동작별 전신 원화를 이어 주세요. 시작·종료 포즈와 발의 접지점을 맞추면 전환도 자연스러워집니다.
- PNG 또는 WebP의 투명 배경. 모든 프레임은 같은 캔버스 크기입니다.
- 원화는 최대 2048×2048, 화면 표시 높이는 80~320px입니다. 권장 표시 높이는 160px입니다.
- 한 동작은 1~240프레임, 프레임당 16~30,000ms. 샘플은 12프레임·100ms입니다.
- anchor는 발의 기준점, bubbleAnchor는 말풍선의 시작점입니다. 좌표는 0~1로 표시합니다.
- 반복 동작의 entryPose와 exitPose는 같아야 합니다. 서로 다른 자세는 연결 원화 클립과 transitions로 연결합니다.
- 스크립트·실행 파일 없이 이미지와 JSON만으로 구성하세요. 전체 팩은 압축 해제 후 최대 512MiB입니다.
언제 어떤 동작을 보여줄까요?
| 이벤트 | 동작 |
|---|---|
idle | 기본 대기 — 반드시 필요 |
chat.waiting | 첫 답변을 기다리는 동안 |
chat.streaming | 답변 스트리밍 중 |
chat.complete | 답변 완료 |
input.listening | 음성 입력을 듣는 동안 |
file.uploading | 파일 업로드 중 |
notification | 보라서비스 알림 |
calendar.reminder | 캘린더 미리 알림 |
cua.working | 컴퓨터 사용 작업 중 |
update.available | 새 버전 알림 |
eventBindings에 연결한 동작이 없으면 fallbacks로 대체 이벤트를 지정합니다. fallback은 순환하면 안 됩니다. 계절·미디어별 확장 이벤트는 앱이 지원하는 규격에 맞춰 추가합니다.
05 / TRY IT ON
완성했다면 VIVI에 입혀 주세요.
- 쉬운 방법: 캐릭터 폴더 안의 파일을 ZIP으로 묶고 확장자를 .vivipack으로 바꿉니다. ZIP 루트에 character.json이 있어야 합니다.
- VIVI 우클릭 → 캐릭터 → 팩 가져오기에서 .vivipack을 선택합니다. 검증을 통과하면 적용됩니다.
- 직접 넣기: 위 OS 폴더에 <packId>/<packVersion>/ 구조로 복사한 뒤 캐릭터 목록을 새로고침하고 선택합니다.
- checksums.json이 들어 있다면 수정한 파일의 SHA-256도 갱신하세요. 처음 만드는 개인 팩은 이 파일을 생략할 수 있습니다.
- 잘못된 팩은 적용하지 않으며 현재 캐릭터를 유지합니다. 기본 VIVI는 앱 설치 폴더에서 직접 수정하지 마세요.
06 / A LITTLE HELP
잘 안 보일 때 확인하세요.
목록에 없어요+
character.json 위치와 packId/packVersion을 확인하고 캐릭터 목록을 새로고침하세요.
그림이 튀거나 잘려요+
캔버스 크기·투명 여백·anchor를 전 프레임에서 맞추고, 160px 실물 크기로 확인하세요.
프레임 수가 다르대요+
frameCount와 frames 배열 길이를 똑같이 맞추세요. 파일 이름의 대소문자도 확인하세요.
전환이 끊겨요+
이전 exitPose와 다음 entryPose 사이의 연결 원화를 등록하세요. 단순 페이드를 전환 원화 대신 사용하지 않습니다.
해시가 안 맞아요+
원화를 고친 뒤 checksums.json의 해당 SHA-256을 다시 계산하거나 개인 팩에서는 파일을 제거하세요.