MUD tarzı metin tabanlı bir dünyada düzeyleri / odaları düzenleme


12

Küçük bir metin tabanlı macera oyunu yazmayı düşünüyorum, ancak dünyayı teknik açıdan nasıl tasarlamam gerektiğinden özellikle emin değilim.

İlk düşüncem bunu XML'de yapmak, aşağıdaki gibi bir şey tasarlamak. Büyük XML yığını için özür dilerim, ama ne yaptığımı tam olarak açıklamanın önemli olduğunu hissettim.

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

Açıkçası bundan daha fazlası olmalı. İnsanlarla ve düşmanlarla etkileşim, ölüm ve tamamlanma gerekli eklemelerdir. XML ile çalışmak oldukça zor olduğundan, muhtemelen bir tür dünya editörü oluşturacağım.

Bu yöntemin herhangi bir çöküşü olup olmadığını ve bunu yapmanın "daha iyi" veya daha standart bir yolu olup olmadığını bilmek istiyorum.


3
Şahsen ben XML'i serileştirme biçiminden başka bir şey olarak görmezdim. "Bir şekilde bunu okuyacağım ve diske yazacağım" sorusunu (XML, JSON, protokol arabellekleri, özel ikili biçim, ne olursa olsun) kullanarak soyutlarsanız, soru "saklamak için hangi veriye ihtiyacım var?" "Bu, oyun gereksinimlerinizin ne olduğuna bağlı olarak yalnızca gerçekten yanıtlayabileceğiniz bir şeydir.
Tetrad

İyi bir nokta. Ancak, oyunların daha önce böyle stilleri kullandığını gördüm ve gerçekten kısıtlayıcı oldukları ortaya çıktı. Bu durumda, oyun akışı ve mantığı oldukça basittir, bu yüzden iyi çalışabilir ve bir komut dosyası motoru uygulamaktan beni kurtarabilir. Öncelikle böyle bir sabit yapının (ayrı odalar, kapılar, nesneler, bir yerde bir tanım dosyasındaki değişkenler) uygulanabilir olup olmadığı ile ilgileniyorum.
Polinom

Tetrad'ı yankılamamaya çalışıyorum, ancak bir dünya editörü yapmayı planlıyorsanız (oyun çok kısa olmayacaksa önereceğim), dosya formatınız üzerinde çalışacağınız için herhangi bir fark yaratmaz. editör, sert kodlama odaları karşı.
Mike Cluck

Yanıtlar:


13

Tamamen C # ile evlenmediyseniz, bunu yapmanın "daha standart" yolu, insanların tam olarak bu tür bir oyun yapmasına yardımcı olmak için zaten var olan birçok metin macera oluşturma aracından birini kullanmaktır. Bu araçlar, zaten çalışan bir ayrıştırıcı, ölümle ilgilenme, kaydetme / geri yükleme / geri alma, karakter etkileşimi ve diğer benzer metin macera işlevselliği standart bitlerini verir. Şu anda, en popüler yazma sistemleri Inform ve TADS'dir (yarım düzine başka kullanılabilir olsa da)

Inform, Infocom oyunları tarafından kullanılan Z Makinesi sanal makine talimat setlerinin çoğuna veya daha yeni glulx sanal makine talimat setlerine derlenebilir. TADS ise kendi sanal makine kodunu derliyor.

İkili tiplerden herhangi biri modern interaktif kurgu tercümanlarının çoğu tarafından çalıştırılabilir (eski günlerde, TADS oyunları için genellikle glulx oyunlarından ZMachine oyunlarından ayrı tercümanlara ihtiyaç duyuyordunuz. istediğiniz herhangi bir platform hakkında; Mac / PC / Linux / BSD / iOS / Android / Kindle / tarayıcı / vb. Yani zaten platformlar arası iyi ve gerçekten halledilir.

Çoğu platform için, şu anda önerilen yorumlayıcı Gargoyle'dir , ancak başka pek çok şey vardır, bu yüzden denemekten çekinmeyin.

Inform (özellikle en son sürüm) 'de kodlama alışmak için biraz zaman alır, çünkü kendini yazarlara karşı mühendislere göre daha fazla pazarlar ve böylece sözdizimi garip ve neredeyse konuşma gibi görünür. Inform 7'nin sözdiziminde, örneğiniz şöyle görünür:

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

Oysa TADS daha çok geleneksel bir programlama diline benziyor ve TADS'deki aynı oyun şöyle:

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

Her iki sistem de serbestçe kullanılabilir, çok sık kullanılır ve çok sayıda öğretici belgeye sahiptir (yukarıda verdiğim bağlantılardan edinilebilir), bu yüzden her ikisini de kontrol etmeye ve tercih ettiğinizi seçmeye değer.

İki sistemin de farklı standart davranışlara sahip olduğuna dikkat edin (her ikisi de değiştirilebilir). Inform kaynağından derlendiği gibi, oynanan oyunun ekran görüntüsü:

Ekran görüntüsünü bildir

Ve Tads kaynağından derlendiği gibi, oyundan bir oyun (bir terminal içinde - tipografi bundan çok daha güzel olabilir):

TADS3 ekran görüntüsü

Dikkat edilmesi gereken ilginç noktalar: TADS, varsayılan olarak sağ üstte bir 'puan' ekranı verir (ancak kapatabilirsiniz), ancak Inform bunu yapmaz (ancak açabilirsiniz). Inform varsayılan olarak oda açıklamasında öğelerin açık / kapalı durumlarını söyleyecektir, Tads yapmaz. Tads, Inform'in yapmadığı (siz söylemediğiniz sürece) oyuncu komutlarını (siz söylemezseniz) gerçekleştirmek için sizin için otomatik olarak harekete geçme eğilimindedir.

Her ikisi de herhangi bir oyun yapmak için kullanılabilir (ikisi de son derece yapılandırılabilir olduğu için), ancak Inform, TADS'nin daha yapılandırılmış olduğu modern tarzda etkileşimli kurgu (genellikle en az bulmaca ve daha fazla anlatımla) üretmek için daha yapılandırılmıştır. eski tarz metin maceraları üretmeye doğru (genellikle bulmacalara odaklanmak ve oyunun dünya modelinin mekaniklerini titizlikle tanımlamak).


bu çok havalı ve bilgilendirici, ancak imo soruyu cevaplamıyor. Temelde aynı soruyu soracaktım. Bu XML'in geçerli bir yaklaşım olup olmadığı veya sahip olacağı herhangi bir tuzak veya zayıflık olup olmadığı hakkında daha fazla bilgi edinmek istiyorum.
DLeh

1
@DLeh Soru "Bu yöntemin herhangi bir çöküşü olup olmadığını ve bunu yapmanın" daha iyi "ya da daha standart bir yolu olup olmadığını bilmek istiyorum" idi Bu yanıt daha iyi ve daha standart bir yol yapıyor .
Trevor Powell

Ama "tuzaklar ve zayıflıklar" hakkında soru sorduğunuz için: Inform uygulaması 19 satır uzunluğunda. TADS örneği 40 satır uzunluğundadır. XML uygulaması 126 satır gerektirir (ve 80 sütuna sözcükle sarılmışsa ve Inform ve TADS uygulamalarının yaptığı gibi okunaklılık için boşluk varsa daha da uzun olurdu).
Trevor Powell

Çok daha kısa olmasının yanı sıra, Inform ve TADS örnekleri de daha fazla özelliği desteklemektedir. Örneğin, her ikisinde de bıçağı XML sürümünde hiç desteklenmeyen dolaplara koyabilirsiniz.
Trevor Powell

1
XML sürümünün dolapların içeriğini dolapların açıklamasına dönüştürdüğünü de belirtmek gerekir. Yani, (açık) dolapları açarken veya bakarken ne yazdıracağınız için içeride pil olduğunu söyleyen sabit bir mesaj var. Peki ya oyuncu zaten pilleri almışsa? XML sürümü içeride piller olduğunu söyleyecektir (çünkü gösterilebilecek tek dize budur), Inform ve TADS sürümleri ise dolapların boş olduğunu söyleyecektir.
Trevor Powell
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.