11 March 2016 - Forum Rules

Main Menu

Ultima: Exodus (NES) --- Now released

Started by Fox Cunning, December 09, 2019, 12:22:43 PM

Previous topic - Next topic


That is looking good, the rock's that you have to walk around are a nice touch.  And that character creation screen is looking nice, too.

Fox Cunning

I can sneak in one more update before the new year! :woot!:

As ROM space was starting to become an issue, I've implemented a simple RLE map compression that frees up almost 10 KBytes in ROM!

That broke the way chests worked, so I had to re-implement that too.
The downside is that chests now disappear when offscreen, but that should rarely happen.

On the bright side, the routines for moving the party have been improved and now take a significantly smaller amount of CPU cycles -- it's not noticeable normally since you are limited to moving one pixel per frame, but it helps when there are a lot of enemies or NPCs roaming the map.

Also, since I had to turn my attention to chests: now the maximum loot value scales with the level of the character opening the chest.

First update of the new year ;D

I have almost completely re-written the enemy's battle AI.
Now not only the sequence is much faster (especially noticeable when there are less than 8 enemies), but enemies are now also a bit smarter and will try to navigate around obstacles including other enemies.

Before/after comparison of movement with 2 enemies:


Those changes to the battle AI sound like they will make a big difference!

Fox Cunning

Quote from: coinilius on January 04, 2020, 05:58:10 PM
Those changes to the battle AI sound like they will make a big difference!
Hopefully so! Especially in ship battles, where enemies now won't get stuck on a plank if the closest character is on the other one.
It could still be made smarter, but I think now there's a good compromise between speed, code size and efficiency.

Another update:
I've put in the code to allow a slightly different palette for each map.
Some maps use lava pits, so they need some kind of red and thus can't be changed too much, but here's a few experiments:

Also each NPC now can use two different palettes to allow some slight variations, as seen in the screenshots above.

Some other routines have also been completely re-written, to this effect:

  • Characters in "good" state will regenerate 1 HP every 5 steps outside of towns (instead of the original 1 HP per 10 steps).
  • Barbarians regenerate health a bit more quickly: 1 HP every 4 steps.
  • Magic users regenerate 1 MP every 2 steps (instead of 1).
  • Druids regenerate MP at double rate (like in the original Ultima 3).
  • Food is consumed at the rate of 1 unit every 20 steps (instead of 10).
  • Diseased characters will consume food at double rate (1 every 10 steps).
  • When out of food, a character loses 1 HP per step (instead of 5 HP every 4 steps).
The rest is unchanged: poisoned characters still lose 1 HP per step, and diseased characters lose 1 HP every 2 steps.


Those changes sound good as well, I like that they are subtle but substantial when all taken together so they should really change up the execution of the game without really changing the flow/feel.

Fox Cunning

Aye, it's one of those areas where the game needs just that little push to become more enjoyable.

Another slight gameplay change I finished implementing over the week-end: characters now receive 1 attribute point in up to two stats depending on profession when levelling up, up to racial maximum.
You will still need to visit Ambrosia to max your attributes.
One of the main critiques of the game was that it punished the player for levelling up, so this is another change that tries to push in the opposite direction.

After that I turned my attention to the dialogue, and I discovered an interesting thing.
Infamously, one of the clues necessary to complete the game was missing... but the text was actually there!
That and many other lines were just either unassigned or missing because they somehow forgot to add the special character in the previous string that makes a yes/no menu appear, or makes the next line show up when you talk to the same NPC again.

Now at least 20 orphaned lines have been restored, including part of the Zelda reference, and a weird 4th wall breaking dialogue that might be a pop culture reference I don't get.

And since I have improved the map compression and now have an entire PRG bank to fill, I've been using it for dialogue portraits (WIP):


this game is looking so good, if you can finish it, I would like an editor to be able to rom this game with other games in the last series

Fox Cunning

Quote from: roney33 on January 12, 2020, 06:26:21 PM
this game is looking so good, if you can finish it, I would like an editor to be able to rom this game with other games in the last series
I had to create a couple of utilities to help with the frustration of pointers and tables (I now respect the work of ROM translators even more).
Here's what the main one looks like:

It is a very rudimentary tool that can export binary files, and then I have to inject them myself into the ROM where needed.
But if there's interest, once done I am happy to release it as open source and maybe improve it a little.


Are you a member of The Cutting Room Floor? I had no idea there were orphaned lines in this game and they don't seem to have an article for it yet. Seems like something that should be added there.

I'm particularly curious about that fourth wall breaker myself.

Fox Cunning

Quote from: Nosuch on January 13, 2020, 05:34:42 AM
Are you a member of The Cutting Room Floor? I had no idea there were orphaned lines in this game and they don't seem to have an article for it yet. Seems like something that should be added there.

