Blog Layout

Of Data Tricks, Lizard Heads and Smugglers

Pyrdacor • Sep 24, 2021

Creativity


There is no doubt: Ambermoon is huge! Not only the world but also the things you can do. But there are many little details as well. Perhaps some of them are only noticed in the second or third playthrough, if ever. To achieve all this the developers were very creative. They had to, because resources were limited and expectations were high. In this blog we will talk about some cool ideas that made it into the game and especially one of them which partly backfired. Some more examples will follow in detail in later blogposts.

While decoding more and more of the game data, some features still remained a mystery to me. And other things were just there unnoticed.

It took quite a while to understand what was going on. Especially when multiple things came together.

The first story will take place on Morag but on the other hand it will precisely not take place on Morag. And that is the problem. Sounds confusing? Don't worry. I'll take you with me on a trip to some crazy data tricks in Ambermoon.


Decoding graphics

Let's start with a bit of background information. Graphics are the bread and butter of Ambermoon. Beside the epic music, the lovely fantasy graphics create such a fantastic atmosphere. There are all kinds of graphics and they are stored in so many different files. At the beginning I had to find out where I would find specific graphics, which format they had, etc. The process of finding this out could fill a blogpost on its own, but let's assume I was able to do so somehow.

For example at some point I managed to load and extract the graphics of the file Party_gfx.amb and in there I found 3 sequences of player graphics for the 2D indoor maps. Most of the time the filenames give a clue about the content. But Party_gfx could be anything from party member portraits over some party related stuff like HP bars or just the 2D sprites of the player. The latter was the case here, but the 3 sequences only represented the indoor 16x32 pixel frames. So what's about the world maps which use smaller 16x16 sprites?

To be honest, I had no clue. I expected them in the same file of course. Was the file corrupt or a wrong version? Was my graphic reader broken? No, there definitely were no other graphics in there. And so...

I faked them! Yes you heard right. For a long time I just faked the world map player sprites in the remake. Because I couldn't find them in the data files. I created them from screenshots of the original game. And luckily nobody noticed.

Only much later I finally found them in another file: Travel_gfx.amb. I didn't understand the format of that file before that and only found the eagle sprite by accident in there. But I didn't make the connection from the eagle sprite to the normal 2D player sprites. Today I know that the world map uses some kind of travel type. So everything from riding a horse or on the back of an eagle, sailing on a boat or just swimming or walking. As you might see, decoding of every single file and implementing every single aspect of the game was an adventure in itself.

But back to the 16x32 pixel party graphics. Those 3 frame sequences of course represent the sprites for each of the 3 worlds: Lyramion, Kire's Moon and Morag. They all look quite similar but the bed sprite was very different for the forest moon version, so you really saw that multiple versions were imporant.

As you can see all 4 directions have 3 frames for movement and the middle frame is also the image for just standing. And there are 4 frames for sitting (1 frame per direction) and a single frame for sleeping. Yes the bed is part of that! How else could you display the sprite that nicely merged under the sheets?


As the same artists created the map tile graphics for Lyramion and Morag (which includes the bed sprite), it is no wonder that the beds on those two worlds look the same. Even though I think that there is no bed on Morag whatsoever. However at first I thought that the Lyramion and Morag player sprites were completely identical! The bed for the forest moon is very obvious and I thought that this was the only reason why there are 3 different sets of player sprites for each world.


Fun fact: Only as I started writing this post I noticed another cool detail about these graphics: the forest moon sprites slightly increase the size of the player! Quite logical if you should appear larger when you are surrounded by little dwarfs. Another epic detail though in my opinion.


To my defence I have to say, that until now I never had a full image with all the 3 sets, which allows easy comparing of the sprites. And the original sprites are much smaller on a modern monitor! Anyway I only noticed much later what was the difference between the Lyramion and Morag sprites: the cute little lizard head!


So this basically means: When you walk on any Morag map, you look like a lizard. Ugh!


While this might be an interesting fact, it will also matter later, so keep it in mind!



Strange "bugs"


Months passed and then as I started to fix and investigate original game bugs, I stumbled onto a very strange issue: the Morag hangar map and also the S'Angrila prison map have two versions. And those versions are basically the same map with the same tiles, texts, events and so on.


This was only found and reported as the english translations of the map texts for those two map versions were different. It seemed that someone back in 1993 translated the texts map by map and slighty did it in a different way for both versions. This was some lucky coincidence for us in the end.


We fixed the translations to become the same, but why the hell were there two map versions and what were the differences of these two maps? It was quite a mystery and I had to find out. I investigated everything.


  • The map structure and tiles. -> Same.
  • The characters on the map. -> Same.
  • The texts on the map. -> Same, beside the translations.
  • The events on the map. -> Same.


But what else is left? Two little things were different.


First of all, events on a map can be stored but there has to be some map tile which triggers the event. For example to trigger a text popup on a map, there has to be an event for it stored in the map data. But in addition there has to be a map tile which uses that event. Otherwise it would never be triggered. And this was the first difference. On the first map version some event was triggered on a tile and on the second map (even though the same event was stored inside the map data) it was not used by any tile. This wasn't that easy to find out. Back then I had no map editor to see that directly. I had to search in large hex files or in a debugger. And even then it wasn't easy to see. Especially when you don't know that this is a possibility. And of course there are several other events which are used on many tiles in both map versions!


But there was a second difference and this was really strange. It was considered a bug for a long time.


The first map version was flagged as "On Lyramion". Remember, those maps are Morag maps!


And this was true for the first version of the hangar AND the prison! Two identical bugs in two strange versions of an almost identical map? Very suspicious. And moreover those two are the only Morag maps which had that "bug".



Lizard magic


Spoiler alert!  If you didn't play the game at least to Morag you might want to abort reading here, as it might spoiler some parts of the story. You can also just skip the gray text passage, but it might be important to understand it.


The first difference (the additional map event) and some playtesting led me to the first part of the reason for the multiple map version mystery. The additional event on the first map version was the teleport to the prison.


When you first enter Morag, S'Riel, a Moranian magician, teleports you to his prison cell, tells you about the Moranians and casts a disguise spell on you, so that everyone thinks you are one of them. Then he dies.


Ok makes sense. When you come back later to the hangar, the event should not be triggered anymore, so just use a second map version without the event then. Same for the prison. On a later return S'Riel is dead, so we need another map version without him.


End of story. Blogpost finished. Bye.



No wait! Wait a second! Luckily I knew enough about map events, map characters and that stuff at that time. I knew that you can just disable events. So why would I need a complete new map just to disable an event? I mean, they had not much space back then. And it is also very easy to hide characters like S'Riel on maps as well. It won't justify two additional maps. Something was wrong here.


It took me a while but finally I understood. And I am honest here with you: I felt a little bit like Sherlock Holmes.


You have to connect the dots. The second difference which seems like a bug, was the key. The maps were not flagged as Lyramion maps by mistake. It was a neat little data trick.


Remember what I said about the party graphics before? The world you are on determines which player sprite is used. So on Lyramion maps you look like a human, but on Morag maps you look like a lizard. But why do you look like a lizard anyway on Morag?


Right. S'Riel casts the disguise spell on you which lets you appear as a Moranian (lizard). But here comes the kicker: he only does this in the prison! So when you first enter Morag, you still look like a human of course. The same is true at your first visit to the prison (when S'Riel teleports you there). Those two maps, even if they are on Morag, are flagged as "On Lyramion" so that you appear as a human on them!


Then when you have the disguise, the maps are swapped and from now on you will always enter the map versions which are correctly flagged as "On Morag". You can test this yourself. On later visits to the hangar or prison you have a lizard head. And even though you won't notice, you effectively are on a different map! Only the english players could notice this in theory through the different translations.


This my friends is a very cool trick to achieve consistency with the storyline and by keeping this simple connection of world and party graphic.


In the end the developers spent much effort and disk space to add this small detail in a consistent way. This itself is very honorable. But it might have some side effects as well.



Side effects


At first glance this stuff looks awesome. But messing with data in such a way can backfire. There are some specialties for each world. Most of them don't affect the trick from above. I mean, only two little 2D maps have this manipulation and you will only stay on them for a very short amount of time. What could possibly go wrong?


There is one big problem. You can cast the spells "Word of mark" and "Word of return" on Lyramion maps. And only on Lyramion maps! For good reasons. I guess the developers didn't think of that back then.


Those two spells are a cool feature to return back to a previously saved location, but it was only designed for the huge island world of Lyramion. You should not use them on the forest moon or Morag. Imagine you could just return to Lyramion from Kire's moon with that spell. It would totally break the game.


The two spells together with the Morag duplicate map trick opened up another possibility which is now considered cheating and was "fixed" by me in the most recent patches. Normally if you would bring the witch's broom or flying disc to Morag, it would be destroyed by some map event. But on first arrival you are on a Lyramion map! So just go there without the mentioned items (so they won't be destroyed), pass the events which would destroy the items, mark a spot and then later get the items and return to the mark. Tada, you skipped the destroy events and smuggled the broom or flying disc onto Morag.


Maybe you can imagine how much time and brain cells I had to spent on finding those things and fixing bugs and backdoors in the original game solely by changing data. I could not revert the lizard head trick as it was integrated deep into the story and fundamental game structure. But I could avoid the abuse of the spells and the broom smuggle. But even this was a hard task. You still can use the spells though but you can't smuggle the items. At least not to the place where it would matter: the world surface.


