mehr Hände

27. April 2009

Vorsicht, eine „damals, als“ Geschichte:

Damals, als ich mir als Spieler die relativ neue Dämonenrüstung besorgt hatte, konnte ich diese als Exxe noch anziehen. Ja, ursprünglich gab es die Beschränkung, dass Exxen jene nicht anziehen dürfen, noch nicht.

Doch als ich sie anzog und damit kämpfen wollte, regnete es Laufzeitfehler. Cane (der Adlige, der die Rüstung geschrieben hatte) sprang zu mir und war ganz baff.

Was war passiert? Die Dämonenrüstung verändert (unter anderem) die Nat-Weapons (Jargon; zu Deutsch: natürliche Hände oder Körperwaffen? – also die Fäuste) und auch deren Anzahl. Mit letzterer Änderung der Anzahl der Fäuste/Klauen von drei auf zwei per Shadow, kam das Kampfsystem einfach nicht klar. Eine Exxe hat nämlich mit dem Exxenschwanz eine Nat-Weapon mehr als die anderen Rassen.

Seit kurzem aber verträgt das KS das Hinzufügen oder Verringern von Nat-Weapons per Shadow. Ob das bedeutet, dass die Dämonenrüstung jemals wieder für Exxen benutzbar sein wird, die Frage stelle ich mir jetzt erstmal gar nicht. Technisch ist die Möglichkeit dazu jetzt jedenfalls gegeben.

neue Efuns/Sfuns

26. April 2009

Ich weiss nie, wie aufmerksam Adlige das öffentliche Changelog (das Mudlib-Brett) lesen. Die letzten Monate haben die Einführung einiger praktischer Efuns und Lfuns (für das Living oder den Player) gezeigt. Ich möchte kurz an einige erinnern. Mögen sie ausgiebigst verwendet werden:

  • query_can_see() – (Lfun) kann das Living überhaupt sehen? Übrigens eine von Morts ursprünglichen Funktionen aus dem nKS. Erspart einem überall auf den eye_level zu prüfen.
  • equal_array() – Prüft auf Gleichheit von Elementen in einem Array. Übrigens ohne tiefe Suche.
  • flatten_array() – „Plättet“ ein 2-dim Array zu einem 1 dimensionalem.
  • delete_v_items() – man beachte das S im Funktionsnamen. Löscht alle passenden V-Items. Wurde eingebaut, weil es tatsächlich Anwender (Kräuter/Pflanzen) gab, die damit gut Evals sparen konnten (bei jedem Pflücken!).
  • message_room() – ein message(), was an alle im Raum geht (und Pseudoclosures versteht). Sehr praktisch für variable Ausgaben an alle im Raum.
  • visible() – Ist ein Objekt sichtbar. Praktisch für die Verwendung mit filter().
  • cwrap() – und andere farbcodesensitive Formatierungsfunktionen. Übrigens kommen sie auch mit MXP-Formatierungen klar.
  • unwrap() – macht ein wrap() rückgängig (so gut es geht).

Etwas ältere Neuerungen:

  • set_shrink_when_used() – (Lfun) Ein Gegenstand bindet sich an die Spielerrassenkörpergrösse.
  • set_allow_rassen_kategorie() / set_allow_sub_rassen() – (Lfun) Ein Gegenstand ist nur von einer Rassenkategorie (zB humanoid) oder Rassenuntergliederung benutzbar.
  • set_plural_class_id() – (Lfun) Den Plural der Klassen-ID setzen. Diese Möglichkeit fehlte lange.
  • execute_order() – (Lfun) Ein System, um NPCs zuverlässig die häufigsten Aktionen ausführen zu lassen.
  • format_itemlist() – Wie format_objectlist(), nur auch für Mappings. Verwendet intern die ebenfalls öffentlich erreichbare enumerate_itemlist(), was das Zusammenzählen von Gegenständen jetzt zentral macht.
  • query_weapon_forbidden() / query_armour_forbidden() – (LFun) In Gildenobjekten: eigene Handhabung von Ausnahmen.
  • lazy_readjust_xxx(alt, neu) – (LFun) beim Laden durch den Inv-Saver können alte Werte so einfacher angepasst werden. xxx steht hier für den betroffene Variable (zB lazy_readjust_max_damage). Wenn der aktuelle Wert gleich alt ist, dann setze ihn auf neu.
  • set_weapon_flag() – spezielle Einstellungen in einer Waffe. zB dass sie nie für Spieler führbar ist durch WEAPON_FLAG_NO_PLAYER (für Testwaffen).

Und hier noch ein paar sehr praktische Änderungen:

  • here() – hat ein neues Argument bekommen, was die Handhabung von „virtual commands“ deutlich erleichtert. Siehe das letzte Beispiel in der Manpage.
  • message() versteht jetzt auch Pseudoclosures.
  • query_msg_in()/… – die Bewegungsmeldungen können nun per Shadow überlagert werden.
  • Wenn man den Grammatikroutinen ein Array übergibt, schicken sie die Ausgabe vorerst durch ein format_stringlist(). Beispiel: „der(({ob1,ob2}))“ ergibt: „der ob1 und der ob2“.

virtuelle Tests

25. April 2009

Da die jüngsten Arbeiten am Kernparser Änderungen am Code zu V-Items bewirkten (Einführung von per Raum eindeutiger Identifizierung eines V-Items ohne Referenzen zu verwenden; Bugfixes bei verschachtelten V-Items; Mikroevaloptimierungen) und zukünftige Erweiterungen in der Vorbereitungsphase sind, wurde eine ausgiebige Testsuite (Unittests) für diesen Code notwendig. Die Änderungen wurden einfach zu ausfallend und ich wurde zunehmend unsicherer, schliesslich würden Spieler Regressionen im V-Item-Code sehr deutlich spüren. Also mussten ein paar automatisierte Tests her und geboren wurde /i/item/test/virtual_test.c.

Über die Jahre hinweg haben die Testsläufe für den Kernparser, der ja logischerweise viele V-Item-Abfragen generiert, immer als kleine Testsuites aus Versehen für VItems gedient, aber offensichtlich konnte man dort nicht alle Randfälle und jedes Verhalten (add/delete/change/vitem-server) von V-Items testen lassen.

Also habe ich vorletzte Woche mal ein paar solcher Tests geschrieben. Die haben natürlich gleich wieder einen Haufen Bugs zum Vorschein gebracht (die aber in der Praxis nicht so relevant zu sein scheinen), die ich dann natürlich beheben musste. Das war mir mal wieder mehr Arbeit als ich ursprünglich veranschlagt hatte. Man rechnet ja nicht damit, dass in Code, der soviele Jahre alt ist, soviele Macken stecken.

Der Hauptschuldige waren natürlich (wieder) die bösen verschachtelten V-Items.

Und als ich eine ganze Reihe von Bugfixes für die V-Items schliesslich fertig hatte, fiel mir auf, dass die Belastungstests erstaunlicherweise weniger Evals verbrauchten. Die V-Item Bugfixes brachten tatsächlich Evalverbesserungen mit sich! Na, das passiert einem nicht alle Tage.

(Wir sprechen hier übrigens wirklich nur von Mikrooptimierungen, den grössten Killer habe ich hoffentlich bereits im März erwischt.)

In Vorbereitung sind (das habe ich, glaube ich, hier schonmal kurz erwähnt) eine gehashte Indizierung, die zumindest negative Suchergebnisse beschleunigen wird und eine prinzipielle Implementierungsänderung der sogenannten „virtuellen Kommandos“ (die „e_xxx“ und „v_xxx“ Keys in V-Items) – der andere Evalkiller, der auf meiner TODO steht. Für beides ist die neue Testsuite auch unabdinglich.

Diese Woche hatte ich nicht viel Zeit, die nächste Woche steht dann ganz im Stern des Kampfsystems.

Ortschaften

20. April 2009

Zu der Erkennung der Herkunft.

