JohnGlassmyer / UltimaHacks

Patches which add features to, and improve the usability of, the 1990s video games Ultima VII (BG and SI) and Ultima Underworld (I and II), along with a program to compile and apply these patches.
https://johnglassmyer.github.io/UltimaHacks/patcher-site
MIT License
129 stars 6 forks source link
game ultima-underworld ultima-vii uw1 uw2

Ultima Hacks

Overview

Some modifications to the video games Ultima VII: The Black Gate (1992), Ultima VII Part Two: Serpent Isle (1993), Ultima Underworld: The Stygian Abyss (1992), and Ultima Underworld II: Labyrinth of Worlds (1993), written as bits of (mostly 16-bit) x86 assembly, together with a program, written in Java, that patches them into the game's executable.

There is also a website (mentioned below) which can quickly apply pre-assembled versions of the patches, for people not interested in building the patches from source code.

The patches take the form of assembly files written in NASM syntax, and rely on some supporting macros that include metadata in the assembled output files regarding overall placement in the patched executable file as well as the locations of segment references (in particular, the segment portions of far procedure calls) which necessitate edits to the patched executable's relocation tables.

Each game with patches applied is fully playable in DOSBox and most likely on original (386/486) hardware as well (though I haven't had a chance to test the patches on original hardware).

Ultima VII: The Black Gate

Ultima VII Part Two: Serpent Isle

Changes focus on improving usability - allowing the player to do things more easily or more directly - and on adding keyboard control to what was a largely mouse-driven game.

New abilities

Other changes

Ultima Underworld: The Stygian Abyss

Ultima Underworld II: Labyrinth of Worlds

The biggest change is the addition of mouse-look (looking around by moving the mouse), which can be toggled on and off with a keypress. In support of this, the allowed range of vertical view angle has been greatly expanded, and the 3D rendering engine has been hacked to have it draw the bits of the world that become visible when the player looks sharply upward or downward.

Also, spell runes can be typed directly (with Ctrl+Alt+<letter>), without having to navigate through the inventory and the rune bag.

Things made more convenient:

A number of keys have been added or changed. The most important:

` (Backquote): toggle mouse-look
        Alt+`: invert mouse-look axes (cycles through 4 states)
         wasd: movement, typical of modern shooters
        Space: attack (using last attack type, or slash)
        Shift: jump
            q: look at object in 3D view
            e: use object in 3D view
            z: display map
            r: flip to rune-bag panel
            f: flip to character panel

Keys for spell-casting:

  Ctrl+Alt+<letter>: select a rune
 Ctrl+Alt+Backspace: clear selected runes
     Ctrl+Alt+Space: cast the selected runes

"Easy Move" actions:

      Ctrl+Up: Easy Move Walk Forward
    Ctrl+Left: Easy Move Left
   Ctrl+Right: Easy Move Right
    Ctrl+Down: Easy Move Backwards

Some miscellaneous keys:

            g: activate compass
            h: activate health and mana flasks
   Ctrl+Shift: standing long jump
        Shift: fly up
         Ctrl: fly down
            c: close container in inventory view
            v: scroll inventory down
            b: scroll inventory up

Keys for navigating the map:

            s: up one level
            w: down next level
            d: previous realm (Ultima Underworld II only)
            a: next realm (Ultima Underworld II only)
            c: go to Avatar's level

How to Apply the Patches

These patches are intended to be applied to particular versions of the games, all as distributed by GOG.com:

Pre-assembled patches can be applied to a game's executable in seconds with the Hack Applier website:

https://johnglassmyer.github.io/UltimaHacks/patcher-site

To use the website, select the game executable file (U7.EXE, SI.EXE, UW.EXE, or UW2.EXE) from your installation of the game, select the corresponding "hack" for that game from the drop-down, and then click the "Apply" button to save a patched copy of the executable, with which you can replace the original file in your installation of the game.

Game executables, as well as saved games, should be backed up before applying patches. Always keep a copy of the original, un-patched executable on-hand.

Note that if you intend to patch a GOG.com installation of Ultima Underworld or Ultima Underworld II that uses an ISO CD image (game.gog), then the executable file you need to patch is contained within that CD image. In that case, you can either

How to Build the Patches (Advanced)

If all you want to do is play the games with the patches applied, please use the Hack Applier site mentioned in the preceding section.

Building the patches from source requires that NASM (for assembling the individual patches), as well as a Java 1.9 or higher JDK and Apache Maven (for building the UltimaPatcher program), be installed and on the system path.

On Windows systems, Git for Windows provides a Bash shell capable of processing the example commands given.

The Java program UltimaPatcher must be built by invoking Maven in the UltimaPatcher directory:

UltimaHacks/UltimaPatcher$ mvn compile package

This should ultimately build a file UltimaPatcher/target/UltimaPatcher.jar.

The script scripts/patchFreshExe.sh performs the remaining steps necessary to build and apply patches to the game executable:

First, configure this script by editing patchingVariables.sh in the game's patches directory to set the correct paths to the original, unmodified executable (ORIGINAL_EXE) and the destination for the patched executable (TARGET_EXE).

E.g. in u7bg/patchingVariables.sh:

...
ORIGINAL_EXE=path/to/U7.EXE-original
TARGET_EXE=path/to/U7.EXE
...

Then, from the game's patches directory, run the script to build and apply the patches, e.g.:

UltimaHacks/u7bg$ ../scripts/patchFreshExe.sh *.asm

More about UltimaPatcher

More generally, UltimaPatcher has the capability to

The assembly file UltimaPatcher.asm provides NASM assembly macros used to produce assembled object files containing metadata that UltimaPatcher uses to apply patch blocks to an executable.