Coucou. Voici un deuxième article dans le même mois !
Comme promis, j’ai envoyé 20 euros à All-Seeing Eye, pour remercier Joonas Hirvonen d’avoir créé cet outil permettant de modifier le jeu Eye Of The Beholder. Je m’en suis servi pour créer un challenge de Hacking pour la THCON. Tout est expliqué dans ce précédent article.
Ce fameux Joonas Hirvonen m’a remercié par mail et m’a encouragé à transmettre mes signalements de bugs. Je vais lui envoyer un document récapitulant tout ça, j’en profite pour le copier-coller ici. Ça ne vous intéresse peut-être pas, mais moi ça me fait un article à peu de frais. (Quelle blague ! Tous mes articles sont à peu de frais !)
C’est en anglais, vive le rosbif !
These bugs and improvement proposals are sorted from most important to less important.
Technical context :
- the game « Eye of the Beholder 1 v1.9 – unofficial » ,
- taken from this site : https://www.oldgames.sk/en/game/eye-of-the-beholder/download/2021/ ,
- played in a DosBox on Windows.
Do what you want with these bugs, as I am not sure I will have the occasion to re-use ASE.
Modifying scripts provokes graphical bugs
Many wall images are scrambled when the game scripts are modified.
Here are steps to reproduce the bug.
- Start a game, create a party, go to the first drainage grate.
- Everything looks OK.

- Launch ASE.exe and set the folder
- Launch EOB1_Explorer.exe
- Add an instruction anywhere in the code, for example :
F8 "I add a new message here." 00 02 00
- Press Ctrl-F9 to compile.
- You get a message box telling « Range check error. »

- Click the button « update INF ».
- Close and restart EOB1_Explorer.exe
- Add another instruction anywhere in the code.
- Press Ctrl-F9 to compile.
- This time you don’t get the error message.
- Click once again the button « update INF ».
- Start another game, re-create a party, go to the first drainage grate.
- This time the image is buggy. I do not know from where it was taken. It looks like a part of an attacking leech.

Other bugs appear on many wall textures. Once it happened, there is no hope to come back to a correct display.
I guess it’s a problem with memory offsets in the game information. It is quite annoying, it cancels all the involvement I would put in the creation of a totally new Eye Of The Beholder game.
Object sub-position cannot be redefined
Information related to objects can be modified in the tab « F4:Items ». But their sub-positions cannot be modified.
As we all know, an object on a square in the map has 5 possible sub-positions : the four corners on the ground, and the alcove carved on a wall.
The function ADD_ITEM
shows it. It has 3 parameters : OBJECT_INDEX, POS_X_Y, SUB_POS.
The initial data contained in the .PAK files undoubtedly contains these supositions. When I modify existing object coordinates, they land on different sub-positions, depending on their index.
If the initial sub-position of the object is in an alcove, and if the object coordinates is on a square that has no wall, we have flying objects !

These flying objects can not be taken. Too bad.
I would say the tab « F4:Items » should have a field « sub-position », that allows us to read and write sub-position of each object.
A weird thing in the game engine : there is only one sub-position to define an object in an alcove, not one per wall side.
If you put a square with an alcove wall on each side, and if you put an object sub-positioned in the alcove on this square, then the object is visible from the four sides ! Logically, when you take it, it goes away from the four sides. In my opinion, this weird behaviour should be documented somewhere.
Encounter scripts should be editable, if possible
I do not know if it is possible at all. Some encounters seem to execute the same kind of instructions as the ones in the script :
- speaking with Armun puts some objects in front of the party and sets a global flag,
- there are movements automatically done before and after speaking with the dwarven cleric, and the previous global flag is checked to initiate the conversation,
- speaking with Shindia spawns the monster « Shindia »,
- …
I guess the dialogue texts, reply choices, player characters joining the party, etc. are all stored somewhere in the game files. If we could modify all this, it would be really cool, and we could make a totally-totally new Eye Of The Beholder game.
Some event parameters are not parsed in the script
Here is the code we usually have with stairs and ladders :
IF TRIGGER_FLAG = 1 (on_enter)
ELSE_GOTO $0473
[...]
IF 3 = 0
ELSE_GOTO $044C
TELEPORT TYPE = $E8 (party), SOURCE = <00,00>, DEST = <18,24>
IF 3 = 1
ELSE_GOTO $0459
TELEPORT TYPE = $E8 (party), SOURCE = <00,00>, DEST = <17,23>
IF 3 = 2
ELSE_GOTO $0466
TELEPORT TYPE = $E8 (party), SOURCE = <00,00>, DEST = <18,22>
IF 3 = 3
ELSE_GOTO $0473
TELEPORT TYPE = $E8 (party), SOURCE = <00,00>, DEST = <19,23>
IF TRIGGER_FLAG = 4 (on_put_item)
ELSE_GOTO $04AE
IF 3 = 0
ELSE_GOTO $0487
TELEPORT TYPE = $F5 (item), SOURCE = <18,23>, DEST = <18,24>
IF 3 = 1
ELSE_GOTO $0494
TELEPORT TYPE = $F5 (item), SOURCE = <18,23>, DEST = <17,23>
IF 3 = 2
ELSE_GOTO $04A1
TELEPORT TYPE = $F5 (item), SOURCE = <18,23>, DEST = <18,22>
IF 3 = 3
ELSE_GOTO $04AE
TELEPORT TYPE = $F5 (item), SOURCE = <18,23>, DEST = <19,23>
END
The translated script shows comparrison between litteral numbers : « 3 = 0
», « 3 = 3
», … which looks really dumb.
This is of course not what the script does. These values corresponds to the direction from where the party comes, or the direction from where the object was thrown. It is used to reposition the party or the object from where it comes, because nothing is supposed to stay at the same square of a stair or ladder.
Some specific words should be used in the translated script to describe this process. For example, 3 = 0
should be replaced by FROM_DIRECTION = NORTH
.
The direction identifiers are the usual ones : 0 = north, 1 = west, 2 = south, 3 = east.
Labels should be shown in the « Events » tab
The « F2:Events » tab shows the translated scripts, but the GOTO
instructions have the litteral adresses.
The « F3:Scripts » tab shows GOTO
instructions with labels, but the script is displayed with raw bytecode.
The text labels should also be displayed in the « F2:Events » tab, to have all the human-readable script in one tab.
It is quite painful to modify the scripts, I was always switching between the two tabs : write some code, check it is correct, and so on. A really nice feature would be a mode to display the two tabs side by side. The « F2:Events » would automatically updates while we type in the « F3:Scripts » tab. But maybe that’s too much to ask.
Texture atlas needed
I had to try different wall numbers in the map, then play the game to see the corresponding images, then repeat for the next level palette, etc.
Some identifiers are the same in many palettes, for example : with « brick » and « blue », the value 51 corresponds to a wall with writings on it.
Other identifiers exist only in one palette, or are different between palettes, for example : all the stone portal images.
That would really be helpful to have the complete list of wall images, with their identifier, for all the palettes. You don’t even have to integrate it in the existing software. Just toss an external document with the images and their identifiers, that would be perfect.
Command parameters should be documented
The tab « F5:Commands » lists all the existing commands, which is great, but not enough.
The parameters of each command should also be documented. Some commands, such as TELEPORT
or ADD_MONSTER
, have numerous, varied and complex parameters.
The documentation you linked to https://moddingwiki.shikadi.net/ is interesting, but really hard to read and to understand. I’m not sure it explains all the commands of Eye Of The Beholder.
Program crashes when writing coordinates with one digit
This one is simple to reproduce :
- Go to « F3:Script » tab, go to the « event trigger points » zone.
- Modify a coordinate of any event, write it with only one digit. For example, replace « 03 » by « 3 ».
- Press Ctrl-F9.
- You get an error message : « Access violation ».

