Forum moved to if-forum.org
Autor Nachricht
<  Wildgewordene Eier-Kreationen
Clive
BeitragVerfasst am: Sa, 5 Aug 2006 - 0:03  Antworten mit Zitat
Wasserträger
Wasserträger


Anmeldungsdatum: 29.08.2002
Beiträge: 60

Hallo miteinander!

Nach längerer Abstinenz hab ich vor einigen Tagen (Wochen? Die Zeit rennt...) wieder begonnen, mich mit Inform & co. auseinander zu setzen. Und weil das letzte Problem schon über nen Monat her ist, dachte ich mir: Beleben wir das Forum doch ein wenig. ;-)

Der unten stehende Glulx-Code funktioniert. Nicht immer. Ich wäre euch dankbar, wenn ihr mir sagen könntet, wo das Problem liegt, weil der Compiler sich auch nicht beschwert und die auftauchenden "Programming errors" (s.u.) mir mit meinen bescheidenen Kenntnissen nicht weiter helfen.

Zunächst mal der Code. Benutze die unglklib.h-Extension und die deutsche Library Release 22.

Code:

Constant story "Legebatterie";
Constant headline "^Ein Test zur Isolierung eines hinterhältigen, üblen, komplett unfairen und
        demoralisierenden Programmierfehlers, der in der normalen Version nur manchmal(?)
        auftritt.^^";

Constant NEWEGG_NAME_LEN 15;

Array newegg_name --> 16;

Global egg_count;

include "parser";
include "verblib";
include "unglklib";

Class   Egg(20)
 with   dekl 0,
    short_name [;
       PrintTheArray(self.&called);rtrue;
    ],
    name 'ei',
    called 0 0 0 0 0 0 0 0,
    age,
    description [;
       print "Du hast das Ei namens ";
       PrintTheArray(self.&called);
       print " vor ", self.age, " Runden produziert.";
    ],
    each_turn [; self.age++;],
 has   proper neuter;


Object   Stall "Hightech-Hühnerstall"
 with   description "Der Hühnerstall der Zukunft! Alles ist komplett steril und frei von Keimen. Das
           Vogelgrippe-Risiko liegt bei Null.",
 has   light;
 
Object   Maschine "Eiermaschine" Stall
 with   dekl 9,
    name 'maschine' 'eiermaschine',
    initial "Hier steht eine Eiermaschine mit einem Hebel.",
    description "Die Maschine hat einen Hebel, an dem man ziehen kann.",
 has   female static;
 
Object   Hebel "Hebel" Stall
 with   dekl 2,
    name 'hebel',
    description "Zieh dran, dann passiert was.",
    before [;
       Pull: print "Du ziehst am Hebel. ";
             Eierlegen();rtrue;
       Push: "Ziehen musst du ihn.";
    ],
 has   male scenery;


[Initialise;
 location = Stall;
 print_ret "^^^^Ziehe am Hebel, um ein Ei zu produzieren, das du individuell benennen kannst.^^";
];

[Eierlegen e i;
   if(egg_count==20) "Nichts passiert. Scheinen keine Eier mehr drin zu sein.";
   
   print "Es macht ~klack~ und ein Ei rollt aus der Maschine. ";
   e = Egg.Create();
   e.age = 0;
   
   GetPlayersInput("Wie willst du dieses Ei nennen?", newegg_name, NEWEGG_NAME_LEN);
   
   for (i=0:i<=newegg_name-->0:i++) {
      e.&called-->i = newegg_name-->i;
   }
      
   egg_count++;
   move e to location;
   print "Das Ei heißt nun "; PrintTheArray(e.&called); ".";   
];

include "germang";


Für alle, die unglklib.h nicht haben und sie sich nicht extra downloaden wollen, folgen hier die benutzten Routinen "PrintTheArray()" und "GetPlayersInput()" mit allem drum und dran:

Code:

Constant PLAYERS_INPUT_LEN = 120;
Array players_input ->121;

