Skip to content
bonkzwonilPublic

About

A savegame editor for Ultima IV: Quest of the Avatar_that runs in your terminal, and speaks both save formats: the original DOS `PARTY.SAV` and ScummVM's slots.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

4 Commits

Folders and files

Repository files navigation

u4ed

A savegame editor for Ultima IV: Quest of the Avatar that runs in your terminal, and speaks both save formats: the original DOS PARTY.SAV and ScummVM's slots.

No Windows. No Wine. No hex editor. Point it at a save, fix your party, keep playing, and move a game between DOSBox and ScummVM in both directions.

Character editor

Why u4ed?

  • Two formats, autodetected. Give it a DOS game directory (or PARTY.SAV) or a ScummVM slot file (~/.local/share/scummvm/saves/ultima4_enh.000) and it figures out the rest. Pointing it at the ScummVM saves directory lists the slots with their names.
  • Export to the other format. Started in ScummVM and want to finish in DOSBox, or carry your Avatar on to Ultima V? Ctrl+E writes a classic PARTY.SAV + MONSTERS.SAV. Coming from DOS? The same key creates a ScummVM slot, with a name and thumbnail so it shows up in ScummVM's load menu.
  • Every save is a version. The same bzip2 version history as u3edit: readable change logs, one-key restore, and your game's own saves are captured as well.
  • Plays nice while you play. If ScummVM or the game saved while the editor was open, u4ed merges your edits on top of the new state field by field instead of throwing away your progress. Ctrl+R reloads while you play.
  • Byte-exact. Only the fields you touch change. In ScummVM slots, the monster tables, metadata and thumbnail are carried over untouched. A no-op save leaves the file bit-for-bit identical.

⏳ The version history

Version history

  • Every save adds a version. Each one is a small bzip2 tarball in .u4ed-history/ next to the save. ScummVM slots get one folder per slot.
  • Your originals are always version 1.
  • Game saves are captured. If the game wrote the files since the last version, that state is recorded as "Changed outside u4ed" before anything is overwritten. Above: ScummVM autosaved after the party walked two steps, and u4ed kept both that save and the user's edits.
  • Readable change logs. For example Jaana: status Poisoned → Good, hit points 143 → 400, gold 1337 → 9999 or +rune of Valor.
  • Restore any version with F5 → r. The restore is itself a new version, so it can be undone too.
  • No lock-in. tar -xjf gets your files back without u4ed.

Features

Inventory Magic
Inventory Magic
Virtues World
Virtues World
  • Characters (all 8): name, sex, class, status (Good / Poisoned / Sleeping / Dead), HP, max HP, XP, Str, Dex, Int, MP, equipped weapon and armour, derived level
  • Inventory: food, gold, torches, gems, keys, sextants, all armour and weapon stocks
  • Magic: all 8 reagents and all 26 spell mixtures
  • Virtues: karma for all eight virtues (0 = elevated, i.e. partial Avatarhood), the eight runes, the eight stones, and the quest items (Bell, Book, Candle, the three-part key, Silver Horn, Wheel, Skull)
  • World: moves, position, party size, transport, both moon phases, ship hull
  • F3 heal: status Good and full HP. F4: revert one character.
  • Export dialog with a suggested free ScummVM slot:

Export

Installation

Requires Python ≥ 3.10 and uv.

cd u4ed
uv run u4ed ~/.local/share/scummvm/saves/ultima4_enh.000   # a ScummVM slot
uv run u4ed ~/dos/ultima4                                   # a DOS game dir

uv tool install . puts u4ed on your PATH.

Usage

u4ed PATH                                    # open the TUI (format autodetected)
u4ed PATH --dump                             # print party, inventory, virtues
u4ed ~/.local/share/scummvm/saves            # lists the ScummVM slots to choose from
u4ed SLOT --export ~/dos/ultima4-copy/       # ScummVM -> PARTY.SAV + MONSTERS.SAV
u4ed ~/dos/ultima4 --export ~/.local/share/scummvm/saves/ultima4_enh.007 --name "From DOS"

--export refuses to overwrite existing files unless you add --force.

Key Action
↑ / ↓ select a character (★ = in the party)
Ctrl+S / F2 save (adds a history version)
F3 heal the selected character
F4 revert the selected character
F5 version history
Ctrl+R / F6 reload from disk
Ctrl+E export to the other format
Ctrl+P command palette
Ctrl+Q quit

Export limitations

The conversion works for saves made on the surface of Britannia. Inside a town or a dungeon, the DOS game keeps extra state in OUTMONST.SAV/DNGMAP.SAV that ScummVM doesn't store, so u4ed refuses: walk outside, save, and export that save. Editing works everywhere.

File formats

Original PARTY.SAV (502 bytes, little-endian): u32 unknown, u32 moves, 8 × 39-byte player records (hp, hpMax, xp, str, dex, int, mp, unknown, weapon, armour as u16; name[16]; sex 0x0B/0x0C, class 0-7, status G P S D), food (u32, hundredths), gold, karma[8], torches, gems, keys, sextants, armour[8], weapons[16], reagents[8], mixtures[26], items (bitmask), x, y, stones, runes, members, transport, balloon, Trammel, Felucca, hull, lbIntro, lastCamp, lastReagent, lastMeditation, lastVirtue, dngx, dngy, orientation, dnglevel, location.

ScummVM slot (gzip): bytes 0x000-0x1D1 are identical to PARTY.SAV. Then come a location chain (u8 count + x/y/z/map per level, world first), orientation, items, stones, runes, the same 11 u16 fields, then one "MONS" + 256-byte monster table per map (the MONSTERS.SAV layout), then ScummVM's extended header (SVMCR, slot name, date, play time, THMB thumbnail). The offset of that header is stored in the last 4 bytes.

Sources: ScummVM engines/ultima/ultima4/filesys/savegame.{h,cpp}, engines/metaengine.cpp and graphics/thumbnail.cpp, plus xu4's savegame.cpp. Verified against real DOS and ScummVM saves (tests/fixtures).

Development

uv run pytest                          # model, formats, export round trips, headless TUI tests
uv run python scripts/make_demo.py     # rebuild the demo saves (both formats)
uv run python scripts/screenshots.py   # re-render docs/screenshots (needs inkscape)

The screenshots show the demo party from tests/fixtures/demo: the Avatar, Werdna (yes, that one), adventuring with Iolo, Shamino, Dupre, Mariah, Geoffrey, Jaana and Katrina.

License

MIT © 2026 Mathias Menzel-Nielsen

About

A savegame editor for Ultima IV: Quest of the Avatar_that runs in your terminal, and speaks both save formats: the original DOS `PARTY.SAV` and ScummVM's slots.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages