Skip to main content

titan-ultima

TITAN - Tool for Interpreting and Transforming Archival Nodes.

TITAN is a Python CLI and library for working with proprietary data formats from Ultima 8: Pagan, Ultima Underworld: The Stygian Abyss, Ultima Underworld II: Labyrinth of Worlds, Ultima 7: The Black Gate / Serpent Isle, Ultima 6: The False Prophet, and the Ultima Online Classic Client. It reads, extracts, converts, inspects, and reconstructs archives, shapes/tiles, palettes, music, speech, maps, world objects, saves, dialogue, and Exult runtime data. Early Ultima 9: Ascension support (FLX archives, TYPENAME.FLX, and sound/*.flx decoding) is also available under titan u9. Deterministic Ultima III: Exodus NES Sosaria-to-U7 map conversion is available under titan u3.

Run titan --help, titan uw1 --help, titan uw2 --help, titan u8 --help, titan u7 --help, titan u6 --help, titan u3 --help, titan u9 --help, titan uo --help, or see the full CLI reference.


Installation

pip install titan-ultima

Requirements:

  • Python 3.9+
  • NumPy >= 1.24
  • Pillow >= 10.0
  • Typer >= 0.15
  • questionary >= 2.0
  • tomli >= 2.0 on Python < 3.11, for titan.toml support

Optional:

  • pyvista plus VTK (pip install pyvista) — used by titan uw2 model-render, uw2 map-3d-render, U9 preview rendering, and u9 map-render-3d.
  • trimesh (pip install "titan-ultima[glb]") — used by titan uw2 map-3d-export and titan u9 map-export-glb to write GLB. Standalone OBJ/STL model export does not require it.

Quick Start

Run setup once. It detects common Ultima 8, Ultima 7, and UO install locations, detects Exult runtime folders and the Exult install directory (for exult_bg.flx / exult_si.flx), writes titan.toml, and can extract the U8 shape/glob data used by map rendering.

titan setup

After setup, many commands can use configured paths:

# U8 map render
titan u8 map-render -m 5

# U8 dialogue web viewer
titan dialogue prepare
# Optional: export NPC JSON files and META sidecars
titan dialogue copy
titan dialogue validate
titan dialogue launch

# U7 configured commands
titan u7 map-render --game bg --sc 85 -o britain_bg.png
titan u7 typeflag-dump --game si -f csv -o tfa_si.csv
titan u7 gamedat-info --game si -f detail -o gamedat_info.txt

# Build embedded U3 NES Sosaria as a selected native U7 secondary map
titan u3 map-create si_source_map.json --output-root scratch/ --map-num 4 --no-render

# UO configured commands, if [uo.game] base is set
titan uo gump-export -o uo_gumps/
titan uo animation-body-names-export -o uo_metadata/

titan setup doesn't detect Ultima 6 installs yet — add [u6.game] base = "<Ultima 6 install>" to titan.toml yourself, or pass -g/--gamedir explicitly on every U6 command:

titan u6 map-render -g "C:/Ultima6" --full -o u6_world.png

Ultima Underworld II install detection is not in titan setup yet. Add its root manually; commands also accept -g/--gamedir:

[uw2.game]
base = "C:/Games/Ultima Underworld 2"
titan uw2 map-render --slots 0 -o castle_maps/
titan uw2 model-render --item 0x158 --item 0x15c -o model_renders/
titan uw2 model-export -o model_exports/
titan uw2 object-info 457
titan uw2 shape-export OBJECTS.GR 302 -o fountain/
titan uw2 shape-export ANIMO.GR 6 -o fountain/

If setup cannot find UO automatically, add it manually:

[uo.game]
base = "C:/Program Files (x86)/Electronic Arts/Ultima Online Classic"

The detailed dialogue web documentation lives in src/titan/dialogue/websrc/READMEd.md.


Capabilities

The table below is the compact command map. The CLI reference is the main place for command options, longer examples, and format notes.

Area Ultima 8 Ultima 7 / Exult Quick example Reference
Archives Flex .FLX list/extract/create/update Create an empty U7/Exult archive via u7 flex-create; add a standalone shape to its lowest permitted empty or a specific record via u7 flex-add-shape (SHAPES.VGA automatic allocation starts at 150) titan u7 flex-add-shape U7O.VGA actor.shp --index 460 --in-place Shared Flex commands, U7 Flex commands
Shapes Export/import U8 .shp frames; shape-batch also accepts U8SHAPES.FLX directly and uses bundled U8 class names in exported PNG filenames when available Export U7 shapes from SHAPES.VGA, FACES.VGA, etc.; create standalone .shp files from A-Z-sorted PNG frames via shape-import; export combined frame/origin/hotspot/WIHH data via shape-frame-report; render animations via shape-animate; inventory cycling/translucency/animation content via shape-cycle-scan titan u7 shape-frame-report STATIC/SHAPES.VGA -o shape_frames.csv U8 commands, U7 shape commands
Shape conversion shape-convert-u7/shape-convert-u7-all: convert one or every U8 static/scenery shape into a U7/Exult-compatible shape (resize + palette requantize + hotspot-convention shift, footprint-calibrated against real U7 game data) (target format) titan u8 shape-convert-u7-all STATIC/U8SHAPES.FLX --typeflag STATIC/TYPEFLAG.DAT --u7-static /path/to/u7/STATIC U8 shape-convert-u7
Palettes Export U8 VGA palette Export 12+ U7 palettes from PALETTES.FLX; inspect slots, semantic names, and colour-cycling via palette-info titan u7 palette-export PALETTES.FLX -o palettes/ U7 palette commands
Music XMIDI to MIDI from MUSIC.FLX (preserves embedded playlist names in exported MIDI filenames when present) MIDI export from ADLIBMUS.DAT, MT32MUS.DAT, ENDSCORE.XMI; optional GM rewrite titan u7 music-export MT32MUS.DAT --target gm -o music_gm/ U8 music commands, U7 music commands
Sound and speech Sonarc sound effects and speech FLX archives (preserves embedded 8-byte SFX identifiers in exported WAV filenames when present) Creative Voice .voc decode and U7SPEECH.SPC export titan u7 speech-export U7SPEECH.SPC -o speech_wav/ Sound commands, U7 voice commands
Dialogue web Prepare, optionally copy NPC JSON/META files, validate, and launch the U8 dialogue web machine Not applicable titan dialogue launch Dialogue CLI, Dialogue README
Maps Render U8 isometric/top-down maps from FIXED.DAT, GLOBs, shapes, saves Export, render, and materialize universal U7 map JSON; create empty secondary Exult maps; render native maps with SHAPES.VGA and optional u7ireg* titan u7 map-export-json STATIC/ -o u7_map.json U8 map commands, U7 map commands
Type data Decode U8 TYPEFLAG.DAT Decode U7 TFA.DAT, SHPDIMS.DAT, WGTVOL.DAT, OCCLUDE.DAT titan u7 typeflag-dump STATIC/ -f csv -o tfa_data.csv U8 data commands, U7 type flag commands
Saves and runtime data List/extract U8 save archives Read Exult .sav; inspect loose gamedat/; dump NPCs, schedules, flags titan u7 save-info exult00bg.sav U8 save commands, U7 save commands
Fonts U8 font archives can be extracted as Flex data U7 font-create wizard for Exult-compatible font shapes titan u7 font-create U7 font-create
World query Not applicable Repeatable IFIX/IREG searches with shape/frame, name, class, flags, area, mod inheritance, refinement and TOML recipes titan u7 world-query --game bg U7 world-query
Container data Not applicable Browse IREG container contents with full nesting; filter by container name, item name, or tile area; optional per-frame item names via Exult FLX titan u7 container-browse --game bg --container-name chest U7 container-browse
Egg data Not applicable Query IREG egg trigger objects — type, usecode function, probability, location titan u7 egg-query --game bg --type usecode U7 egg-query
Text and misc data Gump layout, XOR credits, quotes, transform palettes Global flags and selected runtime metadata titan u8 credits-decrypt ECREDITS.DAT U8 data commands

Ultima Underworld

Native UW1 support currently covers all floor/ceiling and wall texture archives. It preserves texture IDs, uses palette 0 from PALS.DAT, joins the descriptions in STRINGS.PAK, and writes both CSV and JSON manifests.

titan uw1 texture-info -g "C:/UW1"
titan uw1 texture-export -g "C:/UW1" -o uw1_textures/ --contact-sheets

See UW1 commands.

Ultima Underworld II

Native UU2 support covers LEV.ARK map extraction, 2D cutaway maps, textured 3D map rendering/GLB export, standalone built-in model rendering/export, PALS.DAT, terrain and .GR image archives, ALLPALS.DAT auxiliary palettes, COMOBJ.DAT render metadata, and OBJECTS.DAT animation descriptors. Map rendering uses verified OBJECTS.GR icons for model-based furniture by default and can optionally project built-in UW2.EXE geometry. Standalone model commands decode that geometry directly, apply palette materials and item-selected TMOBJ.GR textures, then render PNG views or write one OBJ/MTL/PNG asset set per item. Placed meshes use native scale 1, clockwise 45-degree headings, and the 0x0078 model pivot; standalone OBJ vertices are also relative to that pivot. NPC animation archives remain future work.

Area Coverage Quick example
Maps Render directly from LEV.ARK, terrain, doors, decals, OBJECTS.GR, animated ANIMO.GR overlays, and 2D furniture icons; optional UW2.EXE geometry and diagnostic extraction titan uw2 map-render --slots 0 -g "C:/UW2" -o maps/ --tick 1
3D maps Render selectable camera views or export GLB from textured tile geometry, placed UW2.EXE furniture, and sprite/ANIMO billboards; objects remain individually named titan uw2 map-3d-render --slot 0 --region 17,46,22,52 -g "C:/UW2" -o castle_3d/
3D objects Render standalone camera views or export 21 mapped built-in item IDs as individual OBJ/MTL assets; UV faces use TMOBJ.GR, other faces use palette materials titan uw2 model-export -g "C:/UW2" -o models/
Palettes Export any 256-color VGA palette from PALS.DAT titan uw2 palette-export PALS.DAT --index 0 -o palettes/
Shapes Inspect/export one or every non-empty image from any .GR archive titan uw2 shape-export OBJECTS.GR 302 -g "C:/UW2" -o fountain/
Object metadata Dump sprite/NPC/model/texture render types; inspect ANIMO.GR frame ranges titan uw2 object-info 457 -g "C:/UW2"

See UU2 commands.

Ultima 6

U6 support covers reading (and limited save-editing of) the full game: tiles, world/dungeon maps, world objects and eggs, actors, party/game state, story flags, dialogue, and text/reference data.

Area Coverage Quick example
Archives LZW decompression; lib_16/lib_32 library files (CONVERSE.A/B, etc.) titan u6 lib-list CONVERSE.A
Graphics Tiles (plain/transparent/pixel-block), palette, TILEFLAG terrain/object metadata titan u6 tile-export-all -g "<install>" -o tiles_png/
Maps Surface world and dungeon-level rendering, animated tiles, correct multi-tile object compositing, optional world-object overlay titan u6 map-render -g "<install>" --full -o u6_world.png
World objects Object placement with container/inventory resolution; eggs (spawn probability/target); the 256-actor identity table titan u6 object-list -g "<install>" --block 5
Story and saves Party roster, player state, clock/weather; read/compare/write per-NPC talk flags and global quest state, including writing changes back to a save titan u6 gamestate-dump -g "<install>/SAVEGAME"
Dialogue CONVERSE.A/B bytecode disassembler, with known global variables annotated by name titan u6 converse-dump CONVERSE.A --item 5
Text and reference data Fonts (English + runic/gargoyle); object names; books/signs; NPC daily schedules titan u6 book-dump BOOK.DAT --book 0

See the U6 commands reference for the full command list.

Ultima 9 (early)

U9 support is newer than U8/U7 and includes FLX archives, TYPENAME.FLX, sound/*.flx (Speech.flx, sfx.flx, music.flx) decoding and metadata, PCM/native-record replacement, anim.flx skeletal clips, and 3D model + texture export from static/sappear.flx.

The U9 format completeness index separates complete format support from structurally complete readers whose remaining questions concern field or gameplay semantics.

Area Coverage Quick example
Archives List/extract any U9 .flx/.FLX archive titan u9 flx-list sound/Speech.flx
Save integrity Verify selected archive custody, fixed/nonfixed allocator structure, and fixed-layout compatibility; display separate verdicts or write JSON titan u9 save-check C:\Ultima\Ultima9 --fixed-reference C:\Ultima\Ultima9\static
Metadata Decode TYPENAME.FLX type-ID → name pairs titan u9 typename-dump static/TYPENAME.FLX
Sound and speech Decode audio to WAV; report sizes/codecs/SFX links and lossless sfxenv.flx acoustic presets; replace one or many records from compatible PCM WAV or native data titan u9 sound-report sound/ -o sounds.csv
Dialogue text List, search and export text.flx/misctext.flx strings by source block; parse and round-trip the text.dat key table, reproduce the game's "<speaker> : <line>" lookup, and export each item with its verified key and target line titan u9 text-keys-export static/text.dat -t static/text.flx --npcs runtime/NPC.FLX -o text_keys.csv
Palette Inspect ankh.pal, its exact index-254 transparency key and duplicate slots; export a PNG swatch plus complete text table titan u9 palette-export static/ankh.pal -o palette/
Texture archives Parse headers/directories/row tables and export any frame or stored mip from bitmap*.flx; the same reader handles all 6,898 pre-baked terrain panels in Texture8.*/texture16.* titan u9 texture-export static/Texture8.9 1087 -p static/ankh.pal -o panels/
Terrain and region maps Losslessly parse terrain.* grids/chunks and environment headers; render textured bird's-eye maps with water, depth-tested model meshes, filterable footprints, and exact cell/tile/chunk-ID grids; catalogue every region in a labelled numeric atlas; export bounded Y-up GLB scenes with shared repeated-model meshes; render those scenes through VTK/OpenGL with a south-high orthographic camera titan u9 map-render-3d britannia.glb --width 8192 --height 8192 -o britannia_south_high.png
3D models and textures Parse and losslessly round-trip all 3,748 retail hierarchical sappear.flx records, expose connection geometry separately, and explicitly retain but quarantine 16 orphaned indexed records as forensic data; export game-compatible render meshes to textured OBJ+MTL+PNG or geometry-only STL, with optional naming and previews titan u9 model-export static/sappear.flx 2 -t static/bitmap16.flx -o model_2/
Animation clips Losslessly parse every anim.flx clip's signed header, active registry IDs and inactive capacity residue, named transform tracks and typed events; report stored-sample and controller timing separately; export registry-backed candidates, a selected static pose, or a versioned rigid-animation bundle containing local limb meshes, exact tracks and an animated GLB titan u9 animation-bundle-export static/anim.flx 172 static/sappear.flx 3223 -o avatar_bundle/
2D UI icons List/export the standalone 2D icons (spell-rune sigils, item icons, ...) mixed into the same bitmap16.flx/bitmapC.flx/bitmapsh.flx archives as 3D model textures -- identified as the entries no sappear.flx model ever references, kept in a separate module/command group/output dir from the mesh commands above titan u9 icon-export-all static/sappear.flx static/bitmapsh.flx -p static/ankh.pal -o icon_export/

U9 2D map commands default to the 28-pixel-per-cell --resolution full preset; 75, 50, and 25 select proportional smaller outputs. The VTK/OpenGL u9 map-render-3d command defaults to 16,384x16,384, with --resolution half selecting 8,192x8,192.

See the U9 commands reference for the full command list.

Ultima Online Classic Client

UO support is export-oriented: it reads the installed Classic Client data directly and writes reviewable PNG, WAV, and CSV outputs. The client directory can be passed per command or configured once as [uo.game] base.

Area Coverage Quick example
2D art Land/static art, gumps, textures, lights, fonts, radar colors, hues titan uo gump-export -o gumps/
World metadata Tiledata, animdata.mul, art.def, all .def redirect files, localization/speech/skills text, multis titan uo def-export -o defs/
Audio and animation Sound effects to WAV; legacy animation frames with body/action/direction naming, resolution metadata, and packaged body-name clues titan uo animation-export --limit 20 -o anims/

See the UO commands reference for the concise command list.


Common Workflows

U8 Dialogue Web

titan dialogue prepare
# Optional NPC export step
titan dialogue copy
titan dialogue validate
titan dialogue launch

For setup, local development, export behavior, and known dialogue-machine limits, see the dedicated dialogue web README.

U7 Exult Runtime Inspection

# Inspect configured Serpent Isle GAMEDAT, including mod fallback sources.
titan u7 gamedat-info --game si -f detail

# Inspect a mod's packaged patch/initgame.dat archive directly.
titan u7 gamedat-info mods/<mod-name>/patch/initgame.dat --static STATIC/

# Inspect a specific Exult save archive.
titan u7 save-info exult00si.sav
titan u7 save-npcs exult00si.sav --static STATIC/ -f detail
titan u7 save-schedules exult00si.sav -f detail

U7 Map Creation, Interchange, and Rendering

# Export a complete native map to universal JSON.
titan u7 map-export-json STATIC/ -o u7_map.json

# Render directly from JSON without consulting native U7 map files.
titan u7 map-render-json u7_map.json --static STATIC/ --sc 0x55 \
  -o superChunk_85_from_json.png

# Materialize universal JSON as a selected native secondary map.
titan u7 map-create --output-root scratch/ --map-num 4 --from-json u7_map.json

# Superchunk render.
titan u7 map-render STATIC/ --sc 0x55 -o superChunk_85.png

# Full world render.
titan u7 map-render STATIC/ --full -o u7_world.png

# Minimap sample with grid.
titan u7 map-sample STATIC/ --scale 4 --grid -o minimap.png

u7 map-render also accepts an Exult mod's patch/ directory as its graphics and map source. If that directory's SHAPES.VGA is a sparse override archive, Titan fills its empty records in memory from the base game selected by --game bg|si and configured in titan.toml. If those paths are not configured, Titan looks for the nearest base STATIC/ above the mod's patch/ directory. Complete base-game archives continue through the normal renderer path unchanged.

U7 map rendering combines each shape's TFA footprint with its real SHAPES.VGA frame count. Frame bit 0x20 swaps X/Y dimensions only for shapes with 32 or fewer real frames, where frames 32+ are generated reflections. Shapes with more than 32 real archive frames keep their stored dimensions. This matches current Exult behavior and fixes extended mod doors and other multi-frame objects without changing door-state or open-frame rules.

U7 shape export, batch export, animation, cycle scans, frame reports and shape insertion share the same base-plus-patch resolution. Archives inside an Exult mods/ or patch/ tree discover their matching base VGA in the nearest game STATIC/ directory, then fall back to the selected --game configuration. For copied or renamed patches, provide --base-archive path/to/SHAPES.VGA. Imports check occupancy in both archives and preserve the sparse patch on disk; overriding an inherited shape requires --index N --replace. A recognized patch whose base cannot be found fails with instructions to provide --base-archive.

Root Flex updates preserve the detected U7/Exult or U8 format. Extraction manifests also preserve the format and header for reconstruction; fresh root flex-create outputs use U7 for .VGA, otherwise U8 unless --archive-format u7 is supplied.

U3 NES Sosaria Map Creation

# List U3 NES commands, then inspect every map-create option
titan u3 --help
titan u3 map-create --help

# Export the Serpent Isle construction source
titan u7 map-export-json --game si -o si_source_map.json

# Create the map in the selected native U7 secondary-map slot
titan u3 map-create si_source_map.json \
  --output-root "D:/work/maps" --map-num 4 --seed 42

U3-specific generation uses Titan's embedded original NES overworld, then passes resulting universal map document directly to shared U7 native writer. Existing mapNN replacement still requires --overwrite-map; shared terrain append still requires --update-chunks. Interactive runs offer a full classic render after creation. Scripts can choose --render or --no-render.

U7 World Query

# Interactive wizard — walks through shape class, flag, and area filters.
titan u7 world-query --game bg

# With explicit paths (no titan.toml required).
titan u7 world-query STATIC/ --gamedat gamedat/

# Pre-set STATIC from config, add a runtime GAMEDAT for IREG objects.
titan u7 world-query --game si --gamedat Exult/serpentisle/gamedat

The wizard prompts for shape-class checkboxes, optional shape numbers, TFA flag checkboxes, area (all or specific superchunks), and output format (summary / full text / CSV). Output can be printed or saved to a file.

U7 Container Browse

# Interactive wizard — configured BG paths.
titan u7 container-browse --game bg

# Show all chests with their full contents tree.
titan u7 container-browse STATIC/ --gamedat gamedat/ --container-name chest

# Find containers holding a sword.
titan u7 container-browse STATIC/ --gamedat gamedat/ --contains-name sword

# Export to CSV with per-frame item names (requires Exult installation).
titan u7 container-browse STATIC/ --gamedat gamedat/ -f csv -o containers.csv \
  --exult-flx "<Exult install>/data/exult_bg.flx"

# Configured paths with per-frame names from titan.toml [exult.paths].
titan u7 container-browse --game bg --container-name desk

U7 Egg Query

# Interactive wizard — configured BG paths.
titan u7 egg-query --game bg

# All usecode eggs.
titan u7 egg-query STATIC/ --gamedat gamedat/ --type usecode

# Find every placement of a specific usecode function.
titan u7 egg-query STATIC/ --gamedat gamedat/ --fn 0x06BC

# Export usecode eggs to CSV.
titan u7 egg-query STATIC/ --gamedat gamedat/ --type usecode -f csv -o usecode_eggs.csv

U8 Map Rendering

titan u8 map-render -m 5
titan u8 map-render -m 0 --no-roof
titan u8 map-render-all --maps 0 5 39 --views iso_classic iso_high

U6 World Rendering

# One surface superchunk, with world objects (furniture, items, etc.) overlaid.
titan u6 map-render -g "C:/Ultima6" --region 0,0,64,64 --objects -o chunk0.png

# A dungeon level.
titan u6 map-render -g "C:/Ultima6" --dungeon 0 --objects -o dungeon0.png

# The entire surface world.
titan u6 map-render -g "C:/Ultima6" --full -o u6_world.png

U9 Sound Extraction

# List an archive's decoded entry headers first.
titan u9 sound-list sound/Speech.flx

# Decode every supported entry to WAV (PCM, mono/stereo ADPCM, EA MicroTalk).
titan u9 sound-extract sound/Speech.flx -o speech_wav/
titan u9 sound-extract sound/sfx.flx -o sfx_wav/
titan u9 sound-extract sound/music.flx -o music_wav/

# Report all audio metadata and SFX-template links.
titan u9 sound-report sound/ -o u9_sound_records.csv

# Replace TV sound 1322 from 22,050 Hz, 16-bit mono PCM WAV into a new FLX.
titan u9 sound-import sound/sfx.flx 1322 1322_EASports.wav -o sfx_patched.flx

U9 Palette Inspection and Export

# Inspect layout, exact transparency semantics, and repeated colour slots.
titan u9 palette-info static/ankh.pal --duplicates

# Write a 16x16 RGB swatch and a complete RGB/reserved/alpha text inventory.
titan u9 palette-export static/ankh.pal -o palette/

U9 3D Model Export

# Inspect record type plus limb/LOD/render/mount/material/texture counts first.
titan u9 model-info static/sappear.flx 2

# Export every material field and join texture metadata from all tiers found
# in the static directory, including invalid UV counts per material row. Limit
# to one model with --model or use --only errors when desired.
titan u9 model-material-report static --model 3306 -o television_materials.csv

# Export a textured OBJ (+ MTL + PNG textures) -- bitmap16.flx covers every
# real texture referenced by any model in this project's test copy of the game.
# preview.png (back-ish) + preview_front.png (rotated 180 degrees) are rendered
# alongside it automatically (needs `pip install pyvista`).
titan u9 model-export static/sappear.flx 2 -t static/bitmap16.flx -o model_2/

# Add real palette colors for any 8-bit textures instead of flat grayscale.
titan u9 model-export static/sappear.flx 2 -t static/bitmapsh.flx -p static/ankh.pal -o model_2/

# Geometry-only STL, no textures or preview needed.
titan u9 model-export static/sappear.flx 2 -f stl --no-preview -o model_2_stl/

U9 Texture Inspection and Export

# Inspect the decoded set/frame headers and every stored mip size.
titan u9 texture-info static/bitmap16.flx 568

# Export dynamic frame metadata across all three tiers. Matching sdInfo,
# sappear material animation evidence, and model names are auto-discovered.
titan u9 texture-frame-report static --entry 7344 -o television_frames.csv

# Export one of the game's own stored mip levels.
titan u9 texture-export static/bitmap16.flx 568 --mip 2 -o textures/

# Texture8/texture16 terrain-panel files use the same entry format.
titan u9 texture-export static/Texture8.9 1087 -p static/ankh.pal -o panels/

U9 Terrain Inspection and Export

# Includes signed water level, floating wave amplitude and raw region flags.
titan u9 terrain-info static/terrain.9

# Inspect the UV orientation encoded at each point in a placed chunk.
titan u9 terrain-chunk static/terrain.9 -t 12,20 -f uv-rotation

# Count textures across the placed terrain surface, not orphaned chunk data.
titan u9 terrain-textures static/terrain.9 --sdinfo static/sdInfo16.flx

Configuration

titan.toml stores default paths so commands can run without long path arguments. Command-line options always override config values.

Config search order:

  1. ./titan.toml
  2. ~/.config/titan/config.toml
  3. User profile folder titan\config.toml

Use titan --config <other config.toml> <command> to override.

Minimal multi-game shape:

[u8.game]
base     = "<Ultima 8 install>"
language = "ENGLISH"

[u8.paths]
fixed    = "FIXED.DAT"
palette  = "U8PAL.PAL"
typeflag = "TYPEFLAG.DAT"
shapes   = "shapes/"
globs    = "globs/"
nonfixed = "U8SAVE.000"

[u7bg.game]
base    = "<Black Gate install>/ULTIMA7"
variant = "blackgate"

[u7bg.paths]
static  = "STATIC/"
shapes  = "STATIC/SHAPES.VGA"
palette = "STATIC/PALETTES.FLX"
gamedat = "gamedat/"

[u7si.game]
base    = "<Serpent Isle install>/SERPENT"
variant = "serpentisle"

[u7si.paths]
static  = "STATIC/"
shapes  = "STATIC/SHAPES.VGA"
palette = "STATIC/PALETTES.FLX"
gamedat = "gamedat/"

[u7si.mods."<mod-name>".paths]
root    = "<User profile>/Exult/serpentisle/mods/<mod-name>"
saves   = "<User profile>/Exult/serpentisle/mods/<mod-name>/saves"
gamedat = "<User profile>/Exult/serpentisle/mods/<mod-name>/gamedat"
archive = "<Serpent Isle install>/SERPENT/mods/<mod-name>/patch/initgame.dat"

[exult.paths]
bg_flx  = "<Exult install>/data/exult_bg.flx"
si_flx  = "<Exult install>/data/exult_si.flx"

[uo.game]
base    = "<Ultima Online Classic Client install>"

Notes:

  • titan setup writes this file for you. Use titan --config <file> setup to write a different config file, including one in a new directory.
  • Rerunning setup keeps existing values and adds missing entries. Before updating an existing file, it saves the original (including comments) as <file>.bak, or <file>.bak.1, etc. if a backup already exists. The updated TOML is reformatted; use titan config --edit to change existing settings.
  • Setup detects both language-folder and flat U8 layouts, and recognizes Roman-numeral U7 folder names such as Ultima VII - Complete.
  • U8 relative paths expand from the configured U8 install and language folder, except shapes and globs, which are local working directories.
  • U7 gamedat should usually point at Exult's initialized runtime copy when available.
  • U7 mod saves is discovered by scanning the mod profile root recursively for .sav files and choosing the folder with the most saves.
  • A fully annotated template is available in titan.toml.example.
  • Full config details are in cli_reference.md#configuration-titantoml.

Inspect the active config:

titan config
titan config --edit

Library Use

TITAN can also be imported as a Python library. U8 modules live under titan.u8; U7 modules live under titan.u7; U6 modules live under titan.u6; early U9 modules live under titan.u9. Backward-compatible imports such as from titan.shape import U8Shape are still supported.

from titan.u7.flex import U7FlexArchive
from titan.u7.palette import U7Palette
from titan.u7.shape import U7Shape

archive = U7FlexArchive.from_file("SHAPES.VGA")
shape = U7Shape.from_data(archive.get_record(150))
palette = U7Palette.from_file("PALETTES.FLX")
shape.to_pngs(palette)[0].save("shape_150_frame0.png")

Supported File Families

Family Ultima 8 Ultima 7 / Exult Ultima Online Classic
Archives *.FLX, speech FLX archives Flex/VGA archives, Exult ZIP/FLEX saves UOP plus MUL/IDX pairs where used by the Classic Client
Shapes and art U8SHAPES.FLX, U8FONTS.FLX, U8GUMPS.FLX SHAPES.VGA, FACES.VGA, GUMPS.VGA, SPRITES.VGA, POINTERS.SHP, generated font shapes art*, gumpart*, texmaps, light, fonts, legacy anim*.mul/idx
Palettes and colors U8PAL.PAL, XFORMPAL.DAT PALETTES.FLX hues.mul, radarcol.mul
Audio SOUND.FLX, MUSIC.FLX, E*.FLX / G*.FLX ADLIBMUS.DAT, MT32MUS.DAT, ENDSCORE.XMI, INTROSND.DAT, U7SPEECH.SPC sound* effects
Maps FIXED.DAT, GLOB.FLX, NONFIXED.DAT, U8SAVE.000 U7MAP, U7CHUNKS, U7IFIX*, SHAPES.VGA, gamedat/u7ireg* Not yet
Type and object data TYPEFLAG.DAT, GUMPAGE.DAT TFA.DAT, SHPDIMS.DAT, WGTVOL.DAT, OCCLUDE.DAT, npc.dat, schedule.dat, flaginit tiledata.mul, animdata.mul, .def, multis
Text ECREDITS.DAT, QUOTES.DAT Selected Exult save/runtime metadata Cliloc.*, speech/skills/system text files

Game Files

TITAN requires the original game files. You must own a legitimate copy of the games. titan setup checks common GOG, EA/Origin, manual, Pentagram, ScummVM, and Exult paths.

Typical GOG, EA/Origin, manual, ScummVM/Pentagram, and Exult folders are auto-detected where possible. If setup cannot find a game, enter the game's base folder manually when prompted.


Documentation


Credits

TITAN uses the following excellent open-source tools:

  • LeRF by Jiacheng Li, Chang Chen, et al. Adaptive downscaling and geometric transforms are powered by LeRF's official LUTs and NumPy implementation.

The font-create wizard ships six TrueType fonts for Ultima script systems. It previews the mapped font, supports redoing font settings, and saves to a separate shape or Exult patch destination. TOML recipes support the same rendering options without prompts; see font-create. See FONTS_CREDITS.md for full attribution and licensing details.

For artwork, titan u7 shape-create guides PNG conversion through the U7 main palette, preview and redo, then saves a shape, a FLX/VGA archive, or both. It supports frame folders, optional comparison PNGs, flats, sparse mod patches, safe slot allocation and repeatable TOML recipes. See shape-create.


License

MIT

TITAN also distributes a modified fold component derived from the Pentagram project as part of dialogue tooling. That component is licensed under GNU GPL v2 or later and is not covered by TITAN's MIT license.

See THIRD_PARTY_NOTICES.md and src/titan/third_party/fold/ for attribution, license scope, source mapping, build entry points, and bundled GPL license text.

Ultima (Copyright 1981-1999, Electronic Arts)

This fan-made tool requires a legitimate copy of the original games: Ultima 8 and Ultima 7. This project is not affiliated with Electronic Arts. All rights to Ultima remain with Electronic Arts.

Metadata

Release files for titan-ultima 0.7.7

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for titan-ultima 0.7.7
File Size Uploaded
titan_ultima-0.7.7.tar.gz 5.3 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for titan-ultima 0.7.7
File Interpreter ABI Platform
titan_ultima-0.7.7-py3-none-any.whl Python 3 none any Details

Total release size: 11.2 MB

Release files / titan_ultima-0.7.7.tar.gz

Download URL titan_ultima-0.7.7.tar.gz
Size 5.3 MB
Tags Source
SHA-256 checksum
How to use checksums
de7ee1a243631df30f409661b522758f9c3a2442ae5c72f7ecfbc9cbf9f0bfe0
BLAKE2b-256 checksum
How to use checksums
317a4dfd97074de560b32655e029f6c414318d3dcc62def3d3f54293e26d372b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

Release files / titan_ultima-0.7.7-py3-none-any.whl

Download URL titan_ultima-0.7.7-py3-none-any.whl
Size 5.8 MB
Tags Python 3
SHA-256 checksum
How to use checksums
1684ce39c4987f373267e450cf892de8fe3f9e3734bc78f1d4944610a139b2b3
BLAKE2b-256 checksum
How to use checksums
ae8879319e7f859f75bb05a4f9422cb414c8a06c0567d3d5a44a076f60d2359c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

Release history Release notifications | RSS feed

0.7.8

2 release files

This release

0.7.7 This release

2 release files

0.7.6

2 release files

0.7.5

2 release files

0.7.4

2 release files

0.7.3

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.9

2 release files

0.6.8

2 release files

0.6.7

2 release files

0.6.6

2 release files

0.6.5

2 release files

0.6.4

2 release files

0.6.3

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.3

2 release files

0.5.2

2 release files

0.4.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page