I'm particularly curious about that fourth wall breaker myself.
I must admit I didn't know of The Cutting Room Floor. I may contact them or see if I can create an account myself.
There are exactly 21 lines that are compressed in ROM but never used in the game.

And the 4th wall breaker dialogue is:

Dialogue index: $AB, packed text address in bank 5: $B50E

If player answers YES or speaks to the same NPC again:
Dialogue index: $AC, packed text address in bank 5: $B52B

If player answers NO:
Dialogue index $AD, packed text address in bank 5: $B539

I don't know if "Computer Gaming World" is a reference to the American magazine by the same name. I'm not American after all.


If I had to guess I'd say you're probably right in that hunch, but your guess is as good as mine here. I may be American but I was also quite young when this was originally released.

Looking forward to your hack when it's released, by the way. :thumbsup: I haven't played it in ages and this looks like a good reason to do so.

Fox Cunning


I am almost done restoring and fixing dialogues - there were quite a few typos and sentences that made little sense in the original script.
Here is one of the restored lines that did not appear in the released game probably because of a mistake in the pointers:

I've been also working on the battles, and specifically the enemies: most of the enemies from the computer versions of Ultima III have now been added!
Here's one example (wizards):


The extra enemies are great, do you think you'll be able to add all the missing enemies?


This looks so great.
Never bothered to play the game, because it felt so unpolished.
Once you complete your hack, I will definitely give it a try, if only for your care and dedication.

Fox Cunning

Quote from: coinilius on January 17, 2020, 12:05:09 AMThe extra enemies are great, do you think you'll be able to add all the missing enemies?

The enemies I managed to add so far are:

  • Troll
  • Zombie
  • Cutpurse
  • Fighter
  • Wizard
  • Orcus
Now the only missing ones are the "special" enemies: Horse (only found in Ambrosia), Chest (only in Castle Death), Grass (only outside Castle Death).

