Schreiben eines Textspiels in Python / Ren'Py

Wie erstelle ich ein Textspiel? Ja was auch immer Wie erstelle ich ein plattformübergreifendes Textspiel in russischer Sprache mit Illustrationen, Sound, Arbeitssicherungen, ohne Probleme mit dem kyrillischen Alphabet und mit jeglichem Gameplay? Ja, und in Ihrer Freizeit nicht von Ihrem Hauptberuf aufblicken? Das ist schon interessanter und in der Tat - ganz einfach. Interessiert bitte unter kat.

Bild

Vor ungefähr einem Jahr haben mein Freund und ich beschlossen, ein kleines Textspiel im Stil von Sunless Sea für 80 Tage zu machen: über Navigation, Handel, Erkundung seltsamer Siedlungen und Gespräche mit seltsamen Persönlichkeiten. Es hätte eine Religion oder vielmehr mehrere geben sollen, die Hauptfigur würde nicht als Retter, Held des Landes und berühmter Seemann gesehen werden, sondern als mäßig unglücklicher Unternehmer / Abenteurer, der sich um niemanden kümmert, und die modische Wahl zwischen kleinerem und größerem Übel durch eine Wahl zwischen Gutem ersetzen und gut: kein Grimdark für Grimdark. Ziemlich schnell waren die Hauptfraktionen und Charaktere, große Häfen, die politische Situation und eine Menge süßer Kleinigkeiten wie das Speerfischen auf Tintenfische (auf der KDPV abgebildet) und die geniale Idee, fast alle Charaktere mit ungarischen Namen zu versehen, erfunden die exotischer klingen als die üblichen europäischen und implizite Sympathien hervorrufen. Im Allgemeinen gab es viele Holzhäuser.

Zu dieser Zeit hatten wir einen Autor und einen Programmierer (dh mich) im Team. Die Anforderungen im vorherigen Absatz sind eher auf die Einstellung und den Geist des Spiels bezogen, daher musste mein Freund sie erfüllen, und vor mir gab es Fragen zum Spieldesign und zur Funktionsweise der Engine. Erstens verbringt der Spieler die meiste Zeit damit, den Text zu lesen und die Aktionen der Hauptfigur auszuwählen. Dazu benötigen Sie nur eine anständige Typografie und die Fähigkeit, Skripte mit Menüs, Optionen und Variablen zu schreiben. Bald schloss sich der Künstler an, sodass ich auch über die Illustrationen nachdenken musste. Zweitens geht es bei dem Spiel um Forschung und Handel. Daher muss der Spieler an einer für ihn zugänglichen Stelle Informationen über die gesammelten Gerüchte und gekauften Waren speichern (und in jeder Hinsicht verarbeiten). Und schließlich benötigen Sie im Navigationsspiel eine Karte und die Fähigkeit, darin zu navigieren. Nur der Befehl, „zu den Tataren zu schwimmen und den Geschichten der Seepferdchen zu lauschen“, entspricht eindeutig nicht dem Geist des Projekts. Dies bedeutet, dass die Engine auch mindestens einfache Minispiele unterstützen muss und sich nicht nur auf die Anzeige von Text und die Berechnung von Spielvariablen beschränkt.

Warum Ren'Py?


Ich muss sofort sagen, dass wir nicht einmal versucht haben, die Engine von Grund auf neu zu schreiben: Radfahren macht an sich schon Spaß, ist aber ineffektiv, wenn das Ziel darin besteht, das Spiel vor dem Rücktritt freizugeben. Auch haben wir den Interactive Fiction-Parser nicht berücksichtigt: Er hat ein sehr kleines Publikum auf Englisch, und auf Russisch könnte unser Projekt, wenn es ein Parser wäre, bestenfalls mehrere hundert Leute interessieren. Aber ich möchte, wenn Sie kein Geld verdienen, zumindest grünes Licht geben und einen guten Ruf erlangen. Glücklicherweise sind die meisten der heutigen englischsprachigen Textspielentwickler vor wenigen Jahren von gemeinnützigen Hobbyprojekten zu professionellen Spieleentwicklern übergegangen. Daher sind die Hauptmaschinen entweder Open Source oder auf jeden Fall kostenlos. Mal sehen, was uns geboten wird.

