
AI 브랜치 다이얼로그 선택지가 엔딩과 호감도를 망치지 않게 설계하는 패턴
AI 기반 브랜치 다이얼로그에서 선택지 폭발, 불투명한 호감도 변화, 우연한 엔딩 고정을 줄이는 설계 패턴을 정리한다. 상태 변수, 가중치, 게이트, 검증 규칙으로 선택의 결과를 일관되게 만드는 방법을 다룬다.
AI 기반 브랜치 다이얼로그는 생성되는 문장 수를 늘리는 기능이 아니라 선택의 의미를 상태 변화와 엔딩 조건으로 안정적으로 연결하는 시스템이다. 핵심은 AI가 대사를 생성하더라도 호감도와 플래그의 최종 판정은 규칙 기반 상태 모델이 담당하게 분리하는 데 있다. 이렇게 하면 예상하지 못한 대화가 나와도 밸런스와 엔딩 도달 조건을 검증할 수 있다.
AI 브랜치 다이얼로그에서 엔딩 설계가 어려운 이유는 무엇인가?
전통적인 분기 대화는 작성자가 모든 노드를 직접 연결하므로 결과를 추적하기 쉽다. 반면 LLM 기반 대화는 플레이어 입력과 NPC의 반응이 매번 달라질 수 있다. 이때 AI의 자연어 출력을 곧바로 affection + 10이나 엔딩 플래그 변경으로 연결하면 다음 문제가 생긴다.
| 문제 | 발생 원인 | 설계 결과 |
|---|---|---|
| 선택지 폭발 | 대사와 상태 전이를 같은 그래프로 관리 | 테스트할 수 없는 경로가 급증 |
| 호감도 인플레이션 | 친절한 표현마다 높은 보상 부여 | 초반 대화만으로 최상위 관계 도달 |
| 엔딩 우연성 | 단일 플래그 또는 직전 선택만으로 판정 | 플레이어가 이유를 이해하지 못함 |
| 캐릭터 붕괴 | AI가 맥락 없이 긍정 반응 생성 | NPC의 가치관과 보상 규칙이 어긋남 |
해결 원칙은 간단하다. AI는 표현과 후보 선택지를 만들고 게임 시스템은 의미 태그와 상태 전이를 검증한다. 자연어를 게임 규칙의 직접 입력으로 사용하지 말고 제한된 의미 단위로 변환한 뒤 적용한다.
대사 생성과 게임 상태를 어떻게 분리할까?
대화 시스템을 세 층으로 나누면 설계와 QA가 쉬워진다.
- 서사 층: NPC 페르소나, 현재 장면, 기억 요약을 바탕으로 대사와 선택지 문구를 생성한다.
- 의도 층: 선택지를
공감,경계 존중,거짓말,협박,회피같은 통제된 태그로 분류한다. - 규칙 층: 태그, 관계 상태, 퀘스트 플래그를 입력으로 받아 호감도와 엔딩 변수 변경을 결정한다.
flowchart LR
P[플레이어 선택] --> I[의도 태그 판정]
I --> R[규칙 엔진]
R --> S[호감도·신뢰·플래그 갱신]
S --> E[엔딩 조건 평가]
R --> N[AI NPC 반응 생성]
N --> D[다음 대화]
이 구조에서 AI는 NPC가 상처받은 말투로 답한다를 생성할 수 있지만 실제로 신뢰가 얼마나 줄어드는지는 규칙 엔진만 결정한다. 의도 태그는 JSON Schema나 열거형으로 제한하는 편이 좋다.
{
"intent": "respect_boundary",
"targetNpc": "mira",
"evidence": ["플레이어가 거절 의사를 수용함"],
"confidence": 0.86
}
confidence가 낮으면 자동 적용하지 말고 neutral 태그로 폴백하거나 미리 작성한 안전 선택지로 바꾼다. 특히 연애, 배신, 사망처럼 회복이 어려운 결과에는 AI 분류 결과 하나만으로 상태를 바꾸지 않는 것이 안전하다.

호감도 시스템은 왜 단일 점수보다 다축 모델이 좋은가?
호감도 하나만 있으면 플레이어는 모든 관계를 ‘좋은 말 많이 하기’로 최적화한다. 그러나 신뢰, 친밀감, 공포, 존중은 서로 다른 선택에서 다르게 움직여야 한다.
예를 들어 NPC Mira의 관계 벡터를 다음처럼 둔다.
T(Trust): 약속을 지키고 정보를 정직하게 다룰수록 증가A(Affection): 개인적 관심과 정서적 공감으로 증가S(Respect): 경계 존중과 역량 인정으로 증가F(Fear): 위협과 강압으로 증가
선택지의 상태 변화량은 장면별 계수까지 포함해 계산할 수 있다.
여기서 B_intent는 의도별 기본 변화량, C_context는 현재 장면의 민감도, M_memory는 이전 사건과의 일관성 보정값이다. 예를 들어 사적인 비밀을 막 알게 된 직후에는 공감의 신뢰 보정이 커질 수 있고 이미 여러 번 약속을 어긴 상태에서는 사과의 효과를 낮출 수 있다.
| 의도 태그 | 신뢰 T | 친밀감 A | 존중 S | 공포 F |
|---|---|---|---|---|
keep_promise | +8 | +2 | +3 | 0 |
show_empathy | +2 | +6 | +1 | 0 |
respect_boundary | +1 | 0 | +7 | -1 |
lie_for_gain | -9 | -2 | -4 | 0 |
threaten | -6 | -5 | -7 | +10 |
변화량은 매 대화에서 그대로 누적하지 말고 상한과 체감 구간을 둔다. 같은 유형의 선택을 반복할수록 보상을 줄이면 대화 반복 파밍을 막을 수 있다.
n은 최근 3개 장면에서 같은 의도 태그를 선택한 횟수다. 최소 계수 0.25는 일관된 역할 연기가 완전히 무의미해지는 문제를 막는다.
멀티 엔딩 조건을 어떻게 투명하고 견고하게 만들까?
좋은 엔딩 조건은 단일 임계값보다 관계 상태, 핵심 사건, 되돌릴 수 없는 선택을 함께 평가한다. 다만 모든 조건을 플레이어에게 숫자로 공개할 필요는 없다. 플레이어가 자신의 행동과 결과를 연결할 수 있는 단서는 제공해야 한다.
1. 엔딩에 필요한 변수를 역할별로 나눈다
| 변수 종류 | 예시 | 용도 |
|---|---|---|
| 누적 관계 값 | trust, affection, respect | 장기적인 관계 방향 판정 |
| 서사 플래그 | shared_secret, saved_village | 사건의 발생 여부 기록 |
| 결정 플래그 | accepted_exile | 되돌릴 수 없는 선택 기록 |
| 메타 조건 | chapter >= 6, companion_alive | 콘텐츠 접근성과 모순 방지 |
2. 엔딩 후보를 게이트와 점수로 구성한다
먼저 필수 조건인 게이트를 통과한 엔딩만 후보로 남긴다. 이후 후보별 점수를 계산해 가장 높은 엔딩을 선택한다.
type EndingState = {
trust: number;
affection: number;
respect: number;
sharedSecret: boolean;
acceptedExile: boolean;
companionAlive: boolean;
};
function scoreMiraReconciliation(s: EndingState): number | null {
if (!s.sharedSecret || !s.companionAlive) return null;
if (s.trust < 55 || s.respect < 45) return null;
return s.trust * 0.5 + s.affection * 0.2 + s.respect * 0.3;
}
게이트는 서사의 논리적 모순을 막고 점수는 서로 다른 플레이 스타일이 같은 엔딩에 도달할 여지를 만든다. 예를 들어 연애 엔딩에는 높은 affection과 trust를 요구하되 동료 엔딩은 respect와 공동 퀘스트 달성으로도 가능하게 설계할 수 있다.
3. 동점과 실패 시의 폴백을 명시한다
후보가 동점이면 우선순위만으로 조용히 결정하지 말고 플레이어가 마지막에 선택할 수 있는 짧은 결단 장면을 제공하는 편이 낫다. 후보가 하나도 없을 때는 ‘배드 엔딩’으로 단정하기보다 관계가 미완인 중립 엔딩을 준비한다. 이는 생성형 대화의 예외 경로를 흡수하는 안전망이 된다.
AI 선택지의 결과를 플레이어가 납득하게 하려면?
AI 선택지는 문장만 달라도 실제 의미가 같을 수 있다. 따라서 UI에는 정확한 수치 대신 결과의 방향과 위험도를 보여 주는 것이 효과적이다.
- 낮은 위험:
미라의 입장을 들어본다 - 중간 위험:
비밀을 공유해 신뢰를 얻으려 한다 - 높은 위험:
증거를 이용해 협박한다
각 선택지에 아이콘이나 짧은 톤 라벨을 붙여 신뢰, 존중, 위험 중 어떤 축이 영향을 받는지 암시한다. 단, 예상 결과와 실제 결과가 계속 다르면 UI 힌트는 오히려 신뢰를 해친다. 의도 태그와 UI 라벨은 같은 데이터 소스에서 생성해야 한다.
또한 중요한 상태 변화 뒤에는 NPC의 반응, 저널 갱신, 다음 선택지의 태도 변화 중 하나를 반드시 보여 준다. ‘호감도가 5 올랐다’보다 ‘미라가 처음으로 작전 회의에 플레이어를 초대했다’가 더 강한 피드백이다.
AI 브랜치 다이얼로그 밸런싱 검증 절차
1. 상태 전이 표를 먼저 만든다
대사를 쓰거나 프롬프트를 설계하기 전에 NPC별 의도 태그, 변화량 범위, 금지 전이를 표로 정의한다. 예를 들어 협박은 어떤 맥락에서도 trust를 올리지 않는다는 규칙을 명시한다.
2. 시뮬레이션 경로를 생성한다
정직형, 공감형, 실리형, 강압형처럼 대표 플레이 스타일을 만들고 장면 순서에 따라 상태를 누적한다. 각 유형이 의도한 엔딩 후보에 진입하는지 한 유형만 압도적으로 효율적인지 확인한다.
3. LLM 출력은 계약 테스트로 검증한다
프롬프트 테스트에서는 문체 품질뿐 아니라 구조화 출력의 유효성을 검사한다. 허용되지 않은 intent, 존재하지 않는 NPC ID, 확신도 누락은 재시도 또는 안전한 기본값으로 처리한다.
const allowedIntents = new Set([
"show_empathy",
"respect_boundary",
"keep_promise",
"lie_for_gain",
"threaten",
"neutral"
]);
function isSafeIntent(intent: string, confidence: number): boolean {
return allowedIntents.has(intent) && confidence >= 0.7;
}
운영 환경에서는 선택지 텍스트, 의도 태그, 적용된 상태 변화, 엔딩 후보 점수를 익명 로그로 남긴다. 이 로그가 있어야 ‘AI가 이상한 선택지를 냈다’와 ‘규칙 테이블이 과도한 보상을 줬다’를 구분할 수 있다.
자주 묻는 질문 (FAQ)
AI가 호감도 수치를 직접 예측하게 해도 될까?
권장하지 않는다. AI는 의도 분류와 서술 생성에 사용하고 수치 변화는 디자이너가 정의한 테이블과 수식으로 계산해야 재현성과 밸런싱을 확보할 수 있다.
모든 대화 선택이 엔딩에 영향을 줘야 할까?
아니다. 대부분의 선택은 분위기와 단기 반응을 만들고 일부 핵심 선택만 서사 플래그나 엔딩 점수에 영향을 주는 편이 플레이어와 QA 모두에게 관리하기 쉽다.
호감도 수치를 UI에 공개해야 할까?
게임의 장르와 톤에 따라 다르다. 연애 시뮬레이션처럼 최적화 자체가 재미라면 수치를 공개하고 서사 몰입이 중요하다면 관계 단계와 행동 피드백만 보여 주는 방식이 적합하다.
정리
AI 브랜치 다이얼로그의 품질은 생성되는 문장의 수가 아니라 선택과 결과의 일관성에서 결정된다. 대사 생성, 의도 태그, 규칙 기반 상태 전이를 분리하고 다축 관계 모델과 게이트 기반 엔딩 조건을 적용하면 자유로운 대화 경험을 유지하면서도 밸런싱과 테스트 가능한 멀티 엔딩 구조를 만들 수 있다.


