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


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 , OrConditionNotCondition을 사용하여 여러 조건을 결합 할 수 있습니다 . 일반적으로 퀘스트 완료시 수행해야 할 작업이 많으므로 MultipleActions 클래스도 있습니다.

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


5

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


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.