"내 목소리가 곧 조작이자 대화가 되는, 사람 사는 것 같은 3인칭 소셜 월드"
음성으로 캐릭터를 조종하고, 명령이 아닌 말은 그대로 채팅 말풍선이 되는 무협 소셜 게임. 이 시리즈는 개발 과정을 시간순으로 기록하는 연대기다.
단일 HTML 파일로 아이디어를 검증하며 하루 만에 다섯 단계를 진화시켰다.
이날 확정된 시그니처 UX가 갸웃 제스처다. 음성 인식이 실패하면 에러 메시지 대신, 캐릭터가 카메라를 고정한 채 뒤돌아 플레이어를 바라보며 어깨를 으쓱하고 고개를 갸웃한다. 기술적 한계를 캐릭터의 매력으로 바꾸는 것 — 이 게임의 정체성이 여기서 시작됐다.
822줄 단일 HTML을 19개 모듈(world/hero/voice/net/game/ui)로 분리했다. 핵심은 네트워크 transport 추상화 — PeerJS P2P 코드를 인터페이스 뒤로 숨겨서, 나중에 Colyseus(WebSocket) 서버로 전환할 때 팩토리 한 줄만 바꾸면 되게 설계. 갸웃 제스처의 카메라 고정 연출은 프레임 단위 수치까지 원본 그대로 보존했다.
전투 개선: 등 뒤의 몹을 정면 본 채 맨손으로 때리던 어색함을 수술했다. 공격 순간 대상을 향해 몸을 돌리고, 등의 검을 뽑아 손에 들고 베고(발도), 맞은 몹은 밀려나고, 내가 맞으면 붉은 파편이 튄다.
욕설 순화(미칭 치환): 욕설·비하 표현이 말풍선에 그대로 나가지 않고 "왕자님", "공자님", "대협" 같은 존칭으로 바뀌어 표시되는 기능을 넣었다. "이 바보야!" → "이 왕자님야!" — 차단 대신 유머로 승화. 부수 효과로 "닥쳐"가 공격 명령("쳐")으로 오분류되던 버그도 함께 해결됐다.
리깅 글TF + 모션캡처 파이프라인을 적용했다. Mixamo 리그의 Soldier로 검증한 뒤, KayKit Adventurers(CC0)의 Knight로 교체 — 진짜 검격 모션캡처 클립 (사선 베기)과 실물 검 모델(오른손 슬롯 부착)까지 들어갔다.
이 과정에서 원본부터 존재하던 좌우 반전 버그 2개를 발견해 수정했다: "오른쪽" 음성 명령이 화면 왼쪽으로 가던 문제, 그리고 캐릭터가 검을 왼손으로 휘두르던 문제(모델 좌우 배치가 해부학적으로 반대였다).
삽질 기록: GLTFLoader는 본(bone) 이름의 점을 제거한다(upperarm.l → upperarml).
본 매칭이 조용히 실패해서 한참 헤맸다.
욕설 순화 기능을 게임의 사회적 가치 제안으로 격상시켰다.
포지셔닝 한 줄: "말이 고와지고, 발음이 또렷해지는 게임"
| 결정 | 이유 |
|---|---|
| 음성 분류 단일 진입점 (handleUtterance) | 명령/채팅/갸웃/순화가 한 곳에서 일관되게 판정 |
| 갸웃 제스처 = 시그니처 | 인식 실패를 매력으로 — 순화 기능도 같은 철학 |
| host-authoritative P2P → 서버 전환 설계 | MVP 속도 우선, transport 추상화로 이식 대비 |
| three.js 버전 고정(r128) | 시각 결과 동일성 보장 |
| KayKit CC0 에셋 | 라이선스 청정 + 모바일 성능(Knight 334KB) |
다음 편에서 계속.