Die erste Option, die mir einfiel, warStorynexus von Failbetter-Spielen , Entwicklern von Fallen London und Sunless Sea. Projekte darauf werden über den Browser bearbeitet, von Failbetter gehostet und sind für Spieler über den Browser zugänglich. Monetarisierungsmöglichkeiten wurden seit letztem Jahr beseitigt. Der Hauptnachteil besteht jedoch nicht darin, dass die meisten Ereignisse in Fallen London durch Karten dargestellt werden, die aus dem Stapel fallen, und ein Spiel auf Storynexus zu erstellen, das diese Metapher nicht verwendet, ist keine triviale Aufgabe. Auf jeden Fall ist es sehr riskant, Ihr Projekt eng an einen Drittanbieter-Server mit geschlossenem Quellcode zu binden, der theoretisch sogar jederzeit nicht mehr funktionieren kann.

Es gibt zwei weitere gute proprietäre Engines für Choose Your Own Adventure, also Spiele unseres Typs: ChoiceScript und Inklewriter. Beide versprechen exzellente Typografie, einfache Entwicklung (browserbasierter Editor für Inklewriter, Skriptsprache für ChoiceScript) und die Möglichkeit der kommerziellen Veröffentlichung. Leider können Sie mit beiden nur reine CYOA-Aktionen ausführen: Es gibt keine Möglichkeit, dem Spiel etwas anderes als den eigentlichen Text, das Menü und die Abbildungen hinzuzufügen. Der aufmerksame Leser wird ausrufen: „Aber wie? In 80 Tagen gab es eine ziemlich komplizierte Benutzeroberfläche für Inventar und Reisen, oder? Und in Zauberei! Ich habe die Schlacht auf jeden Fall gesehen! “Leider wurden diese Systeme von Inkle Studios für bestimmte Spiele entwickelt, und im Editor gibt es weder sie noch zumindest die Möglichkeit, sich selbst zu verbessern. Aus dem gleichen Grunde (und auch , weil er, äh , Art ) gaben wir auf Bindfäden .

Die einzige Option, die zu uns passte, war Ren'Py. Hierbei handelt es sich um eine kostenlose Open-Source-Open-Source-Engine für Bildromane (auf deren Basis beispielsweise „Endless Summer“ und „Katawa shoujo“ erstellt wurden), die für unsere Aufgaben recht einfach zu konfigurieren ist. Die Spiele sind plattformübergreifend: Zum Erstellen einer Distribution für Win / Mac / Linux muss nur eine einzige Taste gedrückt werden, und Sie müssen nicht einmal das Ziel-Betriebssystem zur Hand haben. Android und iOS werden ebenfalls angekündigt, und es gibt Ren'Py-Versionen für mobile Achsen, aber wir selbst zielen noch nicht auf den mobilen Markt ab und können nicht über die Entwicklung dafür sprechen. Darüber hinaus hat Ren'Py eine sehr freundliche und lebendige Community in Russisch und Englisch .

Das einfachste Skript auf Ren'Py


Ren'Py ist in Python 2.7 + Pygame geschrieben und hat ein eigenes DSL. In dieser Sprache wird das Skript aufgrund von Befehlen wie "Show bg_city_night_53.png as a background without animation" oder "Speak a replica" This ... SEMPAJ !!! "im Namen des Zeichens nyasha1" in einem imperativen Stil geschrieben. Zweitens ist eine Teilmenge dieser Sprache die Bildschirmsprache, in der Sie Bildschirme in einem deklarativen Stil aus einem begrenzten Satz von Anzeigeelementen (d. H. Widgets: Schaltflächen, Bilder, Textfelder usw.) zusammenstellen und deren Funktionalität konfigurieren können. Wenn die integrierten Funktionen nicht ausreichen, können Sie mit Python eigene hinzufügen. Wir werden uns im nächsten Artikel damit befassen, aber im Moment werden wir uns mit dem Skript befassen.

Das Skript in Ren'Py besteht aus einer Folge von Repliken, Aktionen mit Bildschirmen und Player-Eingaben. Über Bildschirme und Eingaben etwas weniger, aber zunächst werden wir uns mit den Zeichen befassen. Im visuellen Roman werden sie wie folgt erstellt (Code aus dem offiziellen Tutorial, mit geringfügigen Änderungen):