If you are curious, just try it out. It works with the remake (1.1 and above) and the original Amiga version as well (1.09 german / 1.10 english and above). Smuggle the broom to Morag and see what happens. But be warned! Save before you try this. At least before leaving the town. Cheaters are punished hard! Sometimes even by myself.


Pyrdacor - 24-09-2021

Share this blog post

By Pyrdacor 19 Jan, 2022
There are quite some hidden bugs in Ambermoon which never would have been noticed if it wasn't for the Ambermoon Advanced project. The cursed items feature is very cool in my opinion, but as there is only one single item in the game which is cursed, it left me with the impression of wasted potential. This is why I always wanted to add more of those cursed items. And so I decided to add another one to the mod. There might be more cursed items in later episodes as well of course. This blog article will be very technical. Having some basic knowledge about computers and how they work will definitely be helpful, but I'll try to explain the things that are needed for you to be able to follow. We will actually modify the original Ambermoon executable, add new code and fix two real bugs together. If you want to code/manipulate along, prepare a hex editor of your choice, maybe a decimal to hex and binary to hex converter and if you want to go the full mile, also install Ghidra which I can strongly recommend for reverse engineering. This all is optional of course. If you only want to read, you might skip some parts. As a general rule of thumb: if you don't understand something, first try to read a bit more. Maybe it becomes clearer then. I'll try to explain complex matter with examples. Ghidra can be downloaded at https://ghidra-sre.org . To work with Amiga assemblies I strongly recommend the Amiga hunk plugin in addition which you can find at https://github.com/lab313ru/ghidra_amiga_ld r . Setup Ghidra and install the plugin: Download and install Ghidra Pick the right plugin version from here https://github.com/lab313ru/ghidra_amiga_ldr/releases (download the zip file after expanding "Assets"). Open up Ghidra Select "File -> Install Extensions ..." and click the green plus symbol ("Add extension") Navigate to the downloaded plugin zip file If you picked the right version, the extension should be added Then create a new non-shared project At last you can just drag&drop the Ambermoon executables (e.g. AM2_CPU) from your filesystem into Ghidra If we modify code in this blog article, always use the hex editor. Ghidra is only used for analyzing the assembler instructions or to find something inside the code or data.
By Pyrdacor 22 Sep, 2021
Ambermoon savegames have a big potential for errors: They store redundant data. For example they store all the items, gold and food a character carries but in addition they also store the total weight. The weight could also be calculated from the other data, so what happens if the value is different from the calculated one? Where it matters the most is bonus stats . Some equipped items grant attributes like strength or skills like swimming or attacking. For example the necromancer dagger grants 2 points of anti-magic and an increase of successful scroll reading of 25%. So far so good. Each item of course stores the information what effects it grants. But now comes the problem. The savegame stores the current value, maximum value and bonus value of all attributes and skills. So if you add up the effects of all the equipped items, it should match the given bonus values. But what if it doesn't? Well, then you will have a problem when you unequip them. For example let's assume the initial savegame stores Targor with an equipped throwing sickle but with a bonus value for the attack skill of 0 (this is actually the case). The throwing sickle grants an attack skill bonus of 10. Now if you start a game, add Targor to your party and unequip the throwing sickle, his attack skill will be crippled by 10 as the game assumes that the bonus was added when equipping the item. Not to mention that he already has 10 attack less to begin with as the bonus value is not set. Another effect of this is that you can no longer maximize your stats. Take the poor Targor again. In-game the value is shown as the sum of current and bonus value, so for example if you currently have 30 attack and a bonus of 10, the game will just show 40. Let's say 40/50 with a max value of 50. You would now think that you can at least reach that 50. But when you have unequipped the item, you have a (hidden) bonus value of -10 (and you can't remove it! it is burnt into your savegame). When you now maximize your stat to the current value of 50, the game will still show only 40/50 as 50 + (-10) is exactly that. This is the reason why those issues were historically reported as "character X can not maximize his attribute/skill Y" instead of "his bonus values are wrong". The original savegames were full of those bonus value corruptions (and still are as we see in a minute). An easy fix would be to load the savegame, calculate all those values and override those redundant values. Unfortunately the original game does not. Interestingly though, it does this with the weight value! But still I consider this a data format issue rather than blaming the loading routine. Storing redundant data is only useful in very rare scenarios and is (as you can see) very error-prone. Not to mention that redundant data in the Ambermoon savegame is unnecessary. Savegame Editor Daniel Schulz created an online savegame editor for Ambermoon a few years ago. In case you don't know, you might want to check it out ( link ). You can edit all the party characters and there is even a nice button to apply equipment effects. The screenshot above is taken from his editor btw. He was aware of many issues regarding equipment bonuses and he fixed a lot of them. He also released his own german patch a while ago which he labeled 1.06. Daniel documented many savegame related fixes as well. As his version was the one with the most fixes, I based my own german patches on that version (therefore I started with 1.07 german). This will matter in a second. Ambermoon Advanced As most of you hopefully know, I started to create a mod for the original Ambermoon. This of course includes changes to the characters (#balancing). And as you can imagine, the mod should be available in all languages. Therefore I opened up my lovely hex editor and started to adjust some bytes. "Oh Selena is quite weak, she should become a bit more max critical strikes. Let's replace that 2 with a 5... Ha, piece of cake. Now move over to the german version and change it as well. Wait a second. There is a 5 already? What the ...?" At this point I noticed a difference in both languages. Shame on me that I never checked that before. The english patches are based on a patch by Meynaf which is itself based on the original english 1.07 version. It also fixes a few savegame issues (namely those which were reported till then). But I didn't know that Daniel Schulz changed so many character values and fixed so much more savegame issues. This was the time for a closer look. I took the english patch 1.10 and the german 1.09 and diffed the character data. Surprisingly there were a lot of differences. This was unexpected. First of all, Daniel changed 5 things which are debatable. All characters got a max swim skill of 99 instead of 95. Selena's max crit was raised from 2 to 5. Nelvin and Tar got higher read magic skill. Nelvin and Tar got higher use magic skill. Tar's current swim skill was raised from 90 to 99. He obviously thought that characters should be able to perfectly swim without getting hurt. At first sight a valid point. But you should know that in Ambermoon the value 95 is always used for the best skilled characters. My assumption is that Karsten Köper thought that even a master in his field can fail to some extent. And 95 is quite a high value in Ambermoon when you consider that your grandpa (the hero of Amberstar) only has an attack skill of 80. How I know that? Well, even every NPC in Ambermoon has their stats set nicely. Even though you can't see most of them in-game. This is commitment! Moreover a swim skill of 95 will still hurt you but mostly you will get only 1 point of damage. To actually die with 100+ HP you can swim all day. I would drown much faster in real life. :) I think the misconception here is that getting hurt is set equal to "you can't swim properly so you're punished". For me the hit points are more like some durability value. If you run out of it you'll kiss the ground and won't stand up anymore. Under that impression a swim skill of 95 makes you a super swimmer as you can swim for hours. Back in the days David Hasselhoff would have given you a red swimsuit and you would have appeared on Baywatch with such an ability. But back to the serious stuff now. The fact that Selena could need some more crit is legit (I also do this in the mod). But I am not sure if it was planned that way by the designers and I am not a big fan of changing values in original patches just to one's liking. Interestingly Daniel said things like "a thief has a maximum crit value of 5" or "a mage has a max use magic value of x". I am not sure where this information comes from but maybe there is something I missed. If he is right, then the changes would be valid. The same is true for the Nelvin and Tar adjustments mentioned above. I guess he just looked at Mando (the other thief - hi Jurie Horneman :D) who indeed has a max crit value of 5. But which value for thieves is correct now? Maybe I just skipped a section in the manual? I also wonder why he also changed the current swim skill value of Tar from 90 to 99. My guess is a story-based reason. At least the crazy dude managed to survive the great flood. But I wonder if such lucky occasion has really something to do with your ability to swim? I doubt it. Savegames fixes Ok back to the german savegames. Beside those debatable changes, Daniel fixed a lot of bonus value issues. He only documented a few but there are many more. I guess some were just fixed by accident through his savegame editor (loading -> apply equipment effects -> fixed bonus values -> save). For example in the english 1.10 version Gryban has 6 wrong bonus values and Chris even 10! There are only 8 attributes and 10 skills in total, just to emphasize this number. Ok HP and SP bonuses are counted as well so there are 20 bonus values in total. Still Chris has half of them wrong! Those wrong values include some twisted ones. For example sometimes the bonuses were added to the wrong attribute or skill which effectively leads to two corrupt values at once. Always adjacent attributes/skills were affected so I guess someone modified the wrong line/entry manually. To emphasize the amount of issues even more: those are only the differences to the fixed english version 1.10 which itself contains several of such bugfixes. So I don't want to know the total amount of issues in the original savegames. Coming patches So the next patches will revert some german savegame changes and add a lot of fixes to the english savegames. Of course along with some other stuff. ;) Even the current 1.10 english patch has still a lot of corrupted bonus values. Wouldn't I have started the Ambermoon Advanced project, I might have not noticed this. Now we have the possibility to fix this once and for all. :) Maybe I can also find some more information about these "class X has a maximum stat Y". If you have any input, be my guest. Pyrdacor - 22-09-2021
Share by: