09.12.2025, 21:52
(Dieser Beitrag wurde zuletzt bearbeitet: Gestern, 08:14 von siebenstreich.)
@Zurgrimm:
Eigentlich ist es nur ein minimaler Fehler, ein einziges Bit:
Beim magischen Bastardschwert ist die Eigenschaft "benutzbar" gesetzt.
Andere derart als "benutzbar" gekennzeichnete Gegenstände sind z.B. das Schuldbuch (kann man lesen), die Stirnreife (aktiviert den Armatrutz-Zauber), der magische Beutel aus der Ruine des Schwarzmagiers, usw.
Wenn man im Inventarbildschirm "Gegenstand benutzen" auswählt, kommt bei als benutzbar gekennzeichneten Gegenständen nicht die Meldung "kann man nicht benutzen", sondern das Programm liest in den Gegenstandseigenschaften den Eintrag "table_index" aus. Beim Schuldbuch steht dort Nummer 6, bei Stirnreifen die Nr. 4 und beim magischen Beutel die Nr. 13. Damit geht das Programm dann in die Tabelle g_use_item_handlers und liest den 6ten, 4ten oder 13ten Eintrag. Dieser wird als Speicheradresse interpretiert, wo das Programm jetzt hinspringt und weitermacht. In unseren Beispielen ist dies die Adresse der Routine zum Lesen des Schuldbuchs (gibt jedem 15 AP und macht Hjore Ahrensson bekannt), oder des Armatrutz-Zaubers, oder der Routine zum Öffnen des Beutels (entfernt eine Wand in der Ruine des Schwarzmagiers).
Was passiert beim magischen Bastardschwerd? Für Waffen ist unter table_index der Index des zugehörigen Eintrags in der Waffentabelle abgelegt, das magische Bastardschwert hat Index 54. Damit will das Programm jetzt den 54ten Eintrag in der Tabelle g_use_item_handlers auslesen. Diese Tabelle hat aber nur 14 Einträge, so dass tatsächlich irgendein anderer Speicherinhalt (der zufällig an der anvisierten Position hinter der Tabelle steht) gelesen und als Sprungadresse zum weiteren Programmverlauf interpretiert wird. Das Programm springt also an eine willkürliche Position, wobei die Wahrscheinlichkeit sehr gering ist, dass das noch irgendeinen Sinn ergibt. Stattdessen passieren komische Dinge und das Programm stürzt ab.
Übrigens ist dies ein Fehler einer Bauart, nach dem etwa Speedrunner suchen. Wenn es noch möglich wäre, die Speicherzelle mit der Sprungadresse gezielt zu manipulieren, so kann man das Programm durch die anschließende Benutzung des mag. Bastardschwerts an jede beliebige Position schicken, z.B. just dorthin, wo der Endkampf gerade gewonnen wurde. Beispiel: Sollte in dieser Speicherzelle die Anzahl der Dukaten des ersten Helden gespeichert sein, so gibt man ihm genau die richtige Anzahl von Dukaten, so dass diese Zahl als Speicheradresse interpretiert dort hinführt, wo man hinwill.
Wie gesagt, das magische Bastardschwert ist als "benutzbar" gekennzeichnet, das war es schon. Warum ist dem so? Hatten die Entwickler das absichtlich gemacht, weil sie eigentlich vorhatten, ihm noch irgendeine Funktion zu verleihen? Oder ist es nur ein dummer Fehler?
So weit ich sehe, gibt es in diesem Umfeld leider auch keinen "verwaisten" Programmcode, der für die Funktion des mag. Bastardschwerts hätte bestimmt sein können. Wir können also wirklich nur ins Blaue mutmaßen, was die Entwickler wohl mal vorhatten.
Eigentlich ist es nur ein minimaler Fehler, ein einziges Bit:
Beim magischen Bastardschwert ist die Eigenschaft "benutzbar" gesetzt.
Andere derart als "benutzbar" gekennzeichnete Gegenstände sind z.B. das Schuldbuch (kann man lesen), die Stirnreife (aktiviert den Armatrutz-Zauber), der magische Beutel aus der Ruine des Schwarzmagiers, usw.
Wenn man im Inventarbildschirm "Gegenstand benutzen" auswählt, kommt bei als benutzbar gekennzeichneten Gegenständen nicht die Meldung "kann man nicht benutzen", sondern das Programm liest in den Gegenstandseigenschaften den Eintrag "table_index" aus. Beim Schuldbuch steht dort Nummer 6, bei Stirnreifen die Nr. 4 und beim magischen Beutel die Nr. 13. Damit geht das Programm dann in die Tabelle g_use_item_handlers und liest den 6ten, 4ten oder 13ten Eintrag. Dieser wird als Speicheradresse interpretiert, wo das Programm jetzt hinspringt und weitermacht. In unseren Beispielen ist dies die Adresse der Routine zum Lesen des Schuldbuchs (gibt jedem 15 AP und macht Hjore Ahrensson bekannt), oder des Armatrutz-Zaubers, oder der Routine zum Öffnen des Beutels (entfernt eine Wand in der Ruine des Schwarzmagiers).
Was passiert beim magischen Bastardschwerd? Für Waffen ist unter table_index der Index des zugehörigen Eintrags in der Waffentabelle abgelegt, das magische Bastardschwert hat Index 54. Damit will das Programm jetzt den 54ten Eintrag in der Tabelle g_use_item_handlers auslesen. Diese Tabelle hat aber nur 14 Einträge, so dass tatsächlich irgendein anderer Speicherinhalt (der zufällig an der anvisierten Position hinter der Tabelle steht) gelesen und als Sprungadresse zum weiteren Programmverlauf interpretiert wird. Das Programm springt also an eine willkürliche Position, wobei die Wahrscheinlichkeit sehr gering ist, dass das noch irgendeinen Sinn ergibt. Stattdessen passieren komische Dinge und das Programm stürzt ab.
Übrigens ist dies ein Fehler einer Bauart, nach dem etwa Speedrunner suchen. Wenn es noch möglich wäre, die Speicherzelle mit der Sprungadresse gezielt zu manipulieren, so kann man das Programm durch die anschließende Benutzung des mag. Bastardschwerts an jede beliebige Position schicken, z.B. just dorthin, wo der Endkampf gerade gewonnen wurde. Beispiel: Sollte in dieser Speicherzelle die Anzahl der Dukaten des ersten Helden gespeichert sein, so gibt man ihm genau die richtige Anzahl von Dukaten, so dass diese Zahl als Speicheradresse interpretiert dort hinführt, wo man hinwill.
(09.12.2025, 18:25)Zurgrimm schrieb:(08.12.2025, 22:36)siebenstreich schrieb: Es handelt sich um das Resultat eines Speicherzugriffsfehlers. Prinzipiell ist vieles denkbar, je nachdem, welche Information an der angefragten Speicheradresse liegt. (Das könnte man genauer nachverfolgen, habe ich aber nicht gemacht.)
Wenn die Information an der Speicheradresse, auf die zugegriffen wird, bekannt wäre, würde das nicht zumindest einen Hinweis darauf liefern, was der Effekt des Benutzens hätte sein sollen?
Wie gesagt, das magische Bastardschwert ist als "benutzbar" gekennzeichnet, das war es schon. Warum ist dem so? Hatten die Entwickler das absichtlich gemacht, weil sie eigentlich vorhatten, ihm noch irgendeine Funktion zu verleihen? Oder ist es nur ein dummer Fehler?
So weit ich sehe, gibt es in diesem Umfeld leider auch keinen "verwaisten" Programmcode, der für die Funktion des mag. Bastardschwerts hätte bestimmt sein können. Wir können also wirklich nur ins Blaue mutmaßen, was die Entwickler wohl mal vorhatten.

