
하드보일드 탐정 ADV를 만들려다 사이버펑크가 되어버린 이야기 —— AI와 공동 작업한 노벨 게임의 기술 구성
요약
AI와 협업하여 하드보일드 탐정물에서 사이버펑크 장르로 변모한 노벨 게임 개발 사례를 소개합니다. 시나리오 라이터가 JSON을 통해 게임 로직을 직접 제어하는 구조와 다양한 미니게임 설계 방식을 다룹니다.
핵심 포인트
- AI와의 협업을 통한 창의적인 세계관 확장 및 플롯 생성
- JSON 구조체를 활용한 시나리오 기반의 게임 이벤트 제어 시스템
- ADV 엔진과 연동되는 통일된 콜백 기반의 미니게임 설계
- 시나리오 데이터와 게임 로직의 분리를 통한 개발 효율성 확보
하고 싶었던 것은 하드보일드한 탐정물이었다.
어스름한 사무실, 민트를 씹는 탐정, 조심스러운 노크 소리. 신주쿠의 밤을 무대로, 옛날 방식의 좋은 탐정 소설의 분위기를 게임으로 만들고 싶었다. 그뿐이었다.
그런데, AI와 함께 스토리를 짜 나가는 동안 이야기가 점점 이상한 방향으로 흘러가기 시작했다.
「지하도에 매주 놓이는 푸른 장미」의 수수께끼를 쫓고 있었을 터인데, 어느샌가 「고스트 프로토콜 (Ghost Protocol)」이라느니 「우로보로스 (Ouroboros)」라느니 하는 험악한 코드네임이 난무하고, 경찰청 전 국장이 암살을 「업무 위탁」으로 결재하거나, 흑막이 디지털 공간에서 「신」 행세를 하고 있다.
완전히 사이버펑크였다.
처음에는 「아니, 그쪽으로 간다고?」라고 생각했지만, AI가 제안하는 플롯이 묘하게 앞뒤가 맞아서 어느덧 올라타게 되었다. 하드보일드와 사이버펑크가 뒤섞여, 스스로는 절대로 생각할 수 없는 카오스한 세계관이 완성되었다.
완성된 것은, 3개 루트 · 28개 시나리오 파일 · 8종류의 미니게임을 가진 노벨 게임이다.
static readonly string[] allFiles = {
"Chapter1", "Chapter2",
"Chapter2_Saeki", "Chapter2_Rin",
...
메인 루트: 총 5장 + Good/Bad End -
린 루트: 총 5장 + Good/Bad End (19세 해커) 향후 추가 예정 -
카스미 루트: 총 6장 + Good/Bad End (바텐더) 향후 추가 예정 -
플래시백: 2개 (고인인 엔도의 과거) 향후 추가 예정
모든 시나리오는 JSON으로 관리되며, 선택지에 의한 분기와 파일 간의 연쇄로 이야기가 진행된다.
시나리오 데이터는 한 줄 한 줄이 JSON 구조체로 정의되어 있다.
[Serializable]
public class DialogueLine
{
...
하나의 JSON 필드로 「대사 표시」, 「배경 변경」, 「BGM 전환」, 「선택지 분기」, 「미니게임 기동」, 「다음 장으로의 연쇄」를 모두 제어할 수 있다. 프로그래머가 개별적으로 이벤트를 짤 필요 없이, 시나리오 라이터 (= AI)가 JSON을 쓰는 것만으로 게임이 움직인다.
ADV 파트 도중에 시나리오에 따른 미니게임이 발동한다. 모두 Action<bool>
콜백(Callback)으로 성패를 ADV 엔진에 반환하는 통일된 설계.
| 미니게임 | 내용 | 장면 |
|---|---|---|
| HackingGame | 16진수 코드 기억 · 재현 (사이먼 게임 스타일) | 린의 해킹 장면 |
| CipherLinkGame | 암호 조각(Fragment) 페어링 | 카스미와 엔도의 암호 키 복원 |
| QTEBattleGame | 타이밍 바 + 키 시퀀스 (Key Sequence) | 격투 장면 |
| StealthGame | 8×6 그리드 잠입 퍼즐 | 빌딩 침입 장면 |
| AlleyChaseGame | 골목길 추격 | 추격 장면 |
| DigitalInquisitionGame | 디지털 심문 | 정보 추출 |
| WisdomRingGame | 지혜의 고리 | 수수께끼 풀이 장면 |
| HangOnGame | 지구력 | 위기 탈출 장면 |
// HackingGame: 16진수 코드를 색상으로 기억
static readonly string[] hexPool = {
"7A", "BD", "1C", "E9", "FF", "42", "D1", "93", "A3", "C8", "55", "F4"
...
// StealthGame: 8×6 그리드에서 적의 시야를 피함
const int COLS = 8, ROWS = 6;
struct Enemy
...
미니게임에 실패해도 스토리는 진행된다 (난이도가 변하는 경우가 있음). ADV의 템포를 해치지 않도록, 각 미니게임은 튜토리얼 → 플레이 → 결과의 3단계로 완결되는 설계로 했다.
LanguageManager
를 통해 모든 텍스트를 키(Key) 기반으로 관리한다. 미니게임의 튜토리얼을 포함하여 다국어화를 진행하고 있다.
// 미니게임 내의 UI 텍스트도 모두 키로 참조
MakeLabel(tutGo.transform, LanguageManager.T("breach_title"), 40, ...);
MakeLabel(tutGo.transform, LanguageManager.T("tut_hacking"), 24, ...);
하지만 이 게임에서 가장 마음에 드는 것은 세계관보다도 캐릭터다.
주인공 사에키 렌(Saeki Ren)은 33세의 탐정. 민트를 씹는 버릇이 있고, 과거에 무언가를 잃어버린 남자. 그를 "아저씨"라고 부르는 19세의 린(Rin)은 건방지지만 실력 있는 해커(Hacker)로, 이 두 사람의 티키타카가 묘하게 즐겁다. 바(Bar)에서 일하는 카스미(Kasumi)나, 이야기의 발단이 되는 고인 엔도(Endo)——AI와 함께 만들었음에도 불구하고, 모든 캐릭터가 제대로 "살아있는" 듯한 느낌이 든다.
솔직히 말해서, 처음에 내가 상상했던 게임과는 완전히 다른 것이 완성되었다. 하지만 이것도 나름대로 좋다. 오히려 나 혼자였다면 절대로 도달할 수 없었을 지점에 와 있다는 감각이 있다.
잿빛의 잔향(Gray Echoes)——제목 또한 AI와의 공동 작업에 어울리는 이름이라고 생각한다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기