Traditionell haben die paar deutschen MUDs, die eine Ortserkennung hatten, diese in einer Tabelle manuell gepflegt. Das heisst, dass (bei uns) ein Vadmin sich hinsetzen musste, und ein paar Stunden lang IP Ranges tracen musste, um zu sehen, welcher Provider im welchem Bereich welche IPs vergeben hatte und diese der korrekten Region (Stadt, Land) zuordnen musste. Naturgemäss wurde das ganze sehr wenig gewartet, wie das halt immer so ist und die Listen mit unbekannten IPs wurde länger und länger und länger … Natürlich war das für die 90er Jahre und Anfang dieses Jahrzehnts die beste Methode.

Dass diese Tabelle überhaupt so viele Jahre halbwegs befriedigend funktionierte, obwohl sie wenig gewartet wurde, lag daran, dass viele neue Spieler eh die Privatsphäre anschalten und also auch von „unbekannt“ zu kommen scheinen und das Nichtkennen grosser Provider auf „Network“ oder „Telekom“ oder sogar „Deutschland“ zurückfiel.

Seit der letzten Woche experimentieren Aleph und ich mit einer neuen Datenbank. Im Web wird zunehmend immer mehr IP-Ort Zuordnung betrieben und wir verwenden eine dafür vorgesehene (frei erhältliche) Tabelle.

Alle haben in den letzten Tagen sicherlich gemerkt, dass die Stadtnamen etwas fluktuierten. Wir mussten tatsächlich ab und an vom neuen auf das alte System zurückschalten (so wie es im Augenblick online ist), weil wir mit verschiedenen Methoden zum Einlesen und Ausgeben der neuen Tabelle experimentieren.

Mit der neuen Datenbank sind auch einige neue Probleme aufgetaucht: Sie ist erstmal weitestgehend vollständig, aber nicht immer genau. Das heisst, dass es jetzt kein „unbekannt“ mehr gibt (abgesehen von Privatsphäre) aber die Ergebnisse schonmal deutlich von der wahren Herkunftsstadt abweichen können.

Das nimmt man also wahr, als wenn die neue Ortung kaputt ist (die falschen Ergebnisse anzeigt) und die alte korrekt war (auch wenn sie nur das Nichtfinden einer IP verschleierte). Auch die generischen Providerzuordnungen: „network“, „telekom“, „AOL“ fallen weg, womit ich allerdings kein Problem habe.

Manche Zuordnungen wie „Deutschland“ – ein Fallback – sind jetzt auch nicht mehr vorgesehen.

Abgesehen von der Tatsache, dass viele neue IPs jetzt falsch (statt gar nicht) aufgelöst werden, gibt es auch das Problem der Fluktuation nach jedem Einloggen: Manche Providerranges wechseln zu schnell oder sind falsch unterteilt. Einige Benutzer bekommen so nach jedem Einloggen einen anderen Ort angezeigt.

Beide Probleme wollen wir noch angehen. Vermutlich mit der Möglichkeit, dass ein Spieler eine explizite Auswahl von Orten bekommt (die wir vorgeben anhand seiner aktuellen IP). Ideen könnten sein, in dieser Auswahl den übergeordneten Kreis (Kreisstadt) aufzunehmen, die Postleitstelle (das ist eine grössere Stadt in der Umgebung) – und vielleicht wieder „Deutschland“. Work in progress.

Ja, danke …

19. April 2009

Nachdem ich mich letztens aufgeregt habe, dass mehr Fehlermeldung abgesetzt werden sollten. Hier meine Lieblingstypen an Fehlermeldungen (höre die Ironie heraus):

  • „typo Beim Betrachten von XXX ist ein Typo.“ – Letztens hat ein Spieler – sogar in einem mehrminütigem Gespräch mit mir – darauf bestanden den Typo nicht genauer zu erläutern. Er sei ja klar. … … Jaaaa … Neeee … Danke, aber diese 5 Minuten hättest Du auch in das Ausschreiben des Typos investieren können. Wollen wir wetten, dass der Betreuer den Typo nicht auf Anhieb sieht? Unterschätze nie die Betriebsblindheit eines Adligen.
  • „idee Hier könnte eine Stadt hin.“ – Der Master Of Understatement. Früher habe ich mal Spielermeldungen so karikiert und mich köstlich amüsiert. Ja, ich habe daraus einen Witz gemacht. Bis mir jemand diesen Satz tatsächlich abgesetzt hat. … Noch nie wurden 1-2 Jahre Arbeit so knallhart zusammgengefasst.

