Sắp xếp các cấp / phòng trong thế giới dựa trên văn bản theo kiểu MUD


12

Tôi đang nghĩ đến việc viết một trò chơi phiêu lưu dựa trên văn bản nhỏ, nhưng tôi không chắc chắn làm thế nào tôi nên thiết kế thế giới từ quan điểm kỹ thuật.

Suy nghĩ đầu tiên của tôi là làm điều đó bằng XML, được thiết kế giống như sau. Xin lỗi về đống XML khổng lồ, nhưng tôi cảm thấy điều quan trọng là phải giải thích đầy đủ những gì tôi đang làm.

<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>

Rõ ràng là cần phải có nhiều hơn thế. Tương tác với người và kẻ thù cũng như cái chết và hoàn thành là những bổ sung cần thiết. Vì XML khá khó để làm việc với, nên tôi có thể tạo một số trình soạn thảo thế giới.

Tôi muốn biết liệu phương pháp này có bất kỳ nhược điểm nào không, và nếu có cách "tốt hơn" hoặc tiêu chuẩn hơn để thực hiện.


3
Cá nhân tôi sẽ không coi XML là bất cứ thứ gì ngoài định dạng tuần tự hóa. Nếu bạn trừu tượng hóa câu hỏi "bằng cách nào đó tôi sẽ đọc và ghi nó vào đĩa" (sử dụng một cái gì đó như XML, JSON, bộ đệm giao thức, định dạng nhị phân tùy chỉnh, bất cứ điều gì), thì câu hỏi sẽ trở thành "tôi cần lưu trữ dữ liệu nào ", Đó là điều mà chỉ bạn thực sự có thể trả lời tùy thuộc vào yêu cầu trò chơi của bạn là gì.
Tetrad

Điểm tốt. Tuy nhiên, tôi đã thấy các trò chơi sử dụng các kiểu như thế này trước đây và chúng hóa ra rất hạn chế. Tuy nhiên, trong trường hợp này, luồng trò chơi và logic khá đơn giản, vì vậy nó có thể hoạt động tốt và giúp tôi tránh thực hiện một công cụ viết kịch bản. Tôi chủ yếu quan tâm đến việc liệu một cấu trúc cố định như vậy (các phòng, cửa, đối tượng, biến số riêng biệt trong một tệp định nghĩa ở đâu đó) có khả thi hay không.
Đa thức

Cố gắng không lặp lại Tetrad nhưng nếu bạn dự định làm một biên tập viên thế giới (mà tôi sẽ đề xuất trừ khi trò chơi sẽ rất ngắn) thì định dạng tệp của bạn sẽ không có gì khác biệt vì bạn sẽ làm việc với nó trong các biên tập viên, so với mã hóa cứng các phòng.
Mike Cluck

Câu trả lời:


13

Nếu bạn chưa hoàn toàn kết hôn với C #, thì cách làm "chuẩn hơn" này là sử dụng một trong nhiều công cụ tạo phiêu lưu văn bản đã tồn tại để giúp mọi người tạo ra chính xác loại trò chơi này. Các công cụ này cung cấp cho bạn một trình phân tích cú pháp đã hoạt động, xử lý cho cái chết, lưu / khôi phục / hoàn tác, tương tác ký tự và các bit tiêu chuẩn tương tự khác của chức năng phiêu lưu văn bản. Ngay bây giờ, các hệ thống tác giả phổ biến nhất là Thông tinTADS (mặc dù cũng có một nửa tá các hệ thống khác có sẵn)

Thông tin có thể biên dịch thành hầu hết các bộ hướng dẫn máy ảo Z Machine được sử dụng bởi các trò chơi Infocom hoặc vào các bộ hướng dẫn máy ảo glulx gần đây. TADS, mặt khác, biên dịch thành mã máy ảo của riêng nó.

Hầu hết các loại phiên dịch nhị phân đều có thể được điều hành bởi hầu hết các thông dịch viên tiểu thuyết tương tác hiện đại (ngày xưa, bạn thường cần các thông dịch viên riêng cho các trò chơi TADS từ các trò chơi ZMachine từ các trò chơi glulx. về bất kỳ nền tảng nào bạn muốn; Mac / PC / Linux / BSD / iOS / Android / Kindle / trình duyệt / v.v. Vì vậy, bạn đã có nền tảng chéo tốt và thực sự quan tâm.

Đối với hầu hết các nền tảng, trình thông dịch hiện được đề xuất là Gargoyle , nhưng có rất nhiều nền tảng khác, vì vậy hãy thoải mái thử nghiệm.

Mã hóa trong Thông tin (đặc biệt là phiên bản mới nhất) cần một chút để làm quen, vì nó tiếp thị nhiều hơn cho các tác giả hơn là đối với các kỹ sư, và do đó cú pháp của nó trông kỳ lạ và gần như là trò chuyện. Trong cú pháp của Inform 7, ví dụ của bạn sẽ như thế này:

"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."

Trong khi đó TADS trông giống ngôn ngữ lập trình truyền thống hơn, và trò chơi tương tự trong TADS trông như thế này:

#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
;

Cả hai hệ thống đều có sẵn miễn phí, được sử dụng rất thường xuyên và có số lượng lớn tài liệu hướng dẫn (có sẵn từ các liên kết tôi đã đưa ra ở trên), vì vậy, đáng để kiểm tra cả hai và chọn tài liệu bạn thích.

Lưu ý rằng hai hệ thống có các hành vi tiêu chuẩn tinh tế khác nhau (mặc dù cả hai có thể được sửa đổi). Dưới đây là ảnh chụp màn hình của trò chơi đang được chơi, được tổng hợp từ nguồn Thông tin:

Thông báo ảnh chụp màn hình

Và đây là một trong những trò chơi đang được chơi (bên trong một thiết bị đầu cuối - kiểu chữ có thể đẹp hơn cái này rất nhiều), như được tổng hợp từ nguồn Tads:

Ảnh chụp màn hình TADS3

Các điểm thú vị cần lưu ý: TADS cung cấp cho bạn màn hình 'điểm số ở trên cùng bên phải theo mặc định (nhưng bạn có thể tắt nó đi), trong khi Inform không (nhưng bạn có thể bật nó lên). Thông báo theo mặc định sẽ cho bạn biết trạng thái mở / đóng của các mục trong mô tả phòng, Tads sẽ không. Tads có xu hướng tự động thực hiện các hành động cho bạn để thực hiện các lệnh của người chơi (trừ khi bạn nói không), trong đó Inform có xu hướng không (trừ khi bạn nói với nó).

Một trong hai có thể được sử dụng để tạo ra bất kỳ loại trò chơi nào (vì cả hai đều có cấu hình cao), nhưng Inform có cấu trúc hơn để tạo ra tiểu thuyết tương tác theo phong cách hiện đại (thường có các câu đố tối thiểu và cách kể chuyện nhiều hơn), trong đó TADS có cấu trúc chặt chẽ hơn hướng tới việc tạo ra những cuộc phiêu lưu văn bản kiểu cũ (thường tập trung mạnh vào các câu đố và xác định chặt chẽ các cơ chế của mô hình thế giới của trò chơi).


Điều này rất tuyệt và nhiều thông tin, nhưng imo không trả lời câu hỏi. Về cơ bản, tôi sẽ hỏi chính xác câu hỏi này. Tôi muốn biết thêm về việc liệu XML này có phải là một cách tiếp cận hợp lệ hay không nếu có bất kỳ cạm bẫy hay điểm yếu nào.
DLeh

1
@DLeh Câu hỏi là "Tôi muốn biết liệu phương pháp này có bất kỳ nhược điểm nào không và liệu có cách nào" tốt hơn "hay tiêu chuẩn hơn không" Câu trả lời này cung cấp cách thức tốt hơn và chuẩn hơn làm-nó .
Trevor Powell

Nhưng vì bạn đã hỏi về "cạm bẫy và điểm yếu": Việc triển khai Thông tin dài 19 dòng. Ví dụ TADS dài 40 dòng. Việc triển khai XML yêu cầu 126 dòng (và sẽ còn dài hơn nếu nó được bao bọc bằng 80 cột và có khoảng trắng cho mức độ dễ đọc, theo cách mà các triển khai Thông tin và TADS thực hiện).
Trevor Powell

Ngoài việc ngắn hơn nhiều, các ví dụ về Thông tin và TADS còn hỗ trợ nhiều tính năng hơn. Ví dụ: trong cả hai, bạn có thể đặt con dao vào tủ, không được hỗ trợ trong phiên bản XML.
Trevor Powell

1
Cũng đáng lưu ý rằng phiên bản XML đang nướng nội dung của tủ vào mô tả của tủ. Đó là, có một thông điệp được mã hóa cứng để in những gì khi mở hoặc nhìn vào tủ (mở), cho bạn biết rằng có pin bên trong. Nhưng nếu người chơi đã lấy pin thì sao? Phiên bản XML sẽ cho bạn biết rằng có pin bên trong (vì đó là chuỗi duy nhất có sẵn để hiển thị), trong khi phiên bản Thông báo và TADS sẽ cho bạn biết rằng các tủ trống.
Trevor Powell
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.