대화 트리를 게임에 어떻게 구현할 수 있습니까?


51

게임에서 대화 트리 시스템을 구현하는 가장 좋은 방법은 무엇입니까? NPC가 플레이어에게 다양한 응답 세트를 제공하기를 원합니다. 일부는 플레이어에 아이템이 있거나 이전 이벤트가 발생한 경우에만 나타날 수 있습니다.


2
BOUNTY는 특히 트리거 구문과 NPC 텍스트의 번역을 처리하는 방법에 대한 좋은 아이디어를 제공합니다. NPC는 대화를 시작한 플레이어에 따라 다른 언어를 이해하고 말할 수 있습니다. gamedev.stackexchange.com/questions/31/ 에서 빌딩 블록 접근 방식을 사용하더라도 텍스트 리포지토리 내부에 논리를 갖는 것은 좋은 생각이 아닙니다. 그러나 그것들을 나누면 코드를 이해하기가 훨씬 어려워집니다.
— Hendrik Brummermann

답변:


17

대화 상자 트리는 XML을 사용하여 수행해야합니다. 좀 더 복잡한 작업을 수행해야하는 경우 스크립트 파일을 참조하여 응답 및 응답 조건을 중첩 된 트리에 저장합니다.

특히 톤이 많은 대화가있는 RPG를 구성하는 경우 스크립트와 대화 상자를 별도로 유지해야합니다. 그런 다음 simpleXML과 같은 라이브러리를 사용하여 XML 파일을 읽을 수 있습니다.

예를 들어 SO와 비슷한 질문이 있습니다 : https://stackoverflow.com/questions/372915/game-logic-in-xml-files


XML의 경우 +1 코드 자체에 포함하는 것보다 훨씬 낫고 코드를 다시 컴파일하지 않고도 변경할 수 있으며 일부 강력한 편집자가 읽을 수있는 표준 형식입니다.
— AttackingHobo

34
XML은 단지 형식 일뿐입니다 (그리고 IMO, 나쁜 형식). 이 대답은 "기본 논리와 흐름을 포함하지만 주로 대화로 구성되는 작은 도메인 언어를 만들고 구문 분석하는 것"입니다. 일반적인 방법으로이 답변에 동의합니다.
— Ipsquiggle

5
정확히 XML은 컨테이너 일 뿐이므로 Lua 또는 다른 스크립팅 언어를 사용하여이를보다 인간적으로 읽고 편집 가능한 방식으로 구현할 수 있습니다.
— LearnCocos2D

4
XML은 구문 분석하는 데 비용이 많이 들고 많은 메모리를 차지합니다. 저장 형식으로 사용하는 것이 좋지만 대화 상자 트리를 런타임에 사용되는 이진 형식으로 변환하는 유틸리티를 작성했습니다. PC를 사용 중이고 메모리 사용에 신경 쓰지 않으면 괜찮을 수 있지만 다른 플랫폼에서는 메모리 비용이 부담이됩니다.
— BigSandwich

1
XML의 경우 -1입니다. @Ipsquiggle 및 @BigSandwich
— o0 '에

20

루아 또는 루비와 같은 스크립팅 언어를 포함하고 그 안에 대화 대화 상자를 코딩하는 방법을 살펴볼 것입니다.

따라서 대화 스크립트는 다음과 같습니다.

switch showDialog "Why don't you just leave me along!", "Okay", "But I found your dog!"
    case 1:
        showDialog "And stay gone!"
    case 2:
        if playerHasObject "dog"
            showDialog "Thank you!"
        else
            showDialog "Liar!"

이것은 또한 AI 및 런타임 동안 조정하는 데 유용한 기타 간단한 것들을 코딩하는 데 효과적입니다. 디버그 (또는 이스터 에그)로 실행할 때 호출 할 수있는 편집기를 응용 프로그램에 내장 할 수도 있습니다.