[ GetPlayersInput prompt_str out_array out_len;
! prompt_tr - string to print to prompt player
! out_array - author-defined array
! out_len   - length of author-defined array
!             (may use constant)

  print (string) prompt_str; print "  ";
  ClearArray(players_input);
  KeyboardPrimitive(players_input);
  CopyInArrayToOutArray(players_input, out_array, out_len);
];
[ CopyInArrayToOutArray in_array out_array out_len i;
  for (i=0: i<=(out_len-1): i++)
  { if (in_array->(i+WORDSIZE) == 0) break;
    out_array->(i+WORDSIZE) = in_array->(i+WORDSIZE);
  }
  if (i > out_len) i = out_len;
  out_array-->0 = i;
];
[PrintTheArray array len i ch;
  len = array-->0;
  for (i=0 : i<=(len-1) : i++)
  { ch = array->(i+WORDSIZE);
    if (ch) print (char) ch;
  }
];


Wenn man das Spiel startet und anfängt, Eier zu produzieren, läuft zunächst alles wie geplant. Dann passiert irgendwann (Zeitpunkt variiert, aber es scheint nie das erste Ei zu sein) Folgendes:

Glulxe hat folgendes geschrieben:

>zieh hebel
Du ziehst am Hebel. Es macht "klack" und ein Ei rollt aus der Maschine.
[** Programming error: Egg_19 (object number 139239) has no property age to write **]
Wie willst du dieses Ei nennen?


Gibt man nun trotzdem einen Namen ein, kann man sich auf eine Flut von verschiedenen Fehlermeldungen gefasst machen. Kompiliert man das Spiel im Debug-Mode, ändert sich an dem Ereignis oben nichts, aber von Anfang an bekommt man nach Benennung des Eis 13 Mal das zu lesen:

Glulxe debugged hat folgendes geschrieben:

>zieh hebel
Du ziehst am Hebel. Es macht "klack" und ein Ei rollt aus der Maschine. Wie willst du dieses Ei nennen? sam

[** Programming error: tried to write outside memory using --> **]
[** Noch zwölfmal dieselbe Meldung**]


Abstürzen tut das Spiel allerdings nach wie vor nur bei der ersten Fehlermeldung. Warum verliert das Ei irgendwann seine Klasse?

Ich hoffe, ihr könnt mir da weiter helfen... aber bisher wurde meine Hoffnung eigentlich nie enttäuscht. :-)

Grüße,

Clive
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Clive
BeitragVerfasst am: Sa, 5 Aug 2006 - 19:34  Antworten mit Zitat
Wasserträger
Wasserträger


Anmeldungsdatum: 29.08.2002
Beiträge: 60

Nach ein bisschen Herumprobieren hab ich herausgefunden, dass die extra-Fehlermeldung im debug-Modus wohl von der Zeile

Code:

KeyboardPrimitive(players_input);


ausgelöst wird. Scheint aber keine negativen Auswirkungen auf das Spiel zu haben. Anders sieht es mit der Zeile

Code:

e = Egg.Create();


aus. Ich hab den darauffolgenden Code der Routine mal eingepackt in eine if-Anweisung:

Code:

if(e provides age) {
    ...Rest der Routine...
}
else "[Das Ei ist korrupt und muss aus Sicherheitsgründen entfernt werden.]";


Die verhindert zumindest, dass Glulxe abstürzt. Und oh Wunder, die Anzahl der Eier hat sich in dem Fall nicht verändert.
Folglich stimmt wohl etwas mit der Create()-Routine nicht?

Das Problem kann man damit zwar leicht mit einer do-Schleife umgehen, aber die Frage bleibt: Warum funktioniert Create() hier mal und mal nicht?

Na, ich werd mal weiter testen. Sehr komisch die Sache.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Clive
BeitragVerfasst am: Sa, 5 Aug 2006 - 23:07  Antworten mit Zitat
Wasserträger
Wasserträger


Anmeldungsdatum: 29.08.2002
Beiträge: 60

Da bisher noch keine Lösung eingetrudelt ist, kann ich ja mal den Stand meiner "Nachforschungen" kundgeben, vielleicht löst das ja bei irgendwem nen Geistesblitz aus, man kann nie wissen.

Zur Vermeidung des Fehlers hab ich die Eierlegen()-Routine mit ein paar "Sicherheiten" ausgestattet:

Code:

