12.1 Was bedeutet „guter Code“ im MUD?
Guter LPC-Code ist nicht der cleverste oder kürzeste Code.
In einem MUD ist guter Code vor allem:
- verständlich für andere (und für dich selbst in einem Jahr)
- robust gegenüber Fehlern und unerwarteten Situationen
- leicht erweiterbar
- sicher im Umgang mit fremden Objekten
- konform mit der Mudlib
Viele Anfänger versuchen, möglichst „mächtig“ zu programmieren.
Erfahrene Magier versuchen, möglichst langweiligen Code zu schreiben –
weil langweiliger Code stabil ist.
12.2 Klarer Aufbau von Objekten
Ein häufiges Anfängerproblem ist chaotischer Code:
Funktionen überall, globale Variablen ohne Struktur,
Logik im falschen Objekt.
Bewährtes Grundschema für viele Objekte:
// 1. Includes & Inherits
#include <properties.h>
inherit "/std/thing";
// 2. Konstanten & Defines
#define MAX_USES 3
// 3. Membervariablen
int uses;
// 4. create()
protected void create() {
::create();
uses = MAX_USES;
}
// 5. Öffentliche Schnittstellen (Spielerbefehle)
int cmd_use(string str) { ... }
// 6. Interne Hilfsfunktionen
protected void do_effect(object who) { ... }
Diese Reihenfolge ist keine Pflicht, aber sie hilft enorm,
sich schnell im Code zurechtzufinden.
12.3 Trennung von Verantwortung
Eine der wichtigsten Regeln guter Architektur lautet:
Ein Objekt sollte genau eine Hauptaufgabe haben.
Schlechte Beispiele:
- Ein Raum, der Quests verwaltet
- Ein Item, das Spielerlevel verändert
- Ein NPC, der globale Spielzustände speichert
Bessere Aufteilung:
- Raum: Umgebung & Beschreibung
- Item: Interaktion & Effekte
- Questobjekt: Questlogik
- Serviceobjekt: Berechnungen, Verwaltung
Wenn du merkst, dass ein Objekt immer größer wird,
ist das meist ein Zeichen, dass du es aufteilen solltest.
12.4 Lesbarkeit vor Cleverness
LPC erlaubt sehr kompakte Konstrukte.
Aber kompakt heißt nicht automatisch gut.
Schwer lesbar
if(o&&living(o)&&interactive(o)&&o->QueryProp(P_HP)>0)
o->SetProp(P_HP,o->QueryProp(P_HP)-10);
Besser lesbar
if (!objectp(o)) return;
if (!living(o)) return;
if (!interactive(o)) return;
int hp = o->QueryProp(P_HP);
if (hp <= 0) return;
o->SetProp(P_HP, hp - 10);
Ja, das ist länger. Aber Fehler lassen sich hier viel leichter finden.
12.5 Defensive Programmierung als Standard
In einem laufenden MUD können jederzeit Dinge passieren:
Spieler loggen aus, Objekte werden zerstört, Räume neu geladen.
Deshalb gilt:
- Jeder Objektzugriff kann fehlschlagen
- Jeder Funktionsaufruf kann einen Fehler werfen
- Jede Referenz kann plötzlich
0 sein
Beispiel mit catch()
mixed res;
if (catch(res = ob->DangerousCall())) {
log_file("errors", "DangerousCall failed in "+object_name(this_object())+"\n");
return;
}
Defensive Programmierung fühlt sich am Anfang „übertrieben“ an,
spart dir aber später extrem viel Zeit.
12.6 Weniger globale Variablen
Globale Variablen sind bequem, aber gefährlich.
Sie machen Abhängigkeiten unsichtbar und Fehler schwer nachvollziehbar.
Problematisch
object last_user;
void use(object who) {
last_user = who;
}
Was passiert, wenn zwei Spieler gleichzeitig interagieren?
Besser
void use(object who) {
// benutze who lokal
}
Speichere nur das, was wirklich dauerhaft zum Objekt gehört.
12.7 Logging statt stilles Scheitern
Ein häufiger Anfängerfehler ist:
Fehler passieren – aber niemand merkt es.
Schlecht
if (!ob) return;
Besser
if (!ob) {
log_file("debug", "ob missing in "+object_name(this_object())+"\n");
return;
}
Logs sind deine Augen, wenn etwas schiefgeht,
während du nicht online bist.
12.8 Zusammenarbeit & Code-Stil
LPC-Code wird selten nur von einer Person gelesen.
Achte daher auf:
- einheitliche Einrückung
- sinnvolle Funktionsnamen
- Kommentare bei nicht offensichtlicher Logik
- keine „magischen Zahlen“ ohne Erklärung
Kommentare sollten erklären warum etwas passiert,
nicht was passiert – das sieht man im Code.
12.9 Typische Anfängerfallen – zusammengefasst
- zu große Objekte
- direktes Manipulieren fremder Objekte
- fehlende Sicherheitsprüfungen
- keine Fehlerbehandlung
- übermäßig cleverer, schwer lesbarer Code
Fast jeder erfahrene Magier ist genau in diese Fallen getappt.
Wichtig ist nicht, sie nie zu machen –
sondern sie zu erkennen und daraus zu lernen.
12.10 Abschluss & Ausblick
Du hast jetzt ein vollständiges Grundlagenverständnis von LPC:
von Datentypen über Objekte, Vererbung, Events, Sicherheit
bis hin zu sauberer Architektur.
Der nächste Schritt ist Praxis:
kleine Räume bauen, Items schreiben, Code lesen,
mit erfahrenen Magiern sprechen.
Guter LPC-Code entsteht nicht über Nacht –
sondern durch viele kleine Verbesserungen.
Willkommen in der Welt der MUD-Entwicklung.
Fast fertig!
Du hast das komplette Anfänger-Manual gelesen.
Nutze es als Nachschlagewerk, kehre zu Kapiteln zurück
und erweitere dein Wissen Schritt für Schritt.
In Kapitel 13 gibt es noch ein großes Beispielprojekt zum Lernen. Das wird toll!
Weiter zu Kapitel 13
Großes Lernbeispiel – Waldlichtung zur Wikingerzeit (Raum, Hebel, Versteck, NPC, Items)