define m = Character('Me', color="#c8c8ff")
define s = Character('Sylvie', color="#c8ffc8")
image sylvie smile = "sylvie_smile.png"
label start
    m "Um... will you..."
    m "Will you be my artist for a visual novel?"
    show sylvie smile
    s "Sure, but what is a \"visual novel?\""

Es wurden zwei Charaktere geschaffen: der Protagonist und Sylvie, die beide hellblau in das Standardfenster am unteren Bildschirmrand schreiben. Sylvie hat auch ein Porträt, das auf dem Bildschirm erscheint, bevor sie zu sprechen beginnt. Es sieht so aus:

Bild

Wenn wir einen visuellen Roman erschaffen würden, würden wir im gleichen Sinne weitermachen, aber wir werden keine Porträts von Charakteren und sogar ein paar Dutzend Illustrationen für das ganze Spiel zeigen. Darüber hinaus ist der Großteil des Textes keine direkte Rede der Zeichen, so dass es unlogisch wäre, ihn an einen von ihnen anzuhängen. Besser einen virtuellen Geschichtenerzähler erstellen:

define narrator = Character(None, kind = nvl, what_color="#000000", size = 12)

Sein Name ist Erzähler; Dies ist ein spezieller Name, der den gesamten Text angibt, der eindeutig nicht anderen Zeichen zugeordnet ist (genau genommen lautet sein Name None, und narrator ist, wie m und s im vorherigen Beispiel, eine Variable, in der das Objekt des Zeichens platziert wird und von der aus z. B. seine Methoden aufgerufen werden , say) Das Argument kind hat zwei Werte: adv und nvl. Das erste ist das oben beschriebene Standardverhalten, und das zweite enthält den nvl-Modus, in dem Porträts nicht angezeigt werden und das Textfeld den größten Teil des Bildschirms einnimmt. Genau das, was wir brauchten. Dieser Modus wird durch den Bildschirm nvl_screen in der Datei screens.rpy und die Gruppe der styles.nvl * -Stile (Dateien screens.rpy und options.rpy) beschrieben, in denen wir die Schriftart, den Hintergrund des Textfelds, die Menüfarbe und alles andere festlegen.

Bild

label start:
  image bg monet_palace_image = Image('images/1129_monet_palace.jpg', align=(0 .5, 0.5)) 
    nvl clear
    hide screen nvl
    scene bg monet_palace_image 
    $ Ren'Py.pause(None) 
   " — Я всегда говорил: твои песенки — дерьмо, Люсьен, и я не понимаю, где ты только находишь музыкантов, согласных это исполнять!"

Wir werden zeilenweise analysieren: Zuerst wird das Startlabel angesagt, ab dem das Spiel beginnt. Dieser Name ist reserviert und die Engine wechselt immer dorthin, nachdem Sie auf die Schaltfläche "Neues Spiel" geklickt haben, wo immer es sich im Skript befindet. Alles, was auf das Etikett folgt, befindet sich logischerweise „innerhalb“ dieses Etiketts. Daher wird es durch Einrückungen unterschieden: Es funktioniert in Ren'Py auf die gleiche Weise wie in reinem Python. Die Initialisierung des Bildes ist ziemlich offensichtlich, aber die folgende Zeile macht eine wichtige Sache: Entfernt den gesamten Text vom Bildschirm nvl_screen. Dies erfolgt nicht automatisch. Wenn Sie also am Ende jeder Seite nicht nvl clear setzen, kriecht der Text leise vom Bildschirm und wird dort angezeigt, bis der Bildschirm endgültig gelöscht ist. Es scheint eine Kleinigkeit zu sein, aber ich habe viel mehr Zeit mit dem Debuggen von fehlendem nvl verbracht, als ich zugeben möchte. Wir entfernen vorübergehend das frisch gewaschene Sieb. Damit der Spieler den Hintergrund genießen kann, muss er den Hintergrund anzeigen, die endlose Pause einschalten (dh auf den Klick warten) und die Story starten. Sobald der Text auf nvl_screen angezeigt wird, kehrt der Bildschirm selbst an seine Stelle zurück.

Die Zeile mit der Pause befindet sich übrigens bereits in Python: Um eine einzelne Zeile einzuschließen, reicht es aus, mit '$' zu beginnen, und längere Codeteile müssen in den 'python:' - Block geschrieben werden. Jeder vom Spiel ausgeführte Code sieht die Module von Ren'Py selbst und Sie müssen sie nicht mehr explizit importieren.

Fügen Sie Verzweigungen und Variablen hinzu


Zu diesem Zeitpunkt ist das Spiel ein Leser, der den Text anzeigt und bei Bedarf den Hintergrund ändert. Das Speichern, Zurückspulen, das Hauptmenü und die Einstellungen funktionieren bereits ab Werk. Wenn wir jedoch eine illustrierte Geschichte schreiben wollten, hätten wir sie geschrieben, oder? Fügen Sie vor dem Text ein kleines Menü ein:

label start:
    menu: 
        "Зайти в меню разнообразного дебага": 
            $ debug_mode = True
            jump debug_menu 
        "Пропустить вступление": 
            jump the_very_start_lazlo_nooptions
        "Начать вступление": 
            label the_very_start: 
                #show screen nvl
                nvl clear 
                hide screen nvl 
                scene bg monet_palace_image 
                $ Ren'Py.pause(None) 
               " — Я всегда говорил: твои песенки — дерьмо, Люсьен, и я не понимаю, где ты только находишь музыкантов, согласных это исполнять!" 

Nach dem Einschalten des Spiels kann der Benutzer (oder vielmehr der Entwickler) auf Wunsch in den Debug-Modus wechseln oder das vorgefertigte Stück der Einführung überspringen und sofort mit dem Testen des Stücks ab dem letzten Commit beginnen. Der Zeilen-Show-Bildschirm nvl wird als unnötig auskommentiert - wie oben erwähnt, wird der Bildschirm von selbst angezeigt, wenn der Text darauf aktualisiert wird. Wie Sie sehen, funktionieren Kommentare auf absolut offensichtliche Weise.

Beschriftungen, Menüs und andere eingerückte Blöcke können beliebig tief verschachtelt werden. In der Praxis wird jedoch versucht, den Text in Folgen von zehn Seiten aufzuteilen. Jede dieser Episoden wird in einem separaten Label ohne Einrückung beschrieben (es muss sich nicht mehr im Start-Label oder sogar in derselben Datei befinden), und die Übergänge von einer Episode zur anderen werden durch Sprünge ausgeführt. Wir kämpfen also nicht nur mit Dutzenden von Einrückungsebenen, sondern sorgen auch für Modularität des Codes: Jede Episode kann einzeln getestet werden, und es ist ziemlich einfach zu überprüfen, welche Variablen gelesen, in welche geschrieben und wohin zugelassen werden.

Die Menüs und Variablen im Spiel sind genau gleich angeordnet. Da es selbst in einer kleinen Episode für zehn Minuten des Spiels unglaublich viele Variablen und Labels gibt, haben wir eine einfache Version der ungarischen Notation übernommen: Der Name des Labels 'the_very_start_lazlo_nooptions' besteht aus drei Teilen: dem Namen des Ortes the_very_start (dh dem Zeitraum vom Beginn des Spiels bis zum ersten Mal auf See) ), den Namen der Folge lazlo (das ist ein Binge von Lazlo, auf dem Sie junge Slipper als Segler anheuern können) und den Namen des Labels selbst. Bei diesem Ansatz sind die Namen ziemlich umständlich, aber es ist besser als beim Testen, dass vor drei Monaten bereits jemand die Variable ship_listing erstellt hat. Setzen Sie True God know where, und jetzt wirkt sich der Wurf eines zufälligen Ereignisses auf das Ergebnis eines anderen zufälligen Ereignisses am anderen Ende aus das Meer.

Anstelle einer Schlussfolgerung


Zu diesem Zeitpunkt haben wir bereits die oben erwähnte Funktionalität von Choicescript und Inklewriter auf Ren'Py reproduziert. Es scheint, dass unser Boot bereit ist zu segeln. Im nächsten Artikel werde ich zeigen, wie Sie mit der Bildschirmsprache RenPy eine komplexere und mit Python eine noch komplexere Benutzeroberfläche erstellen können.

Bild

Jetzt auch beliebt: