MUD 스타일의 텍스트 기반 세계에서 레벨 / 객실 구성


12

작은 텍스트 기반 어드벤처 게임을 작성할 생각이지만 기술적 인 관점에서 어떻게 세상을 디자인해야하는지 잘 모르겠습니다.

내 첫 번째 생각은 XML로 다음과 같은 것을 디자인하는 것입니다. 엄청난 양의 XML에 대해 사과하지만, 내가하고있는 일을 완전히 설명하는 것이 중요하다고 생각했습니다.

<level>
    <start>
        <!-- start in kitchen with empty inventory -->
        <room>Kitchen</room>
        <inventory></inventory>
    </start>
    <rooms>
        <room>
            <name>Kitchen</name>
            <description>A small kitchen that looks like it hasn't been used in a while. It has a table in the middle, and there are some cupboards. There is a door to the north, which leads to the garden.</description>
            <!-- IDs of the objects the room contains -->
            <objects>
                <object>Cupboards</object>
                <object>Knife</object>
                <object>Batteries</object>
            </objects>
            </room>
        <room>
            <name>Garden</name>
            <description>The garden is wild and full of prickly bushes. To the north there is a path, which leads into the trees. To the south there is a house.</description>
            <objects>
            </objects>
        </room>
        <room>
            <name>Woods</name>
            <description>The woods are quite dark, with little light bleeding in from the garden. It is eerily quiet.</description>
            <objects>
                <object>Trees01</object>
            </objects>
        </room>
    </rooms>
    <doors>
        <!--
            a door isn't necessarily a door.
            each door has a type, i.e. "There is a <type> leading to..."
            from and to are references the rooms that this door joins.
            direction specifies the direction (N,S,E,W,Up,Down) from <from> to <to>
        -->
        <door>
            <type>door</type>
            <direction>N</direction>
            <from>Kitchen</from>
            <to>Garden</to>
        </door>
        <door>
            <type>path</type>
            <direction>N</direction>
            <from>Garden</type>
            <to>Woods</type>
        </door>
    </doors>
    <variables>
        <!-- variables set by actions -->
        <variable name="cupboard_open">0</variable>
    </variables>
    <objects>
        <!-- definitions for objects -->
        <object>
            <name>Trees01</name>
            <displayName>Trees</displayName>
            <actions>
                <!-- any actions not defined will show the default failure message -->
                <action>
                    <command>EXAMINE</command>
                    <message>The trees are tall and thick. There aren't any low branches, so it'd be difficult to climb them.</message>
                </action>
            </actions>
        </object>
        <object>
            <name>Cupboards</name>
            <displayName>Cupboards</displayName>
            <actions>
                <action>
                    <!-- requirements make the command only work when they are met -->
                    <requirements>
                        <!-- equivilent of "if(cupboard_open == 1)" -->
                        <require operation="equal" value="1">cupboard_open</require>
                    </requirements>
                    <command>EXAMINE</command>
                    <!-- fail message is the message displayed when the requirements aren't met -->
                    <failMessage>The cupboard is closed.</failMessage>
                    <message>The cupboard contains some batteires.</message>
                </action>
                <action>
                    <requirements>
                        <require operation="equal" value="0">cupboard_open</require>
                    </requirements>
                    <command>OPEN</command>
                    <failMessage>The cupboard is already open.</failMessage>
                    <message>You open the cupboard. It contains some batteries.</message>
                    <!-- assigns is a list of operations performed on variables when the action succeeds -->
                    <assigns>
                        <assign operation="set" value="1">cupboard_open</assign>
                    </assigns>
                </action>
                <action>
                    <requirements>
                        <require operation="equal" value="1">cupboard_open</require>
                    </requirements>
                    <command>CLOSE</command>
                    <failMessage>The cupboard is already closed.</failMessage>
                    <message>You closed the cupboard./message>
                    <assigns>
                        <assign operation="set" value="0">cupboard_open</assign>
                    </assigns>
                </action>
            </actions>
        </object>
        <object>
            <name>Batteries</name>
            <displayName>Batteries</displayName>
            <!-- by setting inventory to non-zero, we can put it in our bag -->
            <inventory>1</inventory>
            <actions>
                <action>
                    <requirements>
                        <require operation="equal" value="1">cupboard_open</require>
                    </requirements>
                    <command>GET</command>
                    <!-- failMessage isn't required here, it'll just show the usual "You can't see any <blank>." message -->
                    <message>You picked up the batteries.</message>
                </action>
            </actions>
        </object>
    </objects>
</level>

분명히 이것보다 더 많은 것이 필요합니다. 죽음과 완성뿐만 아니라 사람과 적과의 상호 작용이 필요합니다. XML은 작업하기가 매우 어렵 기 때문에 아마도 일종의 세계 편집기를 만들 것입니다.