Code size limit should be checked
When the script of a level is too big, it can lead to unexpected behaviours.
The last address value in « F2:Events » should be checked. If it is greater than $1AF0
, there are risks to have unexpected behaviours. I’m not sure of the exact limit, it may be a rounded value, like $1B00
.
This should be checked by EOB1_Explorer.exe, and a warning message should be displayed when updating/saving the INF file.
The unexpected behaviour seems quite random, and occur when the party arrives in the level having the INF too big.
Sometimes, it’s an immediate crash with a totally unrelated message :

Some other times, it’s a crash with a message « Far heap corrupt! » when you click on the button « CAMP » :

Race and class values are not completely documented
The file EOB1_Explorer_Notes.txt has an uncomplete list of race indexes. Here is the complete one :
- 00 = Human
- 01 = Elf
- 02 = Half-elf
- 03 = Dwarf
- 04 = Gnome
- 05 = Halfling
The Class identifiers are not correct and does not correspond to the HAS_CLASS
function.
There are only 4 « base class »,
- 01 = Fighter
- 02 = Mage
- 04 = Cleric
- 08 = Thief
HAS_CLASS
adds all the classes of your characters, by using the boolean « OR », and returns true if there is at least one set bit in common with the parameter given to the function.
Multi-class activates the corresponding bits of all the base classes.
For example, let’s say the party has a Fighter/Mage and 3 clerics (that’s a weird party).
HAS_CLASS(2)
will return True. It evaluates to :
has_class_param & (classes_chara_01 | classes_chara_02 | ... )
2 & ((fighter | mage) | cleric | cleric | cleric)
2 & (fighter | mage | cleric)
2 & (1 | 2 | 4)
2
True
It is not possible to check if there is a ranger in the party. This class only lights the « fighter » bit.
It is also not possible to check if there is a paladin. This class lights the « fighter » and the « cleric » bits.
The way how the function HAS_CLASS
works should be documented.
That’s all
Thank you once again for having created these tools. They are wonderful, even with those tiny bugs.
I used EOB_Explorer1 to create a hacking challenge that involves the game and your tools. This challenge was part of the CTF at the Toulouse Hacking Convention 2022. The people who tried it said it was really interesting (a few of them managed to solve it, though). I will submit it to root-me.org in the upcoming months and I will let you know about it, if root-me accepts it.
For the moment, I have not planned to create other challenges or other games with Eye Of The Beholder, so there may have no specific reason to fix these bugs. Anyway, I’m really happy to have « revived » this game in a quite uncommon way. It was an important part of my childhood, I took many years to finish it.
See you next time !
Voilà, c’était tout ce que j’avais à dire. Je l’envoie à mon nouvel ami Joonas ce soir. S’il me répond des trucs intéressants, je vous en ferais part.
Bien entendu, j’ai plusieurs autres idées de challenge « TUR-ROX », avec d’autres jeux. J’essayerais d’en concrétiser une ou deux pour la prochaine THCON.
Cet article est un rapport de bug.
Rapport de bug -> bug -> ladybug -> l’héroïne de dessin animé -> vêtements aux motifs de cette héroïne -> femme ronde !
Enjoy :

Pour le mois prochain, je me permettrais d’être moins blogalement productif. Je vous rassemblerai un package de commentaires de jeux du Ludum Dare, et ça devrait suffire.
D’ailleurs, faut que je vous annonce mon classement. Eh bien on fera tout ça en même temps.
THCON + Ludum Dare, ça a été un beau bazar ces dernières semaines. Peut-être que maintenant je vais avoir du temps pour faire la road-map de Squarity ?
On ne sait pas…