Die Pre-Production ist in der Regel die Phase der Konzeptfindung. Diese Phase ist ein kreativer und kollaborativer
Prozess, an dessen Ende im besten Falle ein Game Design Document steht. Für das Game Design Document wurde ein Template verwendet.
Game Design ist ein kreativer Prozess. Das gilt auch für Serious Games. Für ein gutes Spiel-Konzept sind also gute
Ideen erforderlich.
Verschiedene Methoden zur Ideenfindung bieten sich an.
Brain-Storming
Recherche von Games(nicht nur Serious Games)
Auseinandersetzung mit dem Problemfeld
Auseinandersetzung mit der Zielgruppe
Low-Fidelity Prototyping (kleine Skizzen oder Stickynotes)
Diese Ideen sollen nicht besonders detailliert oder ausgereift sein. Ein wesentlicher Teil der konzeptuellen
Entwicklung ist die
Iteration von Ideen. Es sollte kein großer Fokus auf einzelne Ideen gesetzt werden, stattdessen sollten viele
verschiedene Konzepte
und Blickpunkte besprochen werden.
Abhängig vom Projekt können auch externe Bedingungen in den Designprozess eingreifen. Es ist möglich, dass die
Lerninhalte oder Zielgruppe bereits vorgegeben sind.
Solche Einschränkungen sollten aber nicht die Offenheit für Inspirationen aus sachfremden Spielen hemmen.
Das Konzept von Chainguard zum Beispiel, ist fast gänzlich von einem Spiel inspiriert, das nichts mit IT-Sicherheit
zu tun hat.
Wenn eine bestimmte Zielgruppe bereits gegeben ist, bietet es sich auch an, diese Zielgruppe in den Designprozess
einzubinden, etwa durch Interviews oder Teilhabe am Designprozess.
Konzeptfindung bei ChainGuard
"[ChainGuard] ist ein Serious Game mit Fokus auf dem Erlernen der Grundkenntnisse der Malware-Detection. Die Spieler
treten
hier, angelehnt an das Spiel Papers, Please!
vom Solo-Entwickler Lucas Pope, in die Rolle eines "Richters" dessen Entscheidungen den mechanischen Kern des
Spieles darstellen. Diese Entscheidungen beschränken sich auf die Bewertung von Software oder
Softwareartefakten. Diese sollen nämlich entweder als harmlos oder als schädlich identifiziert werden. Folglich
nimmt der Spieler die Rolle eine Anti-Malware Software ein, die die Verantwortung für die Sicherheit des Systems
trägt.
In dieser Rolle stehen dem Spieler verschiedene Werkzeuge zur Enttarnung von schädlicher Software zur Verfügung.
Diese Werkzeuge dienen gleichzeitig als Lerngegenstand, da sie verbreitete Methoden der
Malware-Detection auf eine simplifizierte Weise repräsentieren und folglich die Nutzung dieser ein Verständnis
für diese Methoden liefert."
Die Entscheidung, das Spiel an "Papers, Please!" anzulehnen
gab dem Team ein einfaches aber auch inspirierendes Blueprint.
Die Spielmechanik als eine behaviouristich bewertbare ja/nein Entscheidung zu beschränken, hat uns den Aufwand genommen,
komplexe Spielmechaniken in einer größtenteils fremden Engine zu implementieren.
Gleichzeitig bot das Konzept "Papers, Please" durch seine eigene komplexe Spielwelt die Inspiration für ein Spiel, dass
trotz einfach erscheinender Mechaniken eine komplexe Umgebung bieten kann.
Die Spielerentscheidung durfte folglich nicht einfach sein und musste von verschiedenen Faktoren abhängen. Das Gebiet
der IT-Sicherheit als Lerngegenstand hat sich aufgrund unserer zumindest
oberflächlichen Vertrautheit und der sich bietenden Komplexität gut angeboten. Aus Einreisenden in "Papers, Please"
wurden Softwarekandidaten. Aus der Grenze und dem Beamten(Spieler) wurde das
Virenschutzprogramm ChainGuard. Die größte Hürde der Konzeptionsphase war es, Malware-Detection Methoden zu finden, zu
abstrahieren und als glaubwürdige Spielelemente darzustellen. Nach einer
kurzen Recherche konnten wir aber Signaturgenerierung, Sandboxing und reverse Engineering als einfach und verständlich
darstellbare Werkzeuge eines Virenschutzprogramms herausarbeiten.
Die restlichen Mechaniken, wie ein Zeitlimit, die Bestrafungen bei falscher Bewertung oder das Register haben sich
natürlich aus der Grundidee des Spieles ergeben.
Motivation - ein Spiel das Spaß macht
Wie bereits im Kapitel "Vorab, was zeichnet ein Serious Game aus?" erwähnt, sollen Serious Games auch einen
Unterhaltungswert bieten. Dieser dient
nicht zuletzt der Motivation und folglich auch dem Lerneffekt und ist somit auch ein integraler Bestandteil der
Entwicklung von Serious Games.
Im folgenden Abschnitt sollen Game Design Prinzipien, die zur Motivation der Spielenden und dadurch auch zum
gewünschten Lerneffekt führen,
aufgeschlüsselt werden.
Feedback - Bewertung - Belohnung
"Eine Aufgabe des Game Designs ist es, gezielte Anreize für ein motivierendes
Spiel zu schaffen. Klassische motivierende Merkmale eines Computerspiels sind
die Rückmeldung, die Bewertung, die Belohnung und das Spielziel.""
Spiele als Interaktive Medien bauen auf der Wechselwirkung zwischen Spieler und Spiel auf.
Ein befriedigendes Spielerlebnis setzt also auch befriedigende Interaktion - und dazu gehört Feedback - vorraus.
Feedback bezeichnet im Allgemeinen die Reaktion der Spielwelt auf das Handeln des Spielers. Dieser soll
das Gefühl bekommen, er habe Einfluss auf diese Welt und seine Entscheidungen seien von Bedeutung.
Sogleich dient positives Feedback der psychologischen Bedürfnisbefriedigung des Spielers.
Das heißt, wenn ein Spieler merkt, dass er in einem Spiel besser wird, ist er motivierter weiterzuspielen.
Ein Beispiel aus ChainGuard: Genehmigt der Spieler eine Malware(also macht er einen Fehler), so treten die negativen
Folgen seines
Handels sofort in Erscheinung. UI-Elemente werden entfernt, der Bildschirm flackert oder wird rot. Wenn ein Spieler
jedoch einen
Nicht-Malware-Kandidaten genehmigt, wird dies mit einem Zuschlag auf die kostbare Zeit belohnt. So wird der Spieler
angetrieben,
das Spiel besser und aufmerksamer zu spielen, sich die Spielmechaniken - also auch den Lerngegenstand - zu
verinnerlichen und über
seine Entscheidungen nachzudenken.
Die Angemessene Herausforderung
Die Schwierigkeit eines Spieles sollte zwar zum einen fordernd genug sein, um die Spielenden bei Laune zu halten und
ein Gefühl des
wahren Triumphes bei Vollendung des Spieles zu bieten. Eine zu harte Schwierigkeit kann jedoch zu Resignation
führen.
Ein ausgewogenes Maß an Schwierigkeit zu finden ist komplex und wirkt nach der Realisation, dass das beste Maß an
Schwierigkeit für jeden
anders ist, nahezu unmöglich. Hier hilft es, sich seiner Zielgruppe bewusst zu sein:
Sind die Personen in der Zielgruppe vertraut mit Lernspielen?
Welches Alter hat die Zielgruppe(Kind/Erwachsen)?
Wie vertraut ist die Zielgruppe mit dem Lerngegenstand?
Die Herausforderung sollte überdies nicht statisch sein. Die Spieler mit einfachen Aufgaben an die Grundmechaniken heranzuführen,
um dann stetig die Herausforderung zu erhöhen ist eine in Videospielen omnipräsente Praxis. (Vgl. Begriff "Scaffolding" VL "Digitales Lehr- und Lernmanagement")
Immersion
...beschreibt den Zustand des vollkommenen Sichhineinversetzens. In einem Videospiel beschreibt dieser Zustand das Gefühl, Teil der Spielwelt zu sein. Die Folge dieses Zustandes
ist, dass das Lernen nicht mehr als Aufgabe, sondern als natürliche Aktivität einer immersiven Umgebung angesehen wird. Dieser Zustand ist also für Serious Games
nicht weniger von Bedeutung als für herkömmliche Videospiele.
Es gibt verschiedene Wege, ein immersives Spielgefühl zu erzeugen. Sie lassen sich jedoch alle auf das Prinzip einer glaubhaften, lebhaften Spielwelt zurückführen.
Eine glaubwürdige Welt wird im Wesentlichen durch Ihre Charaktere verkörpert. Ferner befriedigt die Interaktion mit glaubwürdigen Charakteren das psychologische Grundbedürfnis der sozialen Integration
und trägt so zu einer motivierten Spielerfahrung bei. Die Charaktere einer immersiven Welt sollte man immer als Abbild der Welt als Ganzes verstehen.
Das heißt, sich zu fragen: In was für einer Welt würde dieser Charakter leben? Oder was für Charaktere würden in dieser Welt leben?
Eine immersive Spielwelt muss diese Fragen für den Spieler beantworten können.
Ein Beispiel aus ChainGuard:
Die Charaktere in dem Spiel sind die Kandidaten. Sie stellen sich dem Spieler durch ihre Beschreibungen vor und "wollen" alle (mehr oder weniger) vom Spieler als Nicht-Schadsoftware genehmigt werden.
Da der Spieler aber weiß, dass er Schadsoftware entlarven muss, realisiert er schnell, dass ein großer Teil der Charaktere dieser Welt ihn anlügt.
Dieser Eindruck wird mit dem eintönigen alten Windows User Interface kombiniert, um ein Gefühl einer dystopischen Spielwelt zu erzeugen, die aber durch ihr
konsistentes Auftreten zur Immersion beitragen und zum Spielen anregen soll.
Wie strukturiere ich Lerninhalte für ein Serious Game?
Spiele als interaktive Medien bieten einzigartige Möglichkeiten und Herausforderungen. Die strukturelle Integration von Lerninhalten in eine Spielumgebung
ist eine dieser Probleme.
Das, was gelernt werden soll, muss im Spiel real vorkommen, beispielsweise strategisches Denken, das Führen von
Teams,
Kooperation oder das Lösen von kombinatorischen Problemen und jede Menge mehr.
Niegemann und Weinberger sprechen sich hier für eine aktive Umsetzung des Lerngegenstandes als Teil des Spieles aus. Was dieser Lerngegenstand ist -
ob reines Faktenwissen oder Verständnis für ein komplexes System - beeinflusst die lerntheoretische Perspektive, die eingenommen werden muss.
Die behaviouristische Perspektive
...sieht Lernen als die Etablierung von Reiz-Reaktions-Mustern. Wichtig für das Design von Spielmechaniken: Eine Aufgabe hat immer die gleiche Lösung. Dieser Ansatz bietet sich am meisten für die Vermittlung von Faktenwissen an.
Als Beispiel für diese Praxis bietet sich die gamifizierte Sprachlern-App Duolingo an.
Genre die sich für behaviouristische Lernspiele eignen:
Quizspiele
Drill- & Practice-Spiele(zum Beispiel ein Piano-Lernspiel)
Denkspiele wie Sudoku
Die kognitivistische Perspektive
...sieht Lernen als einen aktiven Prozess des Lernenden(des Spielers). Es geht darum, das Problemlösen zu erlernen und eigene Vorgehensweisen zu entwickeln.
Der Lerneffekt entsteht hier in erster Linie durch Testen und Ausprobieren. Das Spiel sollte dem Spieler nicht die Lösung, sondern Tipps geben.
Wichtig für das Design von Spielmechaniken: Eine Umgebung schaffen, in der eigene Strategien und Denkansätze ausprobiert werden können.
ChainGuard zum Beispiel versucht den Spieler dazu zu bringen, verschiedene Methoden der Malware-Detection auszuprobieren und seine eigene Strategie zum Abarbeiten der Kandidaten
in begrenzter Zeit zu finden. Es ist nicht - so wie beim Behaviorismus - eine richtige Strategie vorgegeben.
Genre die sich für Kognitivistische Lernspiele eignen:
Offene Rätselspiele mit vielen verschiedenen Mechaniken(zB: Portal 2)
Detektiv- und Rätselspiele
Explorationsspiele
Die konstruktivistische Perspektive
...sieht Lernen als aktiven Konstruktionsprozess von Wissen durch den Lernenden(Spieler). Der Lerngegenstand wird durch eine tiefgreifendes Verständnis
einer komplexen und realistischen Spielumgebung vermittelt. Daraus folgt, dass das Spiel selbst diesen komplexen Prozess ermöglichen und unterstützen muss.
Wichtig für das Design von Spielmechaniken: Eine Welt schaffen, deren Regeln und Mechaniken auf dem Lerngegenstand aufbauen.
So wie beim Kognitivismus, nimmt hier das Spiel selbst nur eine beratende Rolle ein.
Sandbox/Open-World-Spiele
Konstruktions- und Bau-Spiele (zum Beispiel Poly Bridge )
Rollenspiele (zum Beispiel um Geschichtswissen zu vermitteln)
Diese drei Perspektiven schließen sich Gegenseitig nicht aus- sie bauen aufeinander auf. Viele Serious Games bieten Lernerfahrungen aus verschiedenen Perspektiven. Ohne eine eindeutig
behaviouristische Bewertung kann das Spielziel unklar erscheinen und ohne tiefgreifende und komplexe Mechaniken kann Immersion und Engagement leiden. Es gilt, eine Balance zu finden.
Zu einer tieferen Behandlung der Lerntheorien, Game-Design(MDA-Ansatz, ...), bieten sich die Lehrmaterialien des Moduls "Digitales Lehr- und Lernmanagement" an.
Proof of Fun
In zeitlich begrenzten Projekten gehört ein minimum viable Product (MVP) zu den größten Projekt-Meilensteinen. Ein MVP wird oft als ein Prototyp des geplanten Produktes verstanden - die simplifizierteste
Version des Spieles.
Hier bietet es sich an, mit der Zielgruppe in Kontakt zu treten und sie in den Entscheidungsprozess zu involvieren, um elementare Funktionen herauszustellen.
Die Konzeption eines MVP ist die Auflistung aller Features, die für die wichtigsten Spielmechaniken gebraucht werden. Diese Features sollten im Entwicklungsprozess priorisert werden.
Hollstrand Supporting Pre-Production
in Game Development (Link),
Zugriff 06. April 2026
Becker, Metz Digitale Lernwelten – Serious Games und Gamification (Link),
Zugriff 06.April 2026
Przybylski, Rigby A Motivational Model of Video Game Engagement (Link),
Zugriff 06. April 2026
Hyrynsalmi et al. What is a Minimum Viable (Video) Game? (Link),
Zugriff 06. April 2026
ChainGuard
...ist ein Serious Game mit Fokus auf dem Erlernen der Grundkenntnisse der Malware-Detection. Die Spieler treten
hier, angelehnt an das Spiel Papers, Please!
vom Solo-Entwickler Lucas Pope, in die Rolle eines Richters dessen Entscheidungen den mechanischen Kern des
Spielerlebnisses darstellen. Diese Entscheidungen beschränken sich auf die Bewertung von Software oder
Softwareartefakten. Diese sollen nämlich entweder als harmlos oder als schädlich identifiziert werden. Folglich
nimmt der Spieler die Rolle eine Anti-Malware Software ein, die die Verantwortung für die Sicherheit des Systems
trägt.
In dieser Rolle stehen dem Spieler verschiedene Werkzeuge zur Enttarnung von schädlicher Software zur Verfügung.
Diese Werkzeuge dienen gleichzeitig als Lerngegenstand, da sie verbreitete Methoden der
Malware-Detection auf eine simplifizierte Weise repräsentieren und folglich die Nutzung dieser ein Verständnis
für diese Methoden liefert. Screenshot von Chainguard
Kandidaten
Die Kandidaten sind Spielobjekte, die Software(-artefakte) repräsentieren. Sie sind ein Teil der Nutzeroberfläche im
Spiel und lassen sich per Drag&Drop verschieben.
Zum Anfang des Spieles befinden sich alle Kandidaten in einer scrollbaren Warteschlange am linken Rand des Fensters.
Ein Icon gibt einen ersten Hinweis über die Natur des Kandidaten.
Die Kandidaten können per Drag&Drop in verschiedene Komponenten des Spieles eingefügt werden: die Sandbox,
Reverse-Engineering-Box, Signatur-Box und das Kontrollpanel. Die Boxen repräsentieren
die oben erwähnten Werkzeuge, mit denen ein Kandidat analysiert werden kann.
Das Register
Das Register bietet dem Spieler einen Katalog an Informationen, die er in seiner Bewertung der Kandidaten nutzen
soll. Neben einer Tabelle mit bereits als schädlich identifizierten Signaturen
bietet das Register eine Liste an System-Calls, die von bestimmten Arten von Software genutzt werden. So kann der
Spieler(sobald er die genutzten Systemaufrufe einer Software herausgefunden hat)
einschätzen, ob ein Kandidat auf Resourcen zugreift die er eigentlich nicht brauchen sollte und kann so Schlüsse auf
die Integrität des Kandidaten ziehen.
Die Signatur-Box
In diesem Gadget kann, wie bereits oben erwähnt, ein Kandidat eingesetzt werden. Nach einer Wartezeit von 20
Sekunden wird dann per Click auf die Signatur-Box eben diese Signatur im Informationsfeld angezeigt. Diese kann mit
der Liste im Register abgeglichen werden
um schädliche Signaturen zu identifizieren.
Die Sandbox
Die Sandbox bietet eine abstrahierte Darstellung der dynamischen Codeanalyse für Malwarekandidaten. Der Spieler kann
einen Kandidaten in diese Sandbox einfügen und mit einer gewissen Wahrscheinlichkeit, und wenn der Kandidat eine
Malware ist, wird sich diese Sandbox rot färben
und somit dem Spieler die böswillige Natur des Kanidaten zeigen.
Die Reverse-Engineering-Box
Die Reverse-Engineering-Box besitzt eine identische Funktionsweise zur Signatur-Box. Der Unterschied ist, dass statt
der Signatur ein Teil des Quellcodes und eine Liste der vom Kandidaten genutzten Systemsaufrufe ausgegeben werden.
Der (pseudo-)Quellcode kann vom Spieler selbst bewertet werden; die Liste der herausgegebenen Systemaurufe können im
Register mit für den Typ der Anwendung erwarteten Systemaufrufen verglichen werden. Wenn eine Software bestimmte
Systemaufrufe
Nutzt, die sie nicht brauchen sollte, ist das im Allgemeinen ein Zeichen für Malware.
Beispiel: ein Musik-Player versendet TCP-Pakete im Hintergrund.
Kontrollpanel
Hier wird die Entscheidung getroffen, ob ein Kandidat schädlich ist oder nicht. Der Kandidat wird in die Mitte des
Panel
eingesetzt und durch einen Knopfdruck bewertet: "Genehmigen" oder "Ablehnen". Die Folgen dieser Entscheidung werden
im
Abschnitt “Feedback” erklärt.
Informationsfeld
Hier werden Informationen über Kandidaten, das Register und den Output der Signatur- und Reverse-Engineering Box bei
einem Klick auf das jeweilige Element angezeigt.
Zeitstrahl
Die Hauptressource, um die die Spielenden kämpfen, ist Zeit. Er muss alle Kandidaten vor Ablauf der Zeit bewerten.
Ist
man zu langsam, oder wird zu viel Malware genehmigt, verliert man das Spiel. Die Bewertung von Kandidaten kann die
verbleibende Zeit erhöhen oder reduzieren. Mehr dazu im nächsten Abschnitt.
Feedback
Abhängig von Kandidat gibt existiert ein Feedback für jede Bewertung:
Kandidat ist\ Spielerentscheidung
Ablehnen
Genehmigen
Malware
Nichts
Man verliert Zeit
Bildschirmflackern
Bildschirm verzieht sich
Spielelemente werden ausgeblendet
Nach 5 genehmigten Malware-Kandidaten ist das Spiel verloren.
keine Malware
Man verliert Zeit
Man gewinnt Zeit zurück
Bezug auf Lernegegenstand
Die Malware-Detection Methoden sind in ihrer Gesamtheit abstrahierte Abbildungen der im Paper
"A Comprehensive Review on Malware Detection Approaches"
vorgestellten Methoden.
Die Generierung und der Abgleich einer Signatur, sowie die Analyse der von einer Software genutzten System-Calls
sind
etablierte und effektive Methoden zur Identifizierung von Schadsoftware. Durch die gamifizierte Nutzung dieser
Methoden
wird ein Verständnis für sie entwickelt - lernen findet statt.
Leitfaden zu Godot
Szenen-Hierarchie
Analog zum Branching-System von Git lohnt es sich bei kollaborativen Projekten sehr, die Arbeit logisch und
praktisch zu trennen, um Konflikte bei - von mehreren Devs gleichzeitig bearbeiteten - Assets zu vermeiden.
Bei Godot bietet sich für die parallele Arbeit die Nutzung von verschiedenen Szenenbäumen an.
Ein Beispiel aus dem Entwicklungsprozess von ChainGuard:
Zu Beginn wurden 3 Basisfunktionen herausgearbeitet, die unser MVP haben musste. Erstens, eine Drag&Drop Funktion
für Spielelemente; Zweitens, die Übertragung eines UI-Mockups in Godot; und Drittens, das Laden von
Kandidaten-Datensätzen aus einer JSON-File.
Diese drei Features sind bewusst so gewählt, dass sie nicht aufeinander aufbauen. So konnte sich jeder eine eigene
Szene erstellen und dort seine Aufgabe umsetzen. Folglich wurden die drei Szenen - und das ist die Besonderheit von
Godot - als Unterszenen in einer umfassenden Hauptszene aggregiert.
Alle Nodes mit dem Filmklappen-Symbol sind Unterszenen.
Erstellen einer neuen Szene:
Speichern der neuen Szene als Asset:
Einfügen einer Unterszene:
Die lose_screen Szene wird als Unterszene in die Hauptszene eingefügt
Skripte in Godot
Die Implementierung eigener Funktionalitäten durch eigens geschriebene Skripte ist ein grundlegender Baustein der
meisten Spiele Engines - so auch in Godot.
Die Sprachen
Godot unterstützt hauptsächlich 2 Skriptsprachen. Godot-Skript ist eine an Python angelehnte Sprache. Die gleiche
Schwache Typisierung, die gleichen Syntaxregeln. Sie wird von der Dokumentation und dem Großteil der Community
bevorzugt. Die zweite unterstützte Sprache ist das dem Unity-Dev bereits bekannte C#. Die Nutzung von C# in Godot
hat
jedoch einige Plattform-Kompatibilitäts-Einschränkungen: zum Beispiel ist der Export auf Web momentan nicht
unterstützt.
Godot-Doku zu C#
Ein Skript pro Node und Vererbung
Anders als in Unity kann man in Godot nur ein Skript pro Node anfügen. Das hat den Grund, dass die vom Nutzer
erstellten
Skripte in Godot Unterklassen der Nodes sind. Folglich kann ein Skript für einen Button automatisch alle
Klasseneigenschaften und Methoden der Button-Klasse(und aller ihrer Oberklassen, bis zur Object-Klasse) nutzen und
überschreiben. Überdies stellt dieses Skript eine neue Art von Node dar und kann auch so im Editor erstellt werden.
Beispiel aus der Entwicklung: In Chainguard exisitert eine Klasse “TimeBar”, die von der UI-Basisklasse “Control”
erbt.
Beim Hinzufügen einer neuen Node kann man nun “TimeBar” als neuen Node-Typen finden.
Das Schriftrollen-Symbol notiert eine durch den Nutzer erstellte KlasseWichtig: Ein Skript wird erst zu einer vollwertigen Unterklasse, wenn im Skript mittels der “class_name XXXX”
Notation ein Name
vergeben wird. extends Control class_name TimeBar
Variablen im Editor setzen
Unity bietet die praktische Funktion, dass öffentliche Felder im Editor geändert werden können. In Godot ist diese
Funktionalität hinter der “@export”-Notation versteckt.
Export-Beispiel aus dem Sandbox-Skript@export var chance_of_trigger := 0.8
Durch die Nutzung der "@export"-Notation werden nun Felder im Editor/Inspektor sichtbar:
Gruppen
...vereinen die Funktionalitäten von Unitys Tags und Layers in einem. Nodes können Gruppen im rechten Editorpanel
hinzugefügt werden:
und per
Drop-Target Objekte durch die Gruppe findenvar containers = get_tree().get_nodes_in_group("drop_container")
Globale Objekte
Objekte wie klassisch betitelte Game-Manager die szenenübergreifend exisiteren sollen sind von Godot unterstützt. Wo
bei Unity die
"DontDestroyOnLoad"-Methode genutzt wird um Objekte in jeder Szene zu verfügbar zu machen, muss man bei Godot für
diese Funktion in die Projekteinstellungen:
Projekt > Projekteinstellungen > Globals
Hier können per Referenz auf ein Skript Globale Objekte definiert werden. Und direkt von Skripten angesprochen
werden.
Signale
"Das sind Nachrichten, die Nodes aussenden, wenn etwas Bestimmtes mit ihnen passiert, z.B. wenn ein Button
gedrückt wird.
Andere Nodes können sich mit diesem Signal verbinden und eine Funktion aufrufen, wenn das Ereignis eintritt.
Signale sind ein in Godot integrierter Delegierungsmechanismus, der es einem Spielobjekt ermöglicht, auf eine
Änderung
in einem anderen zu reagieren, ohne dass sie sich gegenseitig referenzieren. Die Verwendung von Signalen führt
zu
weniger Kopplung und hält Ihren Code flexibel." (Quelle)
Signale sind also eine Möglichkeit Funktionen global aufzurufen ohne eine Referenz auf diese. Dieses Feature ist
auch besonders bei kooperativen Workflows praktisch,
da man, statt via einer Referenz auf eine noch nicht vorhandenes Objekt, ein Signal auslösen kann dass einfach von
später hinzukommenden Komponenten aufgenommen werden kann
ohne etwas am Code des Auslösers ändern zu müssen.
Es gibt 2 Wege, wie man einen Funktionsaufruf mit einem Signal verbinden kann: über Skript oder über den Editor.
Editor
Schaue dir zunächst die verfügbaren Signale einer Node im Inspektor an.
Liste der Signale einer Node anzeigen
Wähle ein Signal aus und weise ihm die Node mit dem Skript deiner Ziel-Funktion zu.
Signal zu einer Zielfunktion zuordnen
Per Skript
signal mein_signal(wert)
func _ready():
print("Sender bereit")
emit_signal("mein_signal", "test")
Sender
extends Node
func _ready():
var sender = get_node("../Sender")
sender.mein_signal.connect(_on_mein_signal)
func _on_mein_signal(wert):
print("Empfangen:", wert)
Empfänger
Definition of Done(DoD):
JSON oder YAML Datei für Speichern von Kandidaten-Attributen anlegen.
In der Datei sollte ein Array von Objekten sein, die alle die folgenden Attribute haben(Datentypen erstmal alle String außer explizit anders beschrieben):
Name,
Publisher,
Description,
IsMalware (bool),
Signature(4-stelliger Zahlencode zB "0239"),
SourceCode (string, kann erstmal Leer bleiben)
System Calls (Array mit Strings, die einen oder mehrere System Calls beinhalten, erstmal kombination aus diesen Mocks nehmen: "KILL_PROCESS, SEND_PACKET, INSTALL_KERNEL_RUNTIME" )
Punishment(Zahlencode, der dann intern in nem Switch benutzt wird um die Folgen der Malware zu mappen, Zahl von 1- 10)
davon erstmal 10 generieren lassen(ich denke KI ist da der schnellste weg um erstmal 10 mockups zu erstellen) 5 sind malware 5 nicht. Die anderen Felder müssen sich noch nicht stark unterscheiden zwischen Malware und nicht Malware.
Bonus/Follow-Up: Datei in Godot auslesen und als Text ausgeben(Konsole oder Textfeld).
Entwicklertagebuch
Um in Chainguard, wie in PapersPlease, über einzelne Kandidaten entscheiden zu können braucht es erst einmal ebend diese Kandidaten.
Das heißt,
es benötigt eine Candidate Klasse,
um eine Datenstruktur für einzelne Kandidaten festzulegen.
Wichtig hierbei ist, dass jedes Skript (jede .gd Datei) eine Klasse ist.
Das heißt, dass man in der Regel nicht über "Class:" eine neue Klasse in dem Dokument definiert,
sondern über "class_name Candidate" der Klasse nur mitteilt, wie sie heißt.
"Class:" existiert trotzdessen, die so definierte Klasse kann aber nicht ohne weiteres von außen aufgerufen werden.
Um Kandidaten speichern und laden zu können braucht es einen CandidatesManager,
dieser schreibt die Kandidaten als Liste, in eine JSON oder lädt sie aus dieser wieder.
In GODOT können einzelne Scenes singulär gestartet werden. Zum Testen der neuen Funktionalität wird also kein Dummy in die main-Scene gepackt,
sondern eine separate Test-Scene für die Funktionalität erstellt. In dieser braucht es dann nur ein Node an das wir unser Skript hängen,
welches die neue Funktionalität mit Mockup Daten testet.
Dafür ist das datenstruktur_und_anzeige_der_kandidaten_daten.gd Skript verantwortlich.
Wir müssen die Kanidaten als Spiel-Elemente Darstellen.
Zunächst brauchen wir die Möglichkeit, UI-Elemente per Drag & Drop über das Spiel zu bewegen.
Die Verwendeten Objekte sollten UI-Objekte(erbt von Control in Godot) und KEINE Node2D sein.
Tutorial https://godot.snoeyz.com/drag-and-drop/
Entwicklertagebuch
Für den Drag-and-Drop-Mechanismus wurde eine Demoszene angelegt, welche aus einem
Control-Node besteht, welches als Kindelemente mehrere Container und ein Item besitzt.
Das Item ist das ziehbare Element, die Container sind die Elemente, auf die das Objekt
gezogen werden. Diesen Containern wurde die "drop_container"-Gruppe zugeordnet. Dem Item wurde das Skript
draggable_item.gd
zugeordnet bekommen. In diesem Skript werden alle Container initialisiert. Wenn es zu einem
InputEventMouseButton
kommt, wird das Dragging durchgeführt. Wenn das Item wieder mit der Maus losgelassen wird,
wird mit der check_drop-Funktion festgestellt, ob das sich Item über der Position eines
Drop-Containers befindet. Falls nicht, wird der letzte Container und die letzte Position für
das Item ausgewählt. Falls das Element über einem Drop-Container ist, wird der letzte Container
gespeichert, damit das Item notfalls wieder auf die letzte Position kann, wenn der nächste Drop
nicht erfolgreich ist. Außerdem wird die aktuelle Position und der aktuelle Container geändert.
Mit der clamp-Funktion
von Godot wird sichergestellt, dass sich das Item genau innerhalb der Grenzen des Containers
liegt. Auch wenn es mit der Maus etwas über die Grenze gezogen wurde.
Nachdem die Grundfunktion implementiert wurde, wurde der Code noch einmal angepasst, um ihn die
Funktionalität zu erweitern, dass der jeweilige Container wissen muss, welches Item sich in ihm
befindet. Dazu wurde der Szene ein DragLayer hinzugefügt. Im Skript
draggable_item.gd
wird das Item bei dem Mausklick mit dem DragLayer gereparentet. Dadurch ist das Item für den Übergang
das Child dieses DragLayers. Sobald das Item gedroppt wird, wird es mit dem an dieser Postion liegenden
Container gereparentet. Dadurch ist dann eine klarere Struktur gegeben, sodass das Item dem Container
zugeordnet werden kann, in welchem es liegt. Der DragLayer verhindert, dass ein Item beim Übergang einem
Container zugeordnet wird, da es sich grade frei bewegt. Befindet sich das Item nicht auf der Position
eines Containers, wird das Item analog zu der bisherigen Lösung mit dem letzten Container gereparentet.
Definition of Done(DoD):
Buttons sind als solche markiert, Bezeichnungen die mit Drag&Drop zu tun haben, können erstmal ignoriert werden. Liste der Signale einer Node anzeigen
Entwicklertagebuch
Die Umsetzung erfolge in der GUI-Szene umgesetzt.
Zur Implementierung wurde eine Komposition aus 2DSprites und Control-UI-Elementen genutzt.
Entwicklertagebuch
Dieses Issues bestand aus der Erstellung aller Issues die für das aktuelle MVP umgesetzt wurden. Also: alle Issues in
dieser Liste.
Definition of Done(DoD):
Die im UI - Mockup als "Drag & Drop" Zeile Markierten Rechtecke zu nur neuen
drop_containers" hinzufügen.
Kandidaten Drag & Dropable machen.
Entwicklertagebuch
Die Drag&Drop Szene wurde als Unterszene der UI-Szene instanziiert und die Drop Targets den verschiedenen Plätzen in der UI(Sandbox, Signatur-Box, Reverse-Engineering-Box und Controlpanel) eingefügt.
Definition of Done(DoD):
Vorraussetzung: Reverse Engineering Box, Register, Signatur-Box Implementiert
Die große Textbox in der Mitte soll abhängig vom ausgewähltem Element Kontext-Infos anzeigen.
Schritte:
Ein Script für die Textbox erstellen
Einen Singleton im Skript haben der das ausgewähle Element anzeigt.
Der Singleton wird gesetzt wenn auf ein Element gecklickt wird, das Kontext-Infos hat(siehe Mockup: Kandidat,
Reverse-Engineering-Box, Register, Signtatur-Box)
Beim Setzen soll eine Funktion "get_context_info" oder ein Signal auf einem Skript des angeklickten Objektes aufgerufen
werden, welches einen String zurück gibt. Dieser soll in der Box angezeigt werden.
Entwicklertagebuch
Statt eines Globalen Singletons wurde eine Game-Manager-Node in einer Gruppe definiert, da es zu Problemen in anderen Szenen kam.
Für Elemente die Kontext Infos geben wurde die Klasse Focusable erstellt, die bei einem click eine Methode des Game-Manager aufruft. Dieses Methode übergiebt einen String der
dann mit BBCOde auf der Kontext-Tafel angezeigt wird.
(In Hindsight hätte man die Verbindung zwischen Button und Game Manager einfacher mit einem Signal lösen können.)
Teil dieser Aufgabe war auch, das Drag&Drop Skript anzupassen, sodas bei einem CLick auf das Objekt auch die wichtigen Daten zu den Kandidaten angezeigt werden.
Definition of Done(DoD):
Erstellen von StartScreen-Szene
Erstellen von Hauptszene(Mit UI-Mockup als Sub-Szene)
Button-Navigation Hauptszene <-> Startscreen
Lose-Szene mit Button zum Start-Screen und Hauptszene("Neu Versuchen")
Wenn Todes-Timer schon implementiert ist: Bei 0 oder weniger Zeit die Lose-Szene öffnen.
Entwicklertagebuch
Für die Menüs wurden der Text der Buttons aus dem Mockup, welche mit Adobe Illustrator erstellt wurden, angepasst
und neu mit den jeweiligen Grafiken für die Buttons exportiert. Die Szenen
main_menu.tscn,
lose_screen.tscn und
win_screen.tscn
wurden mit den jeweiligen Buttons angelegt, wobei sich der Win- und der Lose-Screen nur vom Anzeigetext unterscheiden. Für spätere
Anpassungen der Screens wurden aber dennoch separate Szenen angelegt. Den Menüs wurde jeweils mithilfe eines Control-Nodes das
menu.gd-Skript
zugewiesen, in welchem den Buttons der jeweilige
change_scene_to_file-Aufruf
zugeordnet wird. Ein solcher Aufruf wurde auch dem
Zeitstrahl
hinzugefügt, damit nach Ablauf der Zeit der Lose-Screen angezeigt wird.
Definition of Done(DoD):
Nachschlageregisterdaten in JSON schreiben und auslesbar machen
Inhalt:
Liste an Schadsoftware mit Namen, Herausgebern und Signaturen
Liste an System Calls und welche Arten von Anwendungen sie benutzen
Register signal/methode schreiben, die einen formattierten String dieses Inhaltes zurück gibt, nachdem die JSON-Datei ausgelesen wurde
Entwicklertagebuch
In diesem Issue wurde nichts anderes gemacht als in "MP-SeriousGames#01 - Datenstruktur und Anzeige der Kandidaten-Daten"
und ein Großteil des Codes aus dem Issue wurde in diesem wiederverwendet.
SysCall und Malware werden dabei getrennt, je analog zu Candidate, behandelt und implementiert.
Genaueres kann im anhängigen Merge-Request nachgelesen werden.
Definition of Done(DoD):
Script für das Drop-Target Sandbox schreiben
Funktion oder Signal Input: candidate.gd Wenn Malware == true
starte mit wahrscheinlichkeit von 0.8 einen Timer von 10 sek, nachdem das Rechteck Rot wird
Entwicklertagebuch
Exakte implementierung wie im Issue beschrieben. Skript
Zusätzlich wurde eine Methode für das entfernen des Kandidaten aus dem Input-Slot implementiert, die den Zustand der VM zurücksetzt.
Skript erbt von DropBox-Klasse, die lediglich die Kanidatenvariable und die receive-Funktion beinhaltet.
Definition of Done(DoD):
Script für das Drop-Target Reverse Engineering Box.
Script soll das "drop_box" erweitern und an Objekt "Drop_Target_RE" ersetzen
Variable on_focus_output: string (Standard-Wert sowas wie "Platziere Software hier um sie zu Analysieren)
"func receive_candidate(new_candidate):" erweitern, sodass
Variable "on_focus_output" nach 20 Sekunden auf eine formatierte Ausgabe von
_SourceCode: String,
_System_Calls: Array[String]
gesetzt wird.
Funktion get_context_info: soll on_focus_output zurückgeben
Entwicklertagebuch
Problemfreie Implementierung i re_box.gd
Skript erbt von DropBox-Klasse,
die lediglich die Kanidatenvariable und die receive-Funktion beinhaltet.
Definition of Done(DoD):
Script für das Drop-Target Signatur-Box.
Variable on_focus_output: string (Standard-Wert sowas wie "Platziere Software hier um sie zu Analysieren)
Funktion/Signal die eine instanz der Candidaten-Klasse nimmt
Soll die Variable "on_focus_output" nach 20 Sekunden auf eine formatierte Ausgabe von _Signatur setzen.
mit dem Namen: "receive_candidate"
Funktion get_context_info: soll on_focus_output zurückgeben
Entwicklertagebuch
Implementierung fast exakt zu Issue #11. Skript: box_signatur.gd
Definition of Done(DoD):
Vorraussetzung: zeitstrahl Implementiert
Singleton-Klasse erstellen die auf einer Node sitzt und global angesprochen wird, wenn ein Kandidat bewertet wurde.
globale Funktion die eine Zahl(punishment_index) und einen boolean(ob richtig bewertet wurde) bekommt
abhängig von boolean soll eine von 2 Funktionen augerufen werden
right_answer(punishment_index)switch mit dem index: 0 : mehr zeit default : nichts
wrong_answer(punishment_index) 0,1 : weniger Zeit 2 : ein zufälliges UI Element wird für 10 Sekunden disabled
Mögliche Konsequenzen:
Screen verfärben
Elemente disable
Mouse Sensitivity
Timer nicht mehr sehen
Screen Rotieren
Entwicklertagebuch
Statt einer Singleton Klasse, wurden die Konsequenzen im game_manager.gd-Srkipt
implementiert.
Die Methode "invoke_consequence" dient als Startpunkt. Diese wird von den Bewertungsbuttons aufgerufen und erhält 3
Parameter: Falsch/Richtig "geraten", Malware ja/nein, punishment Index des Kandidaten.
Die Methode enthält sowohl den Mechanismus der im GDD in der Tabelle benannt wird als auch einen Zähler für genehmigte
Malware. Wenn der Zähler 5 erreicht, ist das Spiel verloren.
Konsequenzen beinhalten:
Verlieren/Dazugewinnen von Zeit
Rotes Noise-Overlay für das Spiel
zufälliges UI-Element aus definierter Liste für 20 Sekunden Disablen
Spieloberfläche für 20 Sekunden verzerren
Definition of Done(DoD):
Oben in der Mitte des UIs soll ein Zeitrahl über eine Minute runterticken und wenn die Zeit <= 0 ist dann eine Nachricht printen
Entwicklertagebuch
Für die Implementierung des Zeitstrahls wurde eine
Demoszene und ein Skript
angelegt. Die Szene enthält ein Control-Element, dessen Kind eine
ProgressBar
ist. Das Control-Element enthält das Skript für den Zeitstrahl. Mit der
_process-Methode
von Godot wird der Wert der ProgressBar beim Ablaufen angepasst, sodass die Animation entsteht. Sobald 60
Sekunden abgelaufen sind, wird die Nachricht "Minute ist vorbei!" ausgegeben.
Definition of Done(DoD):
Vorraussetzung: UI - Mockup umgesetzt, Datenstruktur für Kandidaten fertig
Jedes UI-Element der Kandidaten soll zu beginn des Spieles einen nicht bereits verwendeten Kandidaten als Script oder
Objekt im Script zugeordnet bekommen.
Entwicklertagebuch
Der Ansatz, die Kandidaten als Teil der UI- oder Drag&Drop Szene statisch hineinzuladen wurde verworfen.
Stattdessen wurde eine szene mit einem Kandidaten erstellt. Dieser Besteht aus der Textur selbst, dem Label und einem Skript,
welches sowohl die Kandidaten-Daten als auch die Funktionalitäten eines Drag&Drop Items vereint.
Definition of Done(DoD):
Einmal das Projekt im jetzigen Zustand bauen und in Web anzeigen lassen.
Probleme/Auffälligkeiten dokumentieren.
Entwicklertagebuch
Die Ergebnisse dieser Aufgabe sind im Teil zum Export des Spieles dokumentiert.
Definition of Done(DoD):
Der grüne und der rote Button sollten ein Skript bekommen, in dem eine Referenz zu dem Kandidatenslot besteht.
Bei einem Button Press soll der Kandidat aus dem Kandidatenslot gelesen werden.
Es wird ermittelt, ob die richtige Entscheidung getroffen wird, mit einem Vergleich des isMalware Attribut mit der Art
des Buttons
Name der function "receive_candidate"
(die unterscheidung des Button kann in Metadaten/Properties getroffen werden, damit kein eigenes Skript geschrieben
werden muss)
Entwicklertagebuch
Buttons bekommen beide das evaluation_button.gd-Skript.
Die Unterscheidung zwischen "Genehmigen" und "Ablehnen" Button wird über das im Editor setzbare attribut "is_green" dargestellt.
Buttons erhalten eine Referenz, wenn ein Kandidat in das Controlpanel eingefügt wird.
Wenn der Button betätigt wird, wird die Bewertung mit den Kandidatendaten abgeglichen und mitsamt der punishmentId an den GameManager geschickt.
Zusätzlich wird in diesem Skript die Anzahl der verbleibendenden Kandidaten getrackt, sodass die Siegbedingung ausgelöst werden kann.
Definition of Done(DoD):
Alle Lilanen Boxen sollten als Drag & Drop Ziele fungieren und ein Skript mit einer Referenz auf den in ihnen liegenden
Kandidaten besitzen.
Entwicklertagebuch
Funktionalität wurde bereits in Issue #6, #10, #11 und #12 umgesetzt.
Definition of Done(DoD):
momentan kann man mehrere draggable items anclicken und gleichzeitig bewegen.
Implementierungsvorschlag: Schranke/Lockable Resource die global trackt ob gerade ein Item gedraggt wird
Entwicklertagebuch
Dieses Problem wurde dadurch gelöst, dass bei jedem Drag eine
Abfrage hinzugefügt wurde,
ob sich bereits ein anderes Child-Element auf dem DragLayer befindet. Falls der Wert größer als 0 ist, findet ein return statt.
Dadurch hat sich allerdings auch die Anzeige des Infotextes in der Mitte geändert, wobei dort dann falsche Texte angezeigt wurden, da die
dazugehörige Funktion auch mit dem ersten Mausklick des Ziehvorganges gestartet wird. Dies wurde behoben, indem die Abfrage der
Child-Elemente an dieser Stelle eben falls implementiert wurde.
Definition of Done(DoD):
Drop Target soll nur einen Kandidaten nehmen können
Entwicklertagebuch
Das Problem wurde innerhalb von
candidate_node.gd
in der snap_to_container-Methode behoben. Indem hier abgefragt wird, ob die Anzahl der Child-Elemente in diesem
Container größer als 0 ist, also ob sich hier bereits ein Item in diesem Container befindet. Falls das der Fall ist, wird das
Item wieder mit dem Warteschlangen-Container gereparentet. Damit das Element auch visuell zurück in die Warteschlange gesetzt wird,
geschieht danach ein Aufruf von queue_container.move_child(self, queue_container.get_child_count() - 1). Damit wird das
Item an die unterste Position geschoben.
Definition of Done(DoD):
Gewonnen: es existieren keine Kandidaten mehr
implementierungshinweis: alle kandidaten beim erstellen in eine Gruppe tun und dann immer wenn der Bewertungsbutton(eval) nach dem "free_queue" aufruf schauen, ob noch nodes in der Gruppe sind
Lose: Timer Abgelaufen, zu oft(fürs erste 5 x) falsch geraten(lässt sich als teil der "invoke_consquences"- methode im game manager gut tracken)
Entwicklertagebuch
Damit die Win-Condition funktioniert, werden alle Kandidaten bei der Erstellung im Skript
candidate_creation.gd
der Gruppe "candidate_nodes" hinzugefügt. Die Größe dieser Gruppe wird dann in der _button_pressed-Methode des
evaluation_button.gd-Skriptes
geprüft. Wenn diese kleiner als oder gleich eins ist, befinden sich keine Kandidaten mehr in der Warteschlange und der
Win-Screen wird über einen
change_scene_to_file-Aufruf
geladen. Die erste Lose-Condition mit zu vielen falschen Antworten wurde mit einer failCount-Variable im
game-manager.gd-Skript
realisiert. Diese wird global deklariert und in der _ready-Methode mit dem Ausgangswert 0 initialisiert. Mit einer
if-Abfrage, ob die bereits vorhandene right_guess-Variable False ist, wird der Wert der
failCount-Variable erhöht. Liegt dieser bei fünf Fehlversuchen, wird der Lose-Screen geladen. Die zweite Lose-Condition
mit dem abgelaufenen Timer wurde bereits beim Anlegen der Szenenstruktur implementiert.
Definition of Done(DoD):
Mock-Kandidaten-Daten erweitern & verbessern
Entwicklertagebuch
Die candidates.json-Datei wurde um mehr Kandidaten ersetzt.
Zusätzlich haben die Kandidaten andere Beschreibungen erhalten. Die erweiterte Datei wurde neu abgespeichert.
Überblick
Das Deployment eines Godot-basierten Serious Games für das Web umfasst mehrere Schritte:
den HTML5-Export aus der Engine, den Transfer auf einen Server und die korrekte
Konfiguration des Webservers. Dabei spielen moderne Web-Sicherheitsstandards
wie Secure Context und Cross-Origin Isolation eine zentrale Rolle,
die häufig zu unerwarteten Problemen führen.
Die Bereitstellung von Spielen über den Browser hat in der Serious-Games-Forschung
besondere Bedeutung: Web-basierte Distribution senkt die Einstiegshürde für Lernende
erheblich, da keine Installation erforderlich ist (Prensky, 2001). Gleichzeitig stellt
die Browser-Plattform spezifische technische Anforderungen, die im Folgenden erläutert werden.
Schritt 1: Godot HTML5-Export
Godot kompiliert das Projekt mithilfe von WebAssembly (WASM) in ein
browserlauffähiges Format. WebAssembly ist ein von Mozilla, Google, Microsoft und Apple
gemeinsam entwickelter Standard (W3C, 2019), der es ermöglicht, kompilierten Code
nahezu nativ im Browser auszuführen.
In Godot: Projekt → Export → Hinzufügen → Web
Export-Template herunterladen (falls nicht vorhanden)
Der Export erzeugt folgende Dateien, die alle benötigt werden:
Datei
Funktion
Pflicht?
index.html
Einstiegspunkt, lädt Engine und Assets
Ja
*.js
JavaScript-Laufzeit der Godot-Engine
Ja
*.wasm
WebAssembly-Modul (kompilierte Engine)
Ja
*.pck
Gepackte Assets, Szenen und Skripte
Ja
*.png
Splash-Screen / Boot-Bild
Optional
Icons
Für Touch-Geräte (Progressive Web App)
Optional
ⓘ Wichtig: Fehlende Dateien führen zu Fehlern wie „Fail to fetch"
oder einem weißen Bildschirm. Immer den gesamten Export-Ordner hochladen.
Godot Engine Documentation (2024). Exporting for the Web.docs.godotengine.org
W3C (2019). WebAssembly Core Specification.w3.org
Schritt 2: Zugriff auf den Server (SSH)
Für das Deployment wird ein Linux-Server mit SSH-Zugang benötigt (in unserem Fall
eine Ubuntu 24.04 VM der HTWK Leipzig). Der Zugriff erfolgt über PuTTY
(SSH-Client für Windows).
Verbindung öffnen → Benutzername und Passwort eingeben
ⓘ Hinweis: Immer die IP-Adresse verwenden, nicht den
Hostnamen – dieser kann auf einen Proxy verweisen und ist für SSH nicht geeignet.
Schritt 3: Dateien auf den Server übertragen
Für den Dateitransfer gibt es zwei bewährte Methoden:
Methode
Tool
Vorteile
Kommandozeile
PSCP (Teil der PuTTY-Suite)
Schnell, skriptbar, kein Extra-Tool
Grafisch
WinSCP
Drag-and-Drop, übersichtlich
Upload mit PSCP (PowerShell auf dem lokalen PC)
Zielordner auf dem Server erstellen (in PuTTY/SSH):
mkdir -p /home/stud/chainguard
Upload starten (in PowerShell, nicht in PuTTY!):
pscp.exe -r "B:\Projekt_Godo\export" stud@[SERVER-IP]:/home/stud/chainguard
Auf dem Server prüfen:
ls -la /home/stud/chainguard/export
ⓘ Typische Fehler:
• unable to open: failure → Zielordner existiert nicht → erst mkdir -p
• No such file or directory → Falsches Arbeitsverzeichnis → einen Ordner höher wechseln
• command not found → PSCP auf dem Server statt auf dem PC ausgeführt
Schritt 4: Webserver einrichten (Apache)
Für den permanenten Betrieb wird ein vollwertiger Webserver empfohlen.
Apache HTTP Server ist der am weitesten verbreitete Webserver weltweit
(Netcraft, 2024) und eignet sich besonders für statische Inhalte wie Godot-HTML5-Exporte.
Das Spiel ist nun unter http://[SERVER-IP]/chainguard erreichbar.
Schnelltest ohne Apache (Python)
Für schnelle Tests ohne Installation eignet sich Pythons eingebauter HTTP-Server:
cd /home/stud/chainguard/export
python3 -m http.server 8080 --bind 0.0.0.0
Erreichbar unter http://[SERVER-IP]:8080 (VPN muss aktiv sein).
Schritt 5: Secure Context und HTTPS
Ein häufiges Problem bei Godot-Web-Exports ist die Fehlermeldung:
⚠ Error:„The following features required to run Godot projects on
the Web are missing: Secure Context – Check web server configuration (use HTTPS)"
Moderne Browser erzwingen für bestimmte APIs (insbesondere SharedArrayBuffer,
das Godot für Multi-Threading nutzt) einen Secure Context. Laut
W3C-Spezifikation gilt ein Kontext als „sicher", wenn er über HTTPS oder von
localhost ausgeliefert wird (W3C, 2021).
Zusätzlich erfordern moderne Browser Cross-Origin Isolation durch
zwei HTTP-Header, damit SharedArrayBuffer verfügbar ist
(Mozilla MDN, 2024):
In Godot: Projekt → Export → Web → Threads: Off (Single-Threaded).
Dadurch wird SharedArrayBuffer nicht mehr benötigt und das Spiel
funktioniert auch ohne HTTPS. Performanceeinbußen sind je nach Projekt minimal.
Lösung B: Cross-Origin-Header setzen (Apache)
# In /etc/apache2/sites-available/000-default.conf
# Innerhalb des <VirtualHost *:80> Blocks:
Header always set Cross-Origin-Opener-Policy "same-origin"
Header always set Cross-Origin-Embedder-Policy "require-corp"
# Headers-Modul aktivieren:
sudo a2enmod headers
sudo systemctl restart apache2
Lösung C: HTTPS mit Self-Signed Certificate (empfohlen für Produktion)
Für einen vollständig konformen Secure Context wird HTTPS benötigt.
Auf einer VM ohne öffentliche Domain eignet sich ein selbstsigniertes Zertifikat:
Das Spiel ist dann unter https://[SERVER-IP]/chainguard erreichbar.
Der Browser zeigt eine Zertifikatswarnung (da selbstsigniert) – über
„Erweitert → Fortfahren" kann diese akzeptiert werden.
W3C (2021). Secure Contexts.w3.org
Mozilla MDN (2024). SharedArrayBuffer: Security requirements.developer.mozilla.org
DigitalOcean (2024). How To Create a Self-Signed SSL Certificate for Apache in Ubuntu.digitalocean.com
Schritt 6: Updates deployen
Beim Aktualisieren des Spiels sollte der alte Inhalt vollständig ersetzt werden,
um veraltete Dateien zu vermeiden:
# 1. Alten Inhalt auf dem Server löschen
sudo rm -rf /var/www/html/chainguard/*
# 2. Neuen Export hochladen (PowerShell auf dem PC)
pscp.exe -r "B:\Projekt_Godo\export\*" stud@[SERVER-IP]:/home/stud/chainguard/
# 3. Ins Webverzeichnis kopieren (SSH auf dem Server)
sudo cp -r /home/stud/chainguard/* /var/www/html/chainguard/
sudo chown -R www-data:www-data /var/www/html/chainguard
sudo chmod -R 755 /var/www/html/chainguard
sudo systemctl reload apache2
# 4. Im Browser: Strg+F5 (harter Reload, Cache umgehen)
Schritt 7: Begleitende Website deployen
Neben dem Spiel selbst kann auch eine begleitende Website (z.B. dieses Tutorial)
auf demselben Server bereitgestellt werden. Beide Projekte liegen in separaten
Ordnern im Apache-Webroot und sind unabhängig voneinander erreichbar.
Dieses Vorgehen entspricht dem Prinzip der Separation of Concerns
(Martin, 2003): Das Spiel und die Dokumentation sind getrennte Artefakte mit
eigenem Deployment-Zyklus.
Verzeichnisstruktur auf dem Server
Server-Pfad
URL
Inhalt
/var/www/html/chainguard/
https://[IP]/chainguard
Godot-Spiel (HTML5-Export)
/var/www/html/tutorial/
https://[IP]/tutorial/main.html
Tutorial-Website
Upload und Einrichtung
# 1. Website hochladen (PowerShell auf dem PC)
pscp.exe -r "B:\Projekt_Godo\Website\src" stud@[SERVER-IP]:/home/stud/tutorial
# 2. Ins Webroot kopieren (SSH auf dem Server)
sudo mkdir -p /var/www/html/tutorial
sudo cp -r /home/stud/tutorial/src/* /var/www/html/tutorial/
sudo chown -R www-data:www-data /var/www/html/tutorial
sudo chmod -R 755 /var/www/html/tutorial
sudo systemctl reload apache2
ⓘ Hinweis: Beide Projekte (Spiel und Website) sind vollständig
unabhängig voneinander. Das Aktualisieren des eines hat keinen Einfluss auf das
andere. Man kann aus der Website direkt auf das Spiel verlinken mit
<a href="/chainguard/index.html">Spiel starten</a>.
Zusammenfassung: Deployment-Pipeline
Phase
Tool / Ort
Aktion
1. Export
Godot (lokal)
Projekt → Export → Web
2. Transfer
PSCP / WinSCP (lokal)
Dateien per SSH auf den Server laden
3. Deploy
SSH (Server)
Dateien ins Apache-Webroot kopieren
4. HTTPS
Apache (Server)
SSL-Zertifikat + Secure Context konfigurieren
5. Website
PSCP + SSH (Server)
Tutorial-Website in separaten Ordner deployen
6. Test
Browser (lokal)
https://[IP]/chainguard + /tutorial aufrufen
Weiterführende Literatur
Godot Engine Docs (2024). Exporting for the Web
(Link), Zugriff 01. April 2026
W3C (2019). WebAssembly Core Specification
(Link), Zugriff 29. März 2026
W3C (2021). Secure Contexts
(Link), Zugriff 06. April 2026
Mozilla MDN (2024). SharedArrayBuffer
(Link), Zugriff 03. April 2026
Haas, A. et al. (2017). Bringing the Web up to Speed with WebAssembly. Proc. ACM SIGPLAN Conference on Programming Language Design and Implementation.
Prensky, M. (2001). Digital Game-Based Learning. McGraw-Hill.
DigitalOcean (2024). Self-Signed SSL Certificate for Apache in Ubuntu
(Link), Zugriff 07. April 2026
Einige Aspekte der Postproduction sind für Spiele im Kontext einer Abschlussarbeit oder für sonstige
Projekte im Hochschulkontext meist nicht von hoher Wichtigkeit, da es in diesen Kontexten zum Beispiel
oft keine Vermarktung braucht, welche im Normalfall ein Teil der Postproduction ist. Allerdings gibt
es einen Postproduction-Aspekt der besonders bei Serious Games sehr wichtig ist: Das Play-Testing.
Erst durch das Play-Testing kann festgestellt werden, ob ein Serious Game wirklich seinen Zweck erfüllt.
Im nachfolgenden Kapitel finden sich einige Hinweise zum Play-Testing bei Serious Games. Außerdem wird
kurz erklärt, wie Updates und Patches über Godot ausgerollt werden, falls das Projekt irgendwann erweitert
oder aktualisiert werden soll.
Play-Testing und Feedback
Anders als bei Spielen, die nicht den Serious Games zuegordnet werden können, ist bei Serious Games
das Feststellen des Lernfortschrittes neben den gewöhnlichen Aspekten des Play-Testing ein sehr
wichtiger Punkt, da ein Serious Game erst seinen Zweck erfüllt, wenn eine Lernentwicklung erreicht
werden kann. Der Fokus in diesem Unterkapitel liegt deswegen nicht auf den klassischen Gesichtspunkten
des Play-Testing, sondern lediglich auf das Testen des Lernfortschrittes.
Bei dem Play-Testing von Serious Games sollte es nach
Symborski, et al.
4 verschiedene Phasen geben.
Die ersten drei davon finden direkt hintereinander statt: Einen Pre-Test, bei dem der aktuelle Wissensstand
vor dem Spielen geprüft wird, das Spiel an sich, sowie ein Post-Test, bei dem der Wissenstand direkt nach
dem Spiel geprüft wird. Durch das Vergleichen des Pre-Tests und des Post-Tests wird der direkte
Unterschied des Lernfortschrittes vor und nach dem Spiel erkenntlich. Für die Feststellung von
Langzeiteffekten gibt es die vierte Phase: Den Follow-Up-Test, der einige Wochen nach den ersten drei
Phasen durchgeführt werden soll. In der Veröffentlichung von
Symborski, et al.
wird die letzte Phase noch
in zwei Tests unterteilt: Einer nach 8 Wochen, der andere nach 12. Für Projekte im Kontext des Studiums
können hier durchaus kürzere Abstände gewählt werden, da in solchen Projekten oft Zeitmangel besteht.
Die zwei Teile der letzten Phase haben nach
Symborski, et al.
unterschiedliche Aspekte, die gestestet
werden sollen. Im der folgenden Aufzählung befinden sich diese Aspekte unterteilt in den zwei Teilen:
Erster Teil (Nach 8 Wochen)
Confirmation Bias: Nur Infos suchen, die eigene Meinung bestätigen
Fundamental Attribution Error: Verhalten anderer wird auf deren Persönlichkeit zurückgeführt
Bias Blindspot: Man erkennt Bias bei anderen, aber nicht bei sich selbst
Zweiter Teil (Nach 12 Wochen)
Anchoring Bias: Erste Information beeinflusst Entscheidung stark
Representativeness Heuristic: Entscheidungen, weil etwas typisch wirkt
Projection Bias: Projektion eigener Einschätzung auf andere
Hierbei ist zu beachten, dass nicht bei jedem Projekt jeder Bias wichtig ist und getestet werden muss.
Die Tests von den verschiedenen Biases wurden von
Barton, et al.
genauer beschriebenen, wobei die Grundstruktur
immer der Vergleich der eigenen Antwort mit den korrekten Antworten ist. Die Abweichung zur richtigen Antwort
stellt den Messwert dar.
Wartung und Updates
Updates und sonstige Patches, die neuen Content oder Bugfixes enthalten, werden in Godot über sogenannte
Rescourcepacks ausgeliefert, welche in Godot entweder als
PCK- oder ZIP- Dateien exportiert werden.
Darin können sich alle möglichen Dateitypen, wie beispielsweise Skripte, Szenen und Texturen befinden. Es ist
auch möglich weitere Godot-Projekte in den Rescourcepacks zu speichern, welche dann während der Laufzeit
des ursprünglichen Projektes geladen werden.
Der Unterschied zwischen den PCK- und ZIP-Files besteht darin, dass die PCK-Files nicht komprimiert sind,
die ZIP-Files allerdings schon. Dadurch sind die PCK-Files größer als die ZIP-Files. Allerdings ist ein
PCK-File gegenüber eines ZIP-Files schneller lesbar, da hier der Inhalt ohne Komprimierung vorliegt. Es
ist also abhängig von Faktoren, wie Größe der Inhalte und gewünschte Performance, welcher Dateityp für
das Rescourcepack sinnvoller ist.
Das Exportieren der Rescourcepacks in Godot erfolgt über Projekt > Exportieren... > PCK/ZIP exportiern... oder über
die Commandline. Die Rescourepacks können dann später im Code manuell mit einem Aufruf von
ProjectSettings.load_rescource_pack geladen werden.
Projekt > Exportieren...
Durch das Nutzen von Rescourcepacks können nicht nur Updates und Patches, sondern auch Mods ausgerollt
werden.
Symborski et al. The Design and Development of Serious Games Using Iterative Evaluation
(Link),
Zugriff 03. April 2026
Barton et al. The Use of Theory in Designing a Serious Game for the Reduction of Cognitive Biases
(Link),
Zugriff 05. April 2026
Godot Engine 4.6 documentation in English Exporting packs, patches, and mods (Link),
Zugriff 03. April 2026
Godot Engine 4.6 documentation in English Exporting projects (Link),
Zugriff 03. April 2026