Beide Fehlertypen – die ungenaue und unvollständige Meldung und die megalomanische Idee – weden bevorzugt sofort gelöscht.

Operas browser javascript

18. April 2009

Vielleicht dreht sich hier nicht jeder Artikel um Avalon. Ich habe gerade einen interessanten Blogeintrag gelesen zur Implementation von Operas seitenspezifischen Ausnahmenbehandlung.

Die Anweisungen erfolgen in JavaScript und greifen ins DOM der Seite ein. Sie werden zentral von Opera verwaltet und der Browser lädt sie regelmässig herunter. Mehr darüber hier.

Das, was mir besonders imponiert hat ist die Tatsache, dass das Konzept so elegant ist, dass es ohne Probleme auf alle Platformen übertragbar ist – und Opera läuft auf vielen Geräten – und schon vor Jahren eingebaut wurde . Das ist mal gutes und zukunftsträchtiges Softwaredesign!

base of operations

15. April 2009

Während wir gestern an der neuen Ortserkennung arbeiteten (das ist eine andere Geschichte), kam uns ein Geistesblitz. Naja, Geistesblitz ist auch übertrieben, die Idee gab es schon lange. Aber der Moment war da: Die Editoren und Shells geöffnet, die Lust ein neues Feature umzusetzen packte uns: Wir ordneten jedem Spieler eine „base of operations“ zu. Zu Deutsch: Ein Quartier.

Ein Quartier ist entweder die Stadt/Siedlung des eigenen Hauses oder die Genesisstadt. Es ist das Basislager, eine rollenspielerische Herkunft. Die avalonische Wunschheimat.

Das Quartier ist nicht der aktuelle Aufenthaltsort. Keine Bange.

Für Adlige ist das Quartier (im Augenblick) entweder die Basilika, für Rassenlords die Genesisstadt und für Herzöge ihre Subdomain.

Die Anwenderschnittstelle war auch schnell eingebaut: „wer -q“ (q für Quartier) ersetzt den real-life Ort durch das Rollenspiel-Quartier. Sieht ganz nett aus.

Im Finger bekommt man diese Angabe ebenfalls mit der Formatoption  „q“ (siehe „hilfe finger“ für Verwendung der Formatoptionen). Ob wir das jemals in die normale Formatvorlage fürs Finger übernehmen bleibt offen. (bei Adligen erscheint es erstmal testweise bei „finger -x“).

Warum ich nicht dafür bin, den RL Ort durch das rollenspielerische Quartier zu ersetzen: Die Wer-Liste mit Quartier ist nicht sooo abwechslungsreich. Schliesslich gibt es nur X Siedlungen und Genesisstädte. Die Angabe der RL Herkunft finde ich, wenn man mal die „Unbekannt“ ignoriert, optisch viel interessanter.

Ausfall am Ostermontag

14. April 2009

Gestern viel Warterei auf Neuigkeiten über den Server. Erstmal war nicht klar, ob der Rechner selbst betroffen war oder nur das Netz. Ein Glück lag das Problem nicht am Rechner (puh).

Nach ersten Reaktionen heute morgen denke ich, dass wir die Notfallprozeduren nochmal klarmachen sollten. Kann ja nicht angehen, dass Spieler nicht wissen, wie sie mit ihren Mitmuddern in Kontakt kommen, wenn wir mal einen kurzen Ausfall haben.

Das rosa Lila

13. April 2009

Nur kurz, ich möchte festhalten, dass wir uns tatsächlich über so etwas Gedanken machen: Wir haben einen Satz Farbadjektive indeklinabel gemacht: „rosa“, „lila“, „magenta“, einige andere …

