การจัดระเบียบระดับ / ห้องในโลกตามข้อความสไตล์โคลน


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 แต่ถ้าคุณวางแผนที่จะสร้าง World Editor (ซึ่งฉันอยากจะแนะนำนอกจากว่าเกมจะสั้นมาก) รูปแบบไฟล์ของคุณจะไม่สร้างความแตกต่างใด ๆ เนื่องจากคุณจะทำงานด้วย บรรณาธิการกับการเข้ารหัสห้องอย่างหนัก
Mike Cluck

คำตอบ:


13

หากคุณยังไม่ได้แต่งงานกับ C # อย่างสมบูรณ์วิธีที่ "มาตรฐานมากกว่า" ในการทำเช่นนี้คือการใช้หนึ่งในเครื่องมือสร้างข้อความผจญภัยที่มีอยู่แล้วเพื่อช่วยให้ผู้คนสร้างเกมประเภทนี้ขึ้นมา เครื่องมือเหล่านี้ให้ตัวแยกวิเคราะห์ที่ใช้งานได้อยู่แล้วจัดการกับความตายบันทึก / กู้คืน / เลิกทำการโต้ตอบกับตัวละครและฟังก์ชั่นการผจญภัยข้อความอื่น ๆ ที่คล้ายกัน ตอนนี้ระบบการเขียนที่ได้รับความนิยมมากที่สุดคือแจ้งและTADS (แม้ว่าจะมีอีกครึ่งโหลที่มีให้ใช้เช่นกัน)

ข้อมูลสามารถรวบรวมลงในชุดคำสั่งเครื่องเสมือนZ Machineส่วนใหญ่ที่ใช้โดยเกม Infocom หรือเป็นชุดคำสั่งเครื่องเสมือน glulx รุ่นล่าสุด ในทางกลับกัน TADS จะรวบรวมลงในรหัสเครื่องเสมือนของตัวเอง

(ในสมัยก่อนคุณจำเป็นต้องใช้ล่ามแยกต่างหากสำหรับเกม TADS จากเกม ZMachine จากเกม glulx แต่โชคดีที่วันเหล่านั้นอยู่ที่นี่แล้ว) ล่ามพร้อมใช้งานเพียงแค่ เกี่ยวกับแพลตฟอร์มใด ๆ ที่คุณต้องการ Mac / PC / Linux / BSD / iOS / Android / จุด / เบราว์เซอร์ / ฯลฯ ดังนั้นคุณจะได้ข้ามแพลตฟอร์มได้ดีและได้รับการดูแลอย่างแท้จริง

สำหรับแพลตฟอร์มส่วนใหญ่ล่ามที่แนะนำในปัจจุบันคือการ์กอยล์แต่มีคนอื่นมากมายดังนั้นอย่าลังเลที่จะทดสอบ

การเขียนโค้ดใน 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 มีโครงสร้างที่มากขึ้นในการสร้างนิยายเชิงโต้ตอบที่ทันสมัยสไตล์ (มักจะมีปริศนาน้อยที่สุด ไปสู่การผลิตการผจญภัยข้อความแบบเก่า (มักเน้นไปที่ปริศนาและการกำหนดกลไกของโมเดลโลกของเกมอย่างจริงจัง)


มันเจ๋งมากและให้ข้อมูล แต่ imo ไม่ตอบคำถาม ฉันจะถามคำถามเดียวกันนี้โดยทั่วไป ฉันต้องการทราบเพิ่มเติมเกี่ยวกับว่า XML นี้เป็นแนวทางที่ถูกต้องหรือไม่หากมีข้อผิดพลาดหรือจุดอ่อนใด ๆ
DLeh

1
@DLeh คำถามคือ "ฉันต้องการทราบว่าวิธีการนี้มีข้อผิดพลาดหรือไม่และหากมี" ดีกว่า "หรือวิธีการทำมาตรฐานมากกว่า" คำตอบนี้ให้ดีขึ้นและมากขึ้นมาตรฐานวิธีการของ - ทำมัน
Trevor Powell

แต่เนื่องจากคุณถามเกี่ยวกับ "หลุมพรางและจุดอ่อน": การใช้งานข้อมูลมีความยาว 19 บรรทัด ตัวอย่าง TADS มีความยาว 40 บรรทัด การนำ XML มาใช้นั้นต้องใช้ 126 บรรทัด (และจะนานกว่านี้ถ้ามันเป็นคำที่ 80 คอลัมน์และมีช่องว่างสำหรับความชัดเจนวิธีการที่แอปพลิเคชันแจ้งและ TADS ทำได้)
Trevor Powell

นอกจากจะสั้นลงมากตัวอย่าง Inform และ TADS ยังรองรับคุณสมบัติเพิ่มเติม ตัวอย่างเช่นในทั้งคู่คุณสามารถวางมีดลงในตู้ซึ่งไม่รองรับเลยในรุ่น XML
Trevor Powell

1
นอกจากนี้ยังเป็นที่น่าสังเกตว่ารุ่น XML กำลังอบเนื้อหาของตู้ในคำอธิบายของตู้ นั่นคือมีข้อความ hardcoded สำหรับสิ่งที่จะพิมพ์เมื่อเปิดหรือดูที่ตู้ (เปิด) ซึ่งจะบอกคุณว่ามีแบตเตอรี่อยู่ภายใน แต่ถ้าหากผู้เล่นได้นำแบตเตอรี่ไปแล้ว? เวอร์ชัน XML จะบอกคุณว่ามีแบตเตอรี่อยู่ภายใน (เพราะเป็นเพียงสายอักขระที่มีให้แสดง) ในขณะที่รุ่นแจ้งและ TADS จะบอกคุณว่าตู้ว่างเปล่า
Trevor Powell
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.