1
논리를 추가 할 수 있으므로 XML을 사용하는 것이 좋습니다. 그러나 텍스트 자체는 아마도 코드가 아니라 XML이어야한다고 말하고 싶습니다. (편집하기 쉽고 다른 언어로 현지화하는 등).
— Iain

현지화 / 쉬운 편집이 필요한 경우 Qt의 tr (QString) 함수 / 매크로와 같이 별도의 파일에 동봉 된 텍스트를 작성하는 함수로 텍스트를 래핑 할 수 있습니다. pepper.troll.no/s60prereleases/doc/linguist-hellotr.html
— 일러

여기서 로직을 시뮬레이트하기 위해 XML에서 속성 또는 추가 태그를 사용하지 못하게하는 것은 무엇입니까?
— lathomas64

16

Stendhal 게임에서는 유한 상태 머신을 사용하여 NPC를 구현합니다.

다음 다이어그램은 퀘스트 작성 방법 튜토리얼 의 작은 예를 보여줍니다 .

유휴, ATTENDING 및 QUEST_OFFERED 상태의 FSM

처음에 NPC는 유휴 상태이며 걸어 다닐 수 있습니다. 플레이어는 "hi"라고 말하여 대화를 시작할 수 있으며 NPC는 ATTENDING 상태로 이동합니다. 이 상태에서는 그의 "직업"에 관한 질문에 대답하고 일부 게임 "도움말"을 제공합니다. 플레이어는 퀘스트를 요청할 수 있으며 NPC는 QUEST_OFFERED 상태로 이동하여 플레이어가 수락 ( "yes")하거나 거부 ( "no")하기를 기다립니다.

전환에 첨부 할 수있는 조건 세트를 정의했습니다 . 예를 들어 퀘스트 완료는 PlayerHasItemWithHimCondition 이 충족 된 경우에만 가능합니다 .

전환이 실행 된 후 NPC는 일부 텍스트를 말하거나 동작을 실행할 수 있습니다. 조건과 유사하게 플레이어에게 퀘스트 보상을주는 데 사용되는 EquipItemAction 과 같은 재사용 가능한 액션 세트를 정의했습니다 .

AndCondition , OrCondition 및 NotCondition을 사용하여 여러 조건을 결합 할 수 있습니다 . 일반적으로 퀘스트 완료시 수행해야 할 작업이 많으므로 MultipleActions 클래스도 있습니다.

Stendhal의 실제 구현은 다른 (인간) 언어로 쉽게 번역 할 수 없기 때문에 일반적인 개념이 좋습니다.


5

Open Source RPG 엔진 Adonthell 의 Dlgedit 도구를 살펴볼 수 있습니다 . 매우 고급이며 필요한 모든 것을 포함해야합니다 (소스 포함)


5

번역을 추가하려고해도 위에서 언급 한대로 논리에 XML을 사용할 수 있다고 생각합니다 . 이러한 유형의 복잡성을 경험할 때는 자체 대화 도구를 작성해야합니다. 대화 텍스트는 표시하려는 언어에 따라 바꿀 수있는 데이터베이스의 키로 저장됩니다.

예를 들어 다음을 수행 할 수 있습니다.

<dialogue id="101" condition="!npc.carsFixed">
  <message>Localize.FixMyCar</message>
  <choices>
    <choice condition="hero.carFixingSkill > 5" priority="7" id="Localize.Sure">
      <command>hero.carFixingSkills += 1</command>
      <command>npc.carFixed = true</command>
      <command>hero.playSmokeAnimation()</command>
      <command>nextDialogue = 104</command>
    </choice>
    <choice condition="hero.carFixingSkill <= 5" id="Localize.CantFix">
      <command>nextDialogue = 105</command>
    </choice>
    <choice id="Localize.FixYourself">
      <command>npc.likesHero -= 1</command>
    </choice>
  </choices>
</dialogue>