Der Duden schreibt noch einige weitere vor, aber wir haben bei allen abgewogen zwischen korrektem Formaldeutsch und dem, was unser Sprachgefühl uns sagt. Der Duden sagt zum Beispiel, dass „orange“ nicht dekliniert werden sollte (dies sei Umgangssprache). Wir konnten uns aber mit „Einem orange Mantel“ nicht abfinden. Mal ganz davon abgesehen, dass solche populären Fehler immer dazu führen, dass sie mehrfach abgesetzt werden. Also bleibt „orange“ deklinabel.

Ich bin letztens über folgendes Problem mit Mengenbezeichnungen und diversen Kollektiva gestolpert: Es gibt wohl historisch eine Reihe von Objekten im MUD, die als „name“-Eintrag ein Wort tragen, das plural:1 fordert („die Handschuhe“ – als Rüstungsteil), aber als „pluralname“ etwas ganz anderes gesetzt haben: „Paar Handschuhe“.

„name“ und „pluralname“ haben grammatikalisch nichts miteinander zu tun. Bei letzterem ist das „Paar“ der bestimmende Teil (der Kern) und hat ein anderes Genus und einen anderen Numerus.

Warum haben Adlige dies so eingebaut? Nunja, es hat eine gewisse Ästhetik: Man nimmt „die Handschuhe“, aber sieht dort „drei Paar Handschuhe“ liegen. Ausserdem gab es bis vor Kurzem damit auch keine Probleme bei Objekt-Gegenständen, da query_cap_name() den „pluralnamen“ immer ignorierte, was aber falsch war und inkonsistent zu VItems/Mappings, wo dieser Fehler schon immer auftrat. Und da VItems/Mappings/Objekte als „Deklinations-Items“ gelten und dasselbe Verhalten an den Tag legen sollten, wurde dies geändert.

Ein Glück hat die oben erklärte Überlagerung von „name“ und „pluralname“ mit unterschiedlichen grammatikalischen Kernen Methode. Sie tritt (und kann nur) auftreten bei Mengenbezeichnungen wie z.B. „Paar“.

Der „name“-Eintrag bezeichnet dann das Gesammelte (alleinstehend und somit als Kern) und der „pluralname“ die Mengenbezeichnung als Kern und  danach das Gesammelte. „Handschuhe“ versus „Paar Handschuhe“.

Wenn man das verstanden hat, ist der Rest fast trivial. Bei mehrwortigem Pluralnamen muss man schauen, ob eine Mengenbezeichnung enthalten ist und dann Fallunterscheidungen machen: Steht die Mengenbezeichnung im Plural oder Singular? Weiss man schon, ob sie im Plural oder Singular gebraucht werden wird („ordinal“ und „kardinal“ Einträge implizieren dies). Daraus wird dann ein korrektes grammatikalisches Item gebaut, was entweder den alten „name“ (mit dessen grammatikalischer Information) verwendet oder den „pluralnamen“ mit der grammatikalischen Information, die von der erkannten Mengenbezeichnung geholt wird.

Gegebenenfalls wird also innerhalb der Grammatikroutine ein neues Deklinationsitem generiert mit den hinzugeschummelten neuen Werten. Das wäre nicht so einfach gewesen, hätte ich vor einem Jahr nicht bereits die Sefun new_deklin_item() eingeführt.

Es gibt sogar einen (aus ästhetischen Gründen) Fall, wo aus einem „pluralnamen“ mit Mengenbezeichnung im Plural eine Mengenbezeichnung im Singular gebastelt wird. Als Beispiel: „Tueten Apfelringe“ mit Ordinalzahl ergibt: „die dritte Tuete Apfelringe“.

So ist aus einem simplen Bugfix (die Änderung an Cap_name()) mal wieder eine ganze Menge mehr Arbeit geworden. War es das wert? Vielleicht. Die jetztige Lösung ist zumindest korrekt. Das Update habe ich in zwei Teilen heute Nacht und vorgestern aufgespielt und die komischen Meldungen über „Paar Handschuhe“ ohne Artikel der letzten Wochen sollten somit auch behoben sein.