TITAN – Tool for Interpreting and Transforming Archival Nodes. CLI and library for Ultima 8: Pagan file formats.
Project description
titan-ultima
TITAN – Tool for Interpreting and Transforming Archival Nodes.
A Python CLI and library for working with Ultima 8: Pagan file formats. TITAN reads, converts, extracts, and reconstructs the game's proprietary archive and data formats — from sprite sheets and sound effects to full isometric world maps.
Run
titan --helpfor a full list of commands, ortitan <command> --helpfor per-command options.
What TITAN can do
| Category | Capability |
|---|---|
| Archives | Read, list, extract, create, and patch Flex (.flx) archives |
| Shapes | Decode RLE-compressed sprite frames to PNG; re-import edited PNGs |
| Palette | Export the VGA 6-bit palette as a colour swatch |
| Sound | Decode Sonarc-compressed audio (.raw) to WAV |
| Music | Convert XMIDI (.xmi) to standard MIDI |
| Maps | Render full isometric or top-down world maps from FIXED.DAT + GLOBs with engine-accurate dependency-graph depth sorting; merge live NPCs and items from save files; filter by all 16 TYPEFLAG bits (fixed, solid, sea, land, occl, bag, damaging, noisy, draw, ignore, roof, transl, editor, explode, unk46, unk47) |
| Type data | Decode TYPEFLAG.DAT shape physics/flag metadata |
| Gumps | Dump GUMPAGE.DAT container UI layout |
| Credits | Decrypt XOR-encoded ECREDITS.DAT / QUOTES.DAT |
| Saves | List and extract entries from U8 save archives |
Installation
pip install titan-ultima
Requires Python 3.9+, NumPy ≥ 1.24, Pillow ≥ 10.0, Typer ≥ 0.15.
Getting started
Option A — first-time wizard (recommended)
Run the interactive setup wizard once. It auto-detects your Ultima 8
installation, handles Pentagram/ScummVM save paths, writes titan.toml, and
optionally extracts the shape and glob archives for you.
titan setup
The wizard will:
- Search common GOG, Origin, and disc install paths for
FIXED.DAT - Ask you to confirm (or enter) the base path and language folder
- Detect
%APPDATA%\Pentagram\u8-save\U8SAVE.000and offer to use it as the live-object source - Write
titan.tomlin your current directory - Optionally run
flex-extractto populateshapes/andglobs/
After setup, map commands need no path arguments at all:
titan map-render -m 5 # renders map_005_iso_classic.png
titan map-render -m 0 --no-roof # roof tiles removed
titan map-render -m 39 --no-editor --no-ignore # player-accurate (no eggs/markers)
titan map-render-all --maps 0 5 39 --views iso_classic iso_high
Option B — manual setup (no config file)
If you prefer to supply explicit paths on every command, TITAN works without a config file too:
# One-time: extract the shape and glob archives
titan flex-extract U8SHAPES.FLX -o shapes/
titan flex-extract GLOB.FLX -o globs/
# Render a map
titan map-render \
--fixed FIXED.DAT --shapes shapes/ --globs globs/ \
--palette U8PAL.PAL --typeflag TYPEFLAG.DAT \
--map 5 -o map_005.png
# Player-accurate render (excludes editor eggs/markers and ignored shapes)
titan map-render \
--fixed FIXED.DAT --shapes shapes/ --globs globs/ \
--palette U8PAL.PAL --typeflag TYPEFLAG.DAT \
--nonfixed U8SAVE.000 --no-editor --no-ignore \
--map 39 -o map_039.png
Other useful commands (no config needed)
# Convert XMIDI music to standard MIDI
titan flex-extract MUSIC.FLX -o music_xmi/
titan music-batch music_xmi/ -o music_midi/
# Decode Sonarc sound effects to WAV
titan flex-extract SOUND.FLX -o sound_raw/
titan sound-batch sound_raw/ -o sound_wav/
# Export all shapes to PNG
titan shape-batch shapes/ -p U8PAL.PAL -o shapes_png/
Run titan <command> --help for per-command options, or see the full
CLI reference.
Configuration (titan.toml)
titan.toml stores default paths so map and other commands work without
repeating long paths on every invocation. CLI flags always override config
values.
File location
TITAN looks for the config in this order:
./titan.toml— current working directory (recommended)~/.config/titan/config.toml— Linux / macOS%APPDATA%\titan\config.toml— Windows
Use titan --config /other/path.toml <command> to override.
Format
[game]
base = "C:/ultima8" # root of your Ultima 8 install
language = "ENGLISH" # ENGLISH, FRENCH, GERMAN, etc.
# leave "" for flat mode (files directly in base/)
[paths]
# Relative paths are auto-expanded to <base>/<language>/STATIC/<name>
fixed = "FIXED.DAT"
palette = "U8PAL.PAL"
typeflag = "TYPEFLAG.DAT"
# Pre-extracted directories (relative to your working directory)
shapes = "shapes/"
globs = "globs/"
# Live objects — relative expands to <base>/<language>/SAVEGAME/<name>
# Absolute paths (e.g. Pentagram/ScummVM) are used unchanged
nonfixed = "U8SAVE.000"
A fully annotated template is available in
titan.toml.example.
Rules:
language = ""enables flat mode — all files expected directly inbase/; useful when you copy game files to your working directory.nonfixedwith an absolute path (e.g. a Pentagram save) is used as-is.shapesandglobsare always relative to the working directory, not the game install.
Inspecting the active config
titan config # show all resolved paths with OK / NOT FOUND status
titan config --edit # open titan.toml in your system editor
Library quick start
TITAN is also a Python library. Every CLI command has a corresponding module.
# Flex archives
from titan.flex import FlexArchive
archive = FlexArchive.from_file("U8SHAPES.FLX")
archive.extract_all("shapes/")
# Shapes + palette
from titan.shape import U8Shape
from titan.palette import U8Palette
pal = U8Palette.from_file("U8PAL.PAL")
shape = U8Shape.from_file("shapes/0001.shp")
frames = shape.to_pngs(pal)
frames[0].save("frame0.png")
# Map rendering
from titan.map import U8MapRenderer
renderer = U8MapRenderer(
fixed_path = "FIXED.DAT",
shapes_dir = "shapes/",
globs_dir = "globs/",
palette_path = "U8PAL.PAL",
typeflag_path = "TYPEFLAG.DAT",
)
img = renderer.render_map(map_num=5, view="iso_classic")
img.save("map_005.png")
# Save archives
from titan.save import U8SaveArchive
save = U8SaveArchive.from_file("U8SAVE.000")
for name, size in save.list_entries():
print(f"{name} {size:,} bytes")
nonfixed_bytes = save.get_data("NONFIXED.DAT")
Supported formats
| Format | Module | Game file(s) |
|---|---|---|
| Flex archive | titan.flex |
*.FLX |
| Shape sprites | titan.shape |
U8SHAPES.FLX → .shp |
| VGA palette | titan.palette |
U8PAL.PAL |
| Sonarc audio | titan.sound |
SOUND.FLX → .raw |
| XMIDI music | titan.music |
MUSIC.FLX → .xmi |
| World map (static) | titan.map |
FIXED.DAT, GLOB.FLX |
| World map (dynamic) | titan.map |
NONFIXED.DAT / U8SAVE.000 |
| Type flags | titan.typeflag |
TYPEFLAG.DAT |
| Gump layout | (cli only) | GUMPAGE.DAT |
| XOR credits | titan.credits |
ECREDITS.DAT, QUOTES.DAT |
| Colour transforms | titan.xformpal |
XFORMPAL.DAT |
| Save archives | titan.save |
U8SAVE.000–.005 |
Game files
TITAN requires the original Ultima 8: Pagan game files. If you own the game through GOG, the default install locations are:
| Platform | Method | Default path |
|---|---|---|
| Windows | GOG Galaxy | C:\Program Files (x86)\GOG Galaxy\Games\Ultima 8 |
| Windows | GOG Offline Installer | C:\GOG Games\Ultima 8 |
| Linux | GOG Galaxy / Offline | ~/GOG Games/Ultima 8 |
titan setup auto-detects these paths and others (legacy EA/Origin disc
installs, common manual redirects such as C:\ULTIMA8).
Typical GOG directory layout
<install root>\
├── ENGLISH\ ← language folder (FRENCH / GERMAN for other editions)
│ ├── STATIC\ ← core game data
│ │ ├── FIXED.DAT world map static objects
│ │ ├── GLOB.FLX reusable object groups (extract → globs/)
│ │ ├── U8SHAPES.FLX all sprites (extract → shapes/)
│ │ ├── U8PAL.PAL VGA colour palette
│ │ ├── TYPEFLAG.DAT shape physics / flag metadata
│ │ ├── GUMPAGE.DAT container gump UI layout
│ │ ├── XFORMPAL.DAT colour-transform palette
│ │ ├── ECREDITS.DAT encrypted credits text
│ │ ├── QUOTES.DAT encrypted quote text
│ │ ├── U8FONTS.FLX font shapes
│ │ ├── U8GUMPS.FLX UI gump shapes
│ │ └── EINTRO.SKF / ENDGAME.SKF
│ ├── SOUND\ ← audio
│ │ ├── SOUND.FLX sound effects (extract → sound_raw/)
│ │ ├── MUSIC.FLX music tracks (extract → music_xmi/)
│ │ └── E*.FLX language-specific voice/effects
│ └── USECODE\ ← game bytecode
│ └── EUSECODE.FLX
│
└── cloud_saves\ ← all GOG saves live here (not in the language folder)
└── SAVEGAME\
├── SGHEADER.DAT save slot names
└── U8SAVE.000–005 save archives
Note: GOG does not write saves into
ENGLISH\SAVEGAME\; all save files go tocloud_saves\SAVEGAME\.titan setupconfigures thenonfixedpath accordingly.
Pentagram save locations
| Platform | Settings folder | Save file |
|---|---|---|
| Windows | %APPDATA%\Pentagram\ |
%APPDATA%\Pentagram\u8-save\U8SAVE.000 |
| macOS | ~/Library/Application Support/Pentagram/ |
~/Library/Application Support/Pentagram/u8-save/U8SAVE.000 |
titan setup detects Pentagram saves on both Windows and macOS automatically.
Module → file reference
| TITAN module | Files needed | Location |
|---|---|---|
titan.flex |
Any .flx archive |
STATIC/ or SOUND/ |
titan.shape |
.shp files (extracted) |
Output of flex-extract U8SHAPES.FLX |
titan.palette |
U8PAL.PAL |
STATIC/ |
titan.sound |
.raw files (extracted) |
Output of flex-extract SOUND.FLX |
titan.music |
.xmi files (extracted) |
Output of flex-extract MUSIC.FLX |
titan.map |
FIXED.DAT, TYPEFLAG.DAT, extracted shapes/ + globs/; U8SAVE.000 (optional) |
STATIC/, SAVEGAME/ |
titan.typeflag |
TYPEFLAG.DAT |
STATIC/ |
titan.credits |
ECREDITS.DAT, QUOTES.DAT |
STATIC/ |
titan.save |
U8SAVE.000–.005 |
SAVEGAME/ or cloud_saves/SAVEGAME/ |
Requirements
- Python 3.9+
- NumPy ≥ 1.24
- Pillow ≥ 10.0
- Typer ≥ 0.15
- tomli ≥ 2.0 (Python < 3.11 only — for
titan.tomlsupport)
License
MIT
Important note
Ultima (Copyright 1981–1999, Electronic Arts)
To use this fan-made tool you must own a legitimate copy of Ultima 8: Pagan. This project is not affiliated with Electronic Arts. All rights to Ultima remain with Electronic Arts.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file titan_ultima-0.4.0.tar.gz.
File metadata
- Download URL: titan_ultima-0.4.0.tar.gz
- Upload date:
- Size: 68.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ba75dc4dea2f97f8b6faef0a84d02c1987a25f89c8a91b4945f7f96d81971365
|
|
| MD5 |
da792673e2dcd4dafc88317c1aaab63e
|
|
| BLAKE2b-256 |
f1ef2d4d7e4080c58af7ca727bec93e8485aa13ed8bd805058698380cb7461d1
|
File details
Details for the file titan_ultima-0.4.0-py3-none-any.whl.
File metadata
- Download URL: titan_ultima-0.4.0-py3-none-any.whl
- Upload date:
- Size: 59.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bb398cb6e0b23ddde5048b691d5459ad0013ff8555511d6d6839262ee25f3c97
|
|
| MD5 |
d29c290eb71ef3078874ace9c8210445
|
|
| BLAKE2b-256 |
d55818d5fbed21269599b38d9f3790090280c3f7cfa776e270f3691089038912
|