[Eierlegen e i try;
   if(egg_count==20) "Nichts passiert. Scheinen keine Eier mehr drin zu sein.";
   
   do {
      e = Egg.Create();
      try++;
      if(try>2) "Nach zwei erfolglosen Versuchen gibt die Maschine auf. Sieht aus, als
           wär sie kaputt.";
   } until(e provides age);
   
   if(e provides age) {      
   print "Es macht ~klack~ und ein Ei rollt aus der Maschine. ";   
   if(try>1) print "Zur Erstellung des Eis waren ", try, " Versuche notwendig. ";
      
   GetPlayersInput("Wie willst du dieses Ei nennen?", newegg_name, NEWEGG_NAME_LEN);
   
   for (i=0:i<=newegg_name-->0:i++) {
      e.&called-->i = newegg_name-->i;
   }
      
   egg_count++;
   move e to location;
   print "Das Ei heißt nun "; PrintTheArray(e.&called); ".";
   }
   else "[Vorsicht! Das Ei ist korrupt und wurde aus Sicherheitsgründen entfernt!]";
];


Die Schleife löst das Problem nämlich leider nicht. Wenn es auch beim zweiten Versuch nicht gelingt, das Ei zu erschaffen, hängt Glulxe sich auf. Wahrscheinlich, weil die Schleife endlos weiter läuft, ohne jemals ein Ei erschaffen zu können. Darum hab ich das in meinem Code abgefangen.

Selten (bisher nur 2 Mal von sehr vielen Versuchen) schaffe ich es, alle 20 Eier zu benennen, ohne dass es ein Problem gibt. Meistens kommt irgendwann am Anfang die Nachricht, dass die Maschine zwei Versuche benötigt hat.
Sobald es soweit ist, lässt auch der komplette Fehlschlag nicht lange auf sich warten, d.h. die Maschine "geht kaputt" und kann auch in nachfolgenden Zügen keine Eier mehr kreieren, bis man das Spiel neustartet.
Leider hab ich bisher auch die Create()-property/routine (?) nirgendwo in den libraries finden können... ich glaub nun stehe ich endgültig auf dem Schlauch.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Sophie
BeitragVerfasst am: So, 6 Aug 2006 - 9:18  Antworten mit Zitat
Wasserträger
Wasserträger


Anmeldungsdatum: 06.06.2005
Beiträge: 59
Wohnort: 46° 38' N 14° 20' O

Clive hat folgendes geschrieben:
Leider hab ich bisher auch die Create()-property/routine (?) nirgendwo in den libraries finden können... ich glaub nun stehe ich endgültig auf dem Schlauch.

Ich mach sowas nie, deswegen kenn ich mich da nicht aus, aber ist Create nicht eine property, die du selber definieren musst?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Clive
BeitragVerfasst am: So, 6 Aug 2006 - 14:59  Antworten mit Zitat
Wasserträger
Wasserträger


Anmeldungsdatum: 29.08.2002
Beiträge: 60

Selber definieren? Wie meinst du das?
In DM4 3.11 wird .create erklärt und ist normalerweise ebenso einfach anzuwenden.

Ich glaube ich habe den Fehler aber entdeckt. Ich muss noch ein bisschen testen, aber bisher klappt jetzt alles wie geplant. Der Wurm liegt da begraben:

Code:

Class   Egg(20)
 with   
    (...)
    called 0 0 0 0 0 0 0 0,


Das sind acht Platzhalter, die Konstante NEWEGG_NAME_LEN lässt aber 15 Buchstaben zu. Wenn ich nun einem Ei einen Namen mit mehr als acht Buchstaben gebe, wird das darauffolgende Ei erst beim zweiten Mal erfolgreich kreiert.
Trotzdem wird auch die erste versuchte Kreation als erschaffene Instanz gewertet und somit ist die Maschine nicht erst nach 20 Eiern leer sondern nach 20 Versuchen, ein Ei zu erschaffen.

Warum immer nur das nächste Ei davon betroffen ist, kann ich mir allerdings nicht erklären. Hat da jemand von den Hobby-Programmierern vielleicht nen Erklärungsansatz?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Martin
BeitragVerfasst am: Mo, 7 Aug 2006 - 7:43  Antworten mit Zitat
Experte
Experte


Anmeldungsdatum: 25.08.2002
Beiträge: 677
Wohnort: München

Sophie hat folgendes geschrieben:
Ich mach sowas nie, deswegen kenn ich mich da nicht aus, aber ist Create nicht eine property, die du selber definieren musst?

Man kann einen eigenen Konstruktor definieren, der dann auch create heißt. Aber auch, wenn der nicht definiert ist, kann man obj.Create() aufrufen, das dann ein generisches Objekt erzeugt. Vorausgesetzt, man hat oben in der Klassendeinition eine Anzahl mit Klammern angegeben, natürlich.

Clive hat folgendes geschrieben:
Das sind acht Platzhalter, die Konstante NEWEGG_NAME_LEN lässt aber 15 Buchstaben zu. Wenn ich nun einem Ei einen Namen mit mehr als acht Buchstaben gebe, wird das darauffolgende Ei erst beim zweiten Mal erfolgreich kreiert.

Das ist kein Fehler. Einträge in Properties, auch wenn es Felder sind, sind Wörter, also zwei Bytes im z-Code und vier Bytes in Glulx. Da Zeichen in beiden Fällen nur in Bytes abgelegt werden - ZSCII in z-Code und ISO-8859-1 in Glulx - kannst du unter Glulx mit 8 Wörtern 32 Zeichen ablegen. Die 15 kommt gewiss aus einem z-Code-Beispiel und hat ein Null-Byte angehängt, um das Ende des Strings zu kennzeichnen. (Der featureless-cube-Code?)

In deinem Code machst du aber folgendes:
Code:

   for (i=0:i<=newegg_name-->0:i++) {
      e.&called-->i = newegg_name-->i;
   }

Wichtig sind hier die Pfeile. Du greifst auf Wörter zu mit -->. Die Routine PrintTheArray benutzt korrekterweise einfache Pfeile ->, die auf Bytes zugreifen. Also muss es heißen:
Code:

   for (i=0:i<=newegg_name-->0:i++) {
      e.&called->i = newegg_name->i;
   }

Der erste Pfeil sollte, glaube ich, doppelt sein, denn die Anzahl der Bytes in einem Inform-Buffer wird durch ein Wort gekennzeichnet.

Wenn man ein normales Feld überschreibt, macht man damit die nachfolgenden Felder kaputt. Wenn man über die Grenzen einer Property hinaus schreibt, kommt der ganze Property-Table durcheinander und Inform, kann Werte nicht mehr Properties zuordnen. In deinem Fall scheint sogar der Property Table des nachfolgenden Objekts kaputt geschrieben worden zu sein, daher tritt der Fehler erst beim zweiten Ei auf.
_________________
Every silver lining has a cloud.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Clive
BeitragVerfasst am: Mo, 7 Aug 2006 - 19:33  Antworten mit Zitat
Wasserträger
Wasserträger


Anmeldungsdatum: 29.08.2002
Beiträge: 60

Martin hat folgendes geschrieben:

Die 15 kommt gewiss aus einem z-Code-Beispiel und hat ein Null-Byte angehängt, um das Ende des Strings zu kennzeichnen. (Der featureless-cube-Code?)


Die 15 kommt auch aus der unglklib.h :
Code:

! Example:

! Constant FIRST_NAME_LEN = 15;    author-defined array
! Array first_name ->16;           length of author-defined array

Denn eigentlich will ich ja auch keine Eier benennen ;)
Wobei mir jetzt auch auffällt, dass der Beispiel-Array nur einen einfachen Pfeil hat... ich schätz mal, ich bin beim gleichzeitigen Nachschlagen im DM4 oder dergleichen etwas durcheinander gekommen.

Martin hat folgendes geschrieben:

Wichtig sind hier die Pfeile. Du greifst auf Wörter zu mit -->. Die Routine PrintTheArray benutzt korrekterweise einfache Pfeile ->, die auf Bytes zugreifen.
...
Der erste Pfeil sollte, glaube ich, doppelt sein, denn die Anzahl der Bytes in einem Inform-Buffer wird durch ein Wort gekennzeichnet.

Ahh.... und ich dachte die Pfeile kennzeichnen nur den Typ des Arrays. Das Problem hierbei ist nur, dass ich bei einem string-Array keinen -> Zuweiser verwenden kann (in dem Fall werden die letzten drei Buchstaben abgeschnitten....), wovor mich auch der Compiler warnt.
Definiere ich nun einen byte-Array, kann ich dagegen nicht mehr die Länge des Arrays abrufen. Wahrscheinlich der Grund, warum der Autor der unglklib.h eine Konstante als Hilfe verwendet hat.

Bei den "featureless white cubes" wird auch eine Hilfskonstante in Form einer Property verwendet, um die Länge des Array festzuhalten... na, vielleicht ist es ja einfach die bessere Methode. *g*
EDIT: Das bezieht sich auf die "light"-Version der cubes im DM4 (seh grad, dass es im richtigen Spiel etwas anders ist)

Martin hat folgendes geschrieben:

In deinem Fall scheint sogar der Property Table des nachfolgenden Objekts kaputt geschrieben worden zu sein, daher tritt der Fehler erst beim zweiten Ei auf.

Ah, und darum klappt das Kreieren des dritten Eis auch wieder... danke!

Wahrscheinlich ist dieses Vermischen von byte- und string-Array auch der Grund, warum mein nachfolgender Versuch, eine parse_name-Routine für die Eier zu schreiben (diesmal nach dem Vorbild der "featureless white cubes", von mäßigem Erfolg gekrönt war:
EDIT: Das bezieht sich auf die "light"-Version der cubes im DM4 (seh grad, dass es im richtigen Spiel etwas anders ist)

Glulxe Test hat folgendes geschrieben:

Du siehst hier auch Tanja und Sonja.

> u tanja
Wen meinst du, Tanja oder Sonja?

Deine Antwort: Sonja
Wen meinst du, Tanja oder Sonja?


Denn so hat die Routine zwar die Länge abgleichen können, aber nicht sämtliche Buchstaben Wobei z.B. "Maren" (auch 5 Buchstaben) nicht als "Tanja" erkannt wird. Und "Anne" wird auch nicht mit "Anna" gleichgesetzt, wohl aber "Enna".
Ich probier mal eine Grunderneuerung meiner Arrays.

Vielen Dank, Martin! Mal wieder was dazugelernt.

Was mich allerdings noch wundert ist dann, dass die Namenszuteilung selbst einwandfrei funktioniert, wenn ich self.&called um genug Platzhalter erweitere, obwohl ich mit --> auf ein Wort statt ein Byte zugreife.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Martin
BeitragVerfasst am: Di, 8 Aug 2006 - 7:22  Antworten mit Zitat
Experte
Experte


Anmeldungsdatum: 25.08.2002
Beiträge: 677
Wohnort: München

Clive hat folgendes geschrieben:
Ahh.... und ich dachte die Pfeile kennzeichnen nur den Typ des Arrays. Das Problem hierbei ist nur, dass ich bei einem string-Array keinen -> Zuweiser verwenden kann (in dem Fall werden die letzten drei Buchstaben abgeschnitten....), wovor mich auch der Compiler warnt.

Die Pfeile kennzeichnen den Modus, mit dem auf das Array zugegriffen wird. Bei der Definition geben sie an, wieviele Bytes freigahelten werden.

Clive hat folgendes geschrieben:
Definiere ich nun einen byte-Array, kann ich dagegen nicht mehr die Länge des Arrays abrufen. Wahrscheinlich der Grund, warum der Autor der unglklib.h eine Konstante als Hilfe verwendet hat.

Doch. Es ist legal, auf Wort-Arrays mit -> und auf Byte-Arrays mit --> zuzugreifen. Der Autor muss nur wissen, was er macht.

Code:

    Array wa --> 12;
    Array ba -> 48;

Beide Arrays haben (in Glulx) 48 Bytes und 12 Wörter, und ich kann natürlich die Bytes eines Worts einzeln "extrahieren". Das eventuelle Gemeckere des Compilers kannst du mit Hilfsvariablen umgehen:
Code:

    [ MyRoutine x;
        x = wa;
        if (wa->0 == 'q') return false;
        return true;
    ];

Oder natürlich eigene Routinen schreiben, die dem Compiler die Natur der Felder verschleiern:
Code:

    [ GetByteAt a n; return a->n; ];
    [ GetWordAt a n; return a-->n; ];
    [ SetByteAt a n i; a->n = i; ];
    [ SetWordAt a n i; a-->n = i; ];


(Ein Feld ist nichts anderes, als eine Adresse im Speicher, ab der die angegebene Anzahl von Bytes freigehalten wird. arr->i bedeutet: Hole mir das byte an der Stelle arr + i; arr-->i bedeutet: Hole mit das Wort an der Stelle arr + 4*i. Deshalb beginnen die Indizes auch immer mit Null, nucht mit Eins.)

Die ganze Array-Sache ist nicht ganz einfach, besonders weil der Z-Code und Glulx selbst Mischfelder, also Felder, auf die man mit -> und --> zugreifen muss, verwenden.

Die Faustregel ist, immer Wort-Felder zu verwenden. Lediglich bei Zeichenketten (die allerdings häufig vorkommen), ist es sinnvoll, Bytes zu verwenden, weil sie einfach weniger Platz benötigen. Und dann muss man aufpassen, ob man ein Byte-Array (n Werte), einen String (n + 1 Werte wie bei Pascal, das erste Byte ist die Länge der belegten Zeichen im String) oder einen Buffer (n + 4 Werte, das erste Wort gibt die Anzahl der belegten Bytes, die folgen, an) verwendet. Die Glulx-eigenen Routinen verwenden meist Buffer.

Clive hat folgendes geschrieben:
Denn so hat die Routine zwar die Länge abgleichen können, aber nicht sämtliche Buchstaben

Oh! Hier musst du aufpassen, welche Daten du übertragen willst. Wenn in newegg_name-->0 die Länge des Strings steht, liegen die Daten natürlich in den Bytes ab newegg_name->(i+2):

Code:

   for (i=0 : i < newegg_name-->0 : i++) {
      e.&called->(i) = newegg_name->(i + 2);
   }
   e.called_length = newegg_name-->0;

(Dieser Code nimmt an, dass der Name und dessen Länge im Objekt in getrennten Properties gespeichert werden.) Wenn du wirklich wissen willst, ob alle Buchstaben korrekt übertragen werden, könntest du in der Schleife die kopierten Buchstaben ausgeben lassen. Dann siehst du schnell, was noch fehlt.

Clive hat folgendes geschrieben:
Bei den "featureless white cubes" wird auch eine Hilfskonstante in Form einer Property verwendet, um die Länge des Array festzuhalten... na, vielleicht ist es ja einfach die bessere Methode.

Properties sind auch Felder, auf deren Adresse man mit .& und auf deren Länge (in Bytes) man mit .# zugreifen kann. Nur: Hier gibt es nicht die verschiedenen Arten von Feldern wie bei einer Array-Definition. Property-Felder sind immer Wort-Felder, und sie werden immer durch die Initialisierung mit Werten definiert. Die Größer der Felder ist statisch, daher muss man sich mit dem Trick, acht Wort-Platzhalter zu definieren, behelfen, um für jedes Ei oder jeden Featureless Cube WORDSIZE * 8 Bytes zur Verfügung zu haben, wobei unter Glulx WORDSIZE vier ist.

(Dass man mit .# die Anzahl der Bytes erhält, ist natürlich für eine Art von Feldern, die eigentlich nur Wörter sein kölnnen und nur durch Tricken als Bytes angesehen werden können, etwas blöd.)
_________________
Every silver lining has a cloud.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Clive
BeitragVerfasst am: Mi, 9 Aug 2006 - 22:02  Antworten mit Zitat
Wasserträger
Wasserträger


Anmeldungsdatum: 29.08.2002
Beiträge: 60

Vielen Dank, Martin!

Ich werd mal so ein bisschen experimentieren und ausprobieren, ob ich auch alles verstanden hab.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Alle Zeiten sind GMT + 1 Stunde (MEZ)

Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Seite 1 von 1
if-de :: Forum Foren-Übersicht  >  Inform & Glulx

Neues Thema eröffnen   Neue Antwort erstellen


 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.



Kontakt: Administrator

Powered by phpBB and NoseBleed v1.05