There is enough of room for extra enemy sprites, but the game uses sprite indices to recognise enemies in this way: NPCs (townsfolk) are $00 to $14, plus $1D which is Sherry/Noriko; roaming enemies are $15 to $1C; $1E is the Whirlpool; the Floor found in Castle Death "recycles" id $05 which is normally assigned to the player owned ship.
To index enemies $15 is subtracted from their ID, while for NPCs $1E is added.
However, enemies go from $00 (Orcs) to $16 (pirates), thus leaving $17 to $1C free to use (and that's where I added the enemies listed above).

Also since the game manages random encounters in a completely different way than the computer versions, it's probably not possible to add the Ambrosian Horses and the Grass without basically re-writing half the game.
Once I look better into how encounters are managed in the castle, I will see if there is any hope to include at least the Chest.

Quote from: Zimgief on January 17, 2020, 04:00:50 AM
This looks so great.
Never bothered to play the game, because it felt so unpolished.
Once you complete your hack, I will definitely give it a try, if only for your care and dedication.

Cheers mate, this game's always had lots of potential but I felt like it could have been much better - which is why I've been working on it for over a month now :laugh:
I still have a couple of gameplay/balance issues I want to fix, then it should be ready for playtesting while I finish polishing the graphics!

UPDATE 18 Jan 2020

Taking a break from the dialogue UI, I turned my attention to the dungeons and gave them a new "coat of paint".
Now each dungeon uses its own palette, fitting its "theme".

Also, I changed chest's graphics to a much larger sprite for the "3D" view, and chests can also be seen from one tile away instead of only being visible when you step on them.



I have also redone the ladders and the Marks graphics.

Now, as I was testing the game with a high level party I noticed that I was hugely underpowered in battle, and better gear did very little to improve that.
So I looked into the battle routines again, and this is what I found...

Hit chance is calculated using this formula: 8 >= RANDOM(0 to armour + 10)? hit : not hit
So with no armour: 20% miss chance. With Mystic Armour ($07): almost 53% miss chance.
Dexterity is not part of the formula, i.e. dexterous characters are not any more able to avoid damage.

The basic damage formula is: RANDOM(0 to ((enemy's min HP / 8 ) + (high byte of target's max HP * 2) + 1)) + X, where X is normally 6 but higher in dungeons or Castle Death.
So damage is a minimum of 6, and also depends on target's HP.

This can be definitely improved, and while the game should be more challenging at higher levels, the player should also be rewarded for levelling up and have new tools/abilities to better fight the more powerful enemies.
Here's what I thought...

  • Have armour also absorb a bit of damage (similarly to how armour works in Ultima VI)
  • Give high level Barbarians a damage bonus
  • Give high level Fighters an extra chance to avoid damage depending on their Dexterity
  • Give high level Thieves a "critical hit" chance based on their Dexterity
  • Slightly reduce MP consumed by higher level spells
  • Give magic users a chance to reduce magical damage taken (e.g. from Dragon's fireball) based on their caster stats (e.g. INT for Wizards, INT+WIS/2 for Druids etc.)

Thoughts? Opinions?


Great work with the improvements on the dungeons, I like the individual pallets and the new chests look good too.


if is possible, i only suggest a sprites for floor, and roof levels


Hard to say. I think you are the only knowledgable person about this game around here!
But I agree that leveling should be a reward, and that playing the game should never become a hassle (no necessary use of grinding or savestates).
Maybe later, once I have played a bit of your version of the game, could I make more useful suggestions.

Fox Cunning

Fair points!

So at the moment I'm almost done rebalancing the magic system. Nothing major, but lots of small changes.
Most notably, spells that previously had a fixed failure/miss chance will now fail more at lower levels and less at higher levels.

For example, the "Poison" spell had a fixed 75% chance of hitting each target, and the damage was completely random (based on frame counter + a shift register randomiser).
With my patch it now has a 50% hit chance (per target) at level 1, and scaling up to 80% at level 25.
Average damage is also increased with caster level instead of being based on the frame counter (but maximum damage will be the same).

The current roadmap is:
1. Finish the magic system rebalance.
2. Implement the  melee/ranged combat changes in my previous post.
3. Finish the "pre-made party" generation changes.
4. Work on the last graphics changes whilst posting a pre-release version of the patch here for gameplay testing.
5. Adjust the gameplay/fix bugs with feedback from pre-release testing.
6. Publish a finished version.

January 26, 2020, 06:05:06 PM - (Auto Merged - Double Posts are not allowed before 7 days.)

I found something interesting whilst working on the magic routines: the "Recall" spell, which was meant to permanently reduce the caster's Wisdom by 5, actually doesn't because of a bug (which is also present in the Japanese version).

Basically, the RAM location where the address to the caster's data is stored gets overwritten before the casting has finished, so instead of reducing the caster's Wisdom, one of the palettes is changed -- this would takes effect only if the screen flashes after casting "Recall", for example if you immediately cast another spell.
The change is temporary and lost if you enter a battle, go to another location, or just open the Status menu.

I had not found this mentioned anywhere. I guess nobody really used the spell. The Wisdom reduction was too much of a punishment for a party that had just had a character reduced to ashes.
You'd have to go all the way to Ambrosia to regain the lost points (at the risk of dying again) and spend 500 gold.

As part of my rebalance, I've changed it to temporarily reduce the caster's HP to 1.
Kind of a high-risk, high reward deal, but not as punishing.

Fox Cunning

Time for some weekly updates!

- Horses allow the party to walk through brush and trees unimpeded.
- Loot chests now have a chance of containing weapons and armour, much like in the computer versions. Higher level characters receive better weapons/armour. Shops are now more useful since you will have something to sell.
- Dialogue portraits have been completed, and each significant or recurring Ultima character now has their own unique graphics.
- Yew is populated by druids, similarly to the computer version of the game.
- As in the computer version, Gray now is home to jesters and scoundrels.
- Armour now also absorbs some damage.
- Characters with high Wisdom/Intelligence now have a chance of receiving less damage from magic attacks.
- Thieves now have a chance of scoring critical hits. The chance is based on character level, whilst the extra damage depends on Dexterity.
- Barbarians now deal a bit of extra damage at higher levels. This extra damage is added to each successful strike.
- XP gain has been completely reworked. If you accumulate XP without levelling up, you will soon start gaining less and less until you eventually stop gaining any XP. This is to discourage grinding at lower levels, which is made unnecessary by other gameplay changes anyway.
- Additional XP can be gained by fighting monsters in more dangerous areas, such as dungeons.

New lootDruids in YewTalking to Iolo

I have clearly used Ultima VI as a reference for portrait graphics.

What's left:
- A few minor bugs to iron out.
- A couple of typos to fix in the original text.
- Some palettes in the pre-game menus need fixing.
- There are still a few places that have duplicated shops.
- The intro "cutscene" with Lord British is being redone (or actually "redrawn").
- The Time Lord will eventually be redesigned too, to fit in with the new graphical style.
- I have explored the possibility of adding at least floor graphics to dungeons. I'm still not 100% sure it will be possible due to not enough room for extra patterns in the PPU, but I will keep it in the list and work on it after I have posted a pre-release version.
- I have also noted some areas where the code can be further optimised for speed (which in most cases means larger code), but I will leave that to after the first pre-release test when I will be more sure of how much extra space I can occupy.