그런 다음 퀘스트 텍스트 렌더러가 "Localize.FixMyCar"를 적절하게 번역 된 텍스트로 바꿉니다.

도구는 플레이어가 편집 가능한 원시 XML과 함께 선택 가능한 언어로 볼 수있는 것을 표시합니다.

마찬가지로 참조한 예제 에서 다음과 같은 것을 사용할 수 있습니다 .

npc.add(ConversationStates.ATTENDING,
        ConversationPhrases.QUEST_MESSAGES, 
        null,
        ConversationStates.QUEST_OFFERED, 
        Localization[ "BringMeABeer" ],
        null);

키가 충분히 서술 적이라면 완전한 텍스트를 가지고 있지 않아도 문제가되지 않습니다.

이와 같은 것도 유용 할 수 있습니다.

Localization[ "<Location>.<NPC_name>.<Dialogue_text_key>" ];

4

LUA 스크립트 또는 XML 파일을 사용하여 캐릭터를 데이터로 구동하십시오. NPC와 상호 작용할 때 NPC에 첨부 된 파일을 가져 와서 읽은 다음 트리거 된 게임 변수를 조정하고 유효한 응답을 생성하십시오.

이 방법을 통해 얻을 수있는 가장 큰 장점은 대화 상자를 쉽게 조작하고 새 문자를 추가하는 등의 작업을 수행 할 수 있다는 것입니다. 또한 모든 경우를 처리 할 때 특별한 로직을 사용하여 코드베이스를 정리하지 않아도됩니다.


1
루아가 아니라 루아입니다. :)
— RCIX

2
당신을 위해서만 했어요 ;)
— David McGraw

4

XML을 사용하는 경우 작은 파일을 작성하여 XML 파일을 편집해야합니다. 그렇지 않으면 당신은 미쳐 갈 것입니다.


도구를 편집 할 도구가 없다면 처음부터 사용하는 것이 의미가 없습니다. 자신 만의 형식을 만드십시오!
— o0 '.

3

매우 깊은 대화 상자 트리가 있으면 ChatMapper를 사용 하십시오 . 그들은 완전한 기능을 갖춘 무료 버전을 가지고 있으며 도구를 사용하면 대화 상자 트리를 XML로 내보낼 수 있습니다. 나는 그것을 사용하고 있으며 복잡한 대화 상자 트리를 시각화하고 구성하는 훌륭한 방법입니다.


1

대화 상자가 복잡하면 대화 상자 구현에 필요한 가장 중요한 것은 상호 작용의 복잡성을 이해하는 방법입니다. 권장하는 개방형 시스템이 없지만 이것을 시각화하기 위해 일종의 노드 편집기를 권장합니다.


1

나는 당신이 이런 종류의 게임을 지시하기 위해 당신 자신의 스크립트 언어를 사용한다고 생각합니다 (그렇지 않으면, 당신은해야합니다).
대화 상자 논리를 만드는 동안 다른 게임 변수로 작업 할 수 있습니다. 게임 엔진은 레고와 같습니다. 브릭 만 프로그래밍하고 스크립트를 사용합니다. 스크립트 인터프리터 또는 컴파일러를 작성하더라도 중요하지 않습니다. 그러나 스크립트는 항상 유용합니다.


0

간단한 오토 마톤이 할 수있는 일 :

(dialogueline_id, condition) -> (next_id, response)

다음과 같이 보일 수 있습니다.

(1, troll is hungry?) -> (2, say "troll be hungry")
(2, player has bananas?) -> (3, say "hey, you have bananas!")
(3, ) -> (-1, (say "i like bananas, i take them and eat, you may pass, bye", remove bananas, feed the troll))
(2, player does not have bananas?) -> (-1, say "go away!!!")

게임에서 당신은 아이디를 찾고 아이디와 조건을 일치 시키려고 노력합니다.

조건과 조치를 모델링해야합니다. 객체, 함수 포인터, XML ...

좋은 대화 편집기도 편리 할 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.