이 방법에 오류가 있는지, 더 나은 방법이나 표준 방법이 있는지 알고 싶습니다.


3
개인적으로 XML을 직렬화 형식 이상의 것으로 취급하지 않습니다. XML, JSON, 프로토콜 버퍼, 사용자 정의 이진 형식 등을 사용하여 "어떻게 이것을 디스크에 읽고 쓸 것"이라는 질문을 이해하면 "어떤 데이터를 저장해야합니까?" 게임 요구 사항에 따라 실제로 답변 할 수있는 것입니다.
Tetrad

좋은 지적. 그러나 게임은 이전에 이와 같은 스타일을 사용하는 것을 보았으며 실제로 제한적이었습니다. 이 경우 게임 흐름과 논리가 매우 간단하므로 제대로 작동하여 스크립팅 엔진을 구현하지 않아도됩니다. 나는 주로 고정 구조 (별도의 방, 문, 객체, 정의 파일의 변수)가 실행 가능한지 여부에 관심이 있습니다.
다항식

Tetrad를 반향하지 않으려 고하지만 월드 에디터를 만들 계획이라면 (게임이 매우 짧지 않을 경우 제안 할 것입니다) 파일 형식은 작업 할 때 차이가 없습니다. 방을 하드 코딩하는 것에 대한 편집기.
Mike Cluck

답변:


13

C #에 완전히 익숙하지 않은 경우이 작업을 수행하는 "보다 표준적인"방법은 사람들이 정확하게 이런 종류의 게임을 만들 수 있도록 이미 존재하는 많은 텍스트 모험 제작 도구 중 하나를 사용하는 것입니다. 이 도구는 이미 작동하는 파서, 사망 처리, 저장 / 복원 / 실행 취소, 문자 상호 작용 및 기타 유사한 표준 텍스트 어드벤처 기능을 제공합니다. 현재 가장 널리 사용되는 저작 시스템은 InformTADS입니다 (다수의 다른 시스템도 사용 가능하지만)

Inform은 Infocom 게임에서 사용하는 대부분의 Z Machine 가상 머신 명령어 세트 또는 최신 glulx 가상 머신 명령어 세트 로 컴파일 할 수 있습니다 . 반면에 TADS는 자체 가상 머신 코드로 컴파일됩니다.

대부분의 현대적인 인터랙티브 픽션 인터프리터가 바이너리 유형을 실행할 수 있습니다. (이전에는 ZMachine 게임과 glulx 게임의 TADS 게임에 대한 별도의 인터프리터가 필요했습니다. 그러나 고맙게도 그 시절은 기본적으로 끝났습니다.) 원하는 플랫폼에 대해 Mac / PC / Linux / BSD / iOS / Android / Kindle / browser / 등 그래서 당신은 이미 크로스 플랫폼을 잘 관리하고 있습니다.

대부분의 플랫폼에서 현재 권장되는 인터프리터는 Gargoyle 이지만 다른 많은 인터프리터가 있으므로 자유롭게 실험하십시오.

Inform (특히 최신 버전)으로 코딩하는 것은 엔지니어보다는 저자에게 더 많은 마케팅을하므로 구문이 이상하고 거의 대화처럼 보이기 때문에 익숙해지는 데 약간의 시간이 걸립니다. Inform 7의 구문에서 예제는 다음과 같습니다.

"My Game" by Polynomial

Kitchen is a room. "A small kitchen that looks like it hasn't been used in a 
while. It has a table in the middle, and there are some cupboards. There is a 
door to the north, which leads to the garden."

In the Kitchen is a knife and some cupboards.  The cupboards are fixed in 
place and closed and openable.  In the cupboards are some batteries.

Garden is north of Kitchen. "The garden is wild and full of prickly bushes. 
To the north there is a path, which leads into the trees. To the south there 
is a house."

Woods is north of Garden.  "The woods are quite dark, with little light bleeding 
in from the garden. It is eerily quiet."  

Trees are scenery in the Woods.  "The trees are tall and thick. There aren't any 
low branches, so it'd be difficult to climb them."

TADS는 전통적인 프로그래밍 언어와 비슷하지만 TADS의 동일한 게임은 다음과 같습니다.

#charset "us-ascii"
#include <adv3.h>
gameMain: GameMainDef
    initialPlayerChar = me
;
versionInfo: GameID
    name = 'My Game'
    byline = 'by Polynomial'
;
startroom: Room                  /* we could call this anything we liked */ 
    roomName = 'Kitchen'         /* the displayed "name" of the room */ 
    desc = "A small kitchen that looks like it hasn't been used 
            in a while. It has a table in the middle, and there 
            are some cupboards. There is a door to the north, 
            which leads to the garden." 
    north = garden         /* where 'north' will take us */ 
; 

+me: Actor
; 

cupboards: OpenableContainer
    vocabWords = 'cupboard/cupboards' 
    name = 'cupboards' 
    isPlural = true
    location = startroom 
; 
battery: Thing
    name = 'battery'
    location = cupboards
;
knife: Thing
    name = 'knife'
    location = startroom
;
garden: Room
    roomName = 'Garden'
    desc = "The garden is wild and full of prickly bushes. To the 
            north there is a path, which leads into the trees. To 
            the south there is a house." 
    north = woods
    south = startroom
; 
woods: Room
    roomName = 'Woods'
    desc = "The woods are quite dark, with little light bleeding 
            in from the garden. It is eerily quiet."
    south = garden
;
trees: Decoration
    desc = "The trees are tall and thick. There aren't any low 
            branches, so it'd be difficult to climb them."
    location = woods
;

두 시스템 모두 무료로 사용할 수 있으며 매우 자주 사용되며 많은 양의 튜토리얼 문서 (위의 링크에서 제공)가 있으므로 두 시스템을 모두 확인하고 원하는 것을 선택하는 것이 좋습니다.

두 시스템은 약간 다른 표준 동작을 갖습니다 (둘 다 수정 될 수 있음). 다음은 정보 소스에서 컴파일 된 게임의 스크린 샷입니다.

스크린 샷 알림

다음은 Tads 소스에서 컴파일 한 게임 중 하나입니다 (터미널 내부 – 타이포그래피가 이보다 훨씬 좋을 수 있음).

TADS3 스크린 샷

흥미로운 점 : TADS는 기본적으로 오른쪽 상단에 '점수'표시를 제공하지만 (끄는 기능은 있지만) 정보는 표시하지 않습니다 (그러나 설정할 수는 있습니다). 기본적으로 룸 설명에서 항목의 열림 / 닫힘 상태를 알려줍니다. Tads는 그렇지 않습니다. Tads는 플레이어 명령을 수행하기 위해 (당신이 지시하지 않는 한) Inform이 지시하지 않는 경향이있는 (당신이 지시하지 않는 한) 자동적으로 당신을 위해 행동을 취하는 경향이 있습니다.

둘 중 하나를 사용하여 모든 종류의 게임을 구성 할 수 있지만 (둘 다 고도로 구성 가능하기 때문에) Inform은 TADS가 더 구조화 된 현대적인 대화 형 소설 (보통 퍼즐이 적고 스타일이 더 많음)을 생성하도록보다 체계화되어 있습니다. 구식 텍스트 어드벤처를 만들기 위해 (종종 퍼즐에 중점을두고 게임 세계 모델의 메커니즘을 엄격하게 정의)


이것은 매우 시원하고 유익하지만 imo는 질문에 대답하지 않습니다. 나는 기본적 으로이 똑같은 질문을 할 것입니다. 이 XML이 유효한 접근인지 아닌지 또는 함정이나 약점이 있는지에 대해 더 알고 싶습니다.
DLeh

1
@DLeh 문제는 "이 방법에 오류가 있는지, 더 나은 방법이 있는지 또는 더 표준적인 방법이 있는지 알고 싶습니다."라는 대답은 보다 우수 하고 표준적인 방법을 제공합니다. 하고 있어요 .
Trevor Powell

그러나 "함정과 약점"에 대해 물었으므로 정보 구현의 길이는 19 줄입니다. TADS 예제는 40 줄입니다. XML 구현에는 126 줄이 필요합니다 (80 행으로 줄 바꿈되고 정보 및 TADS 구현 방식과 같이 가독성을 위해 공백이 포함 된 경우 더 길어질 수 있음).
Trevor Powell

훨씬 짧을뿐만 아니라 Inform 및 TADS 예제는 더 많은 기능을 지원합니다. 예를 들어 두 가지 모두 나이프를 찬장에 넣을 수 있으며 XML 버전에서는 전혀 지원되지 않습니다.
Trevor Powell

1
XML 버전이 찬장의 내용을 찬장의 설명으로 굽고 있다는 점도 주목할 가치가있다. 즉, (열린) 찬장을 열거 나 볼 때 인쇄 할 내용에 대한 하드 코딩 된 메시지가 있는데, 이는 내부에 배터리가 있음을 알려줍니다. 그러나 플레이어가 이미 배터리를 가져간 경우 어떻게해야합니까? XML 버전은 내부에 배터리가 있음을 알려주며 (표시 할 수있는 유일한 문자열이기 때문에) Inform 및 TADS 버전은 찬장이 비어 있음을 알려줍니다.
Trevor Powell
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.