A 1:1 Python conversion of the C# Ultima SDK
Project description
A comprehensive 1:1 Python conversion of the C# Ultima Online SDK. This library provides full read access to Ultima Online client data files (.mul, .idx, and UOP formats) for use in tools, servers, and modding pipelines.
Features
- Full access to UO client data files: Art, Animations, Gumps, TileData, Hues, Map, and more
- Support for both legacy
.mul/.idxand modern.uopfile formats - Built-in PNG rendering helpers via Pillow
- Automatic client directory discovery on Windows (registry lookup)
- Manifest-based override support for custom client data
- Typed API with type hints throughout
- Comprehensive test suite including mocked and real-client smoke tests
Installation
From PyPI (coming soon)
pip install ultima-sdk-python
From Source
git clone https://github.com/UltimaWorks/ultima-sdk-python.git
cd ultima-sdk-python
pip install -e .
Requirements
- Python 3.10+
- Pillow 10.0+
- An Ultima Online client installation (for reading
.mul,.idx, and.uopfiles)
Quick Start
from ultima_sdk import Files, TileData, Art, Animations, Hues
# Initialize file paths (auto-detects UO client on Windows)
Files.initialize() # or: Files.initialize("C:\\Ultima Online")
# Load tile data
TileData.initialize()
land_tile = TileData.get_land_tile(0) # Get grass tile
static_tile = TileData.get_static_tile(3388) # Get a static item
# Load hues
Hues.initialize()
hue_0 = Hues.get_hue(0) # Default hue
# Load art
Art.initialize()
art = Art.get_art(0x4001) # Load art by graphic ID
if art:
img = art.to_image() # Convert to PIL Image
img.save("output.png")
# Load animations
Animations.initialize()
anim = Animations.get_animation(body=1, action=0, direction=0)
Module Reference
Files
The Files class manages all UO client data file paths and discovery.
from ultima_sdk import Files
# Auto-detect client directory (Windows registry)
Files.initialize()
# Or specify manually
Files.initialize("/path/to/ultima_online")
# Check if a file exists
if Files.file_exists("artidx.mul"):
print("Art index found!")
# Get absolute path to a file
art_path = Files.get_file_path("artidx.mul")
TileData
Reads tiledata.mul for land and static tile definitions.
from ultima_sdk import TileData
TileData.initialize()
# Land tiles (ground textures)
land = TileData.get_land_tile(0) # Grass
print(land.name, land.flags)
# Static tiles (items, walls, furniture)
static = TileData.get_static_tile(3388) # Wooden chest
print(static.name, static.height)
Hues
Reads hues.mul for color/shader data.
from ultima_sdk import Hues
Hues.initialize()
hue = Hues.get_hue(1) # Red hue
print(hue.name) # "Crimson"
Art
Reads artidx.mul / art.mul for static item graphics.
from ultima_sdk import Art
Art.initialize()
art = Art.get_art(0x4001) # Load by graphic ID
if art:
img = art.to_image() # Returns PIL.Image
img.save("item.png")
Animations
Reads anim.idx / anim.mul and variant files for character/object animations.
from ultima_sdk import Animations
Animations.initialize()
# Get a single frame
frame = Animations.get_animation(body=1, action=0, direction=0)
# Export as GIF
Animations.export_gif(1, 5, "character.gif")
Gumps
Reads gumpidx.mul / gumpart.mul for UI element graphics.
from ultima_sdk import Gumps
Gumps.initialize()
gump = Gumps.get_gump(gump_id=0x829)
if gump:
img = gump.to_image()
Map
Reads map data including statics, map markers, and multi-object placements.
from ultima_sdk import Map
Map.initialize()
# Get statics at a location
statics = Map.get_statics(0, 1396, 819) # Britain
for s in statics:
print(s.item_id, s.x, s.y, s.z)
Skills
Reads skills.def for skill definitions.
from ultima_sdk import Skills
Skills.initialize()
for skill_id in range(150):
skill = Skills.get_skill(skill_id)
if skill:
print(f"{skill.name}: gainrate={skill.gain_rate}")
Rendering
All art, animation, and gump objects have a .to_image() method that returns a PIL.Image.
from ultima_sdk import Art
Art.initialize()
art = Art.get_art(0x4051)
img = art.to_image()
img.save("output.png")
File Structure
ultima-sdk-python/
├── pyproject.toml
├── README.md
├── LICENSE
├── .github/workflows/ # CI/CD pipelines
├── examples/ # Usage examples for each module
├── scripts/ # Utility scripts
├── tests/ # Test suite
└── ultima_sdk/
├── __init__.py # Package entry point
├── files.py # File path management
├── tiledata.py # TileData.mul reader
├── hues.py # Hues.mul reader
├── art.py # Art graphics reader
├── animations.py # Animation reader
├── gumps.py # Gump graphics reader
├── map.py # Map data reader
├── skills.py # Skills.def reader
├── multis.py # Multi-object data
├── textures.py # Texture reader
├── sound.py # Sound/music reader
├── uop.py # UOP file format support
├── verdata.py # Version data (patching)
├── rendering.py # PIL image helpers
└── ... # Other utility modules
Examples
The examples/ directory contains runnable scripts for every major module:
| File | Description |
|---|---|
art_example.py |
Load and save art tiles as PNG |
animations_gif_example.py |
Export animations to GIF |
map_example.py |
Query static objects on a map |
rendering_example.py |
Render art/animations to images |
uop_example.py |
Work with UOP-format data files |
verdata_example.py |
Apply patch data from verdata |
| ... | See examples/ for all 30+ examples |
Tests
# Run all tests
pytest -v
# Run with coverage
pytest --cov=ultima_sdk --cov-report=term
# Run a specific test module
pytest tests/test_art.py -v
Platform Support
| Platform | Support | Notes |
|---|---|---|
| Windows | Full | Auto-detection via registry |
| Linux | Supported | Manual path configuration |
| macOS | Supported | Manual path configuration |
License
Written under the Pickleware License. See LICENSE for full terms.
Contributing
Contributions are welcome! See CONTRIBUTING.md for setup instructions, code standards, and the PR workflow.
Related Projects
- UOFiddler — Original C# Ultima SDK this project converts from
- ServUO — Popular Ultima Online server implementation
- JSmith.UoSdk — .NET SDK for UO client data
Support
For issues, questions, or feature requests, please open an issue on the GitHub Issues page. ]]>
Project details
Release history Release notifications | RSS feed
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 ultima_sdk_python-1.1.3.tar.gz.
File metadata
- Download URL: ultima_sdk_python-1.1.3.tar.gz
- Upload date:
- Size: 72.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b0882aa254f7a601fc714f77876353beb90af9848b192301d34c938d643fc869
|
|
| MD5 |
9d7302e50031b3f9c218e0b564027935
|
|
| BLAKE2b-256 |
b9dcd70704a9c5123313a55c94581893171f921c1bc96bbc0766446a42d330a8
|
Provenance
The following attestation bundles were made for ultima_sdk_python-1.1.3.tar.gz:
Publisher:
workflow.yml on UltimaWorks/ultima-sdk-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ultima_sdk_python-1.1.3.tar.gz -
Subject digest:
b0882aa254f7a601fc714f77876353beb90af9848b192301d34c938d643fc869 - Sigstore transparency entry: 1428858194
- Sigstore integration time:
-
Permalink:
UltimaWorks/ultima-sdk-python@a0fbe46d3a90dd7c7ca6f8458c75f4acfe2c3bc2 -
Branch / Tag:
refs/tags/v1.1.3 - Owner: https://github.com/UltimaWorks
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@a0fbe46d3a90dd7c7ca6f8458c75f4acfe2c3bc2 -
Trigger Event:
release
-
Statement type:
File details
Details for the file ultima_sdk_python-1.1.3-py3-none-any.whl.
File metadata
- Download URL: ultima_sdk_python-1.1.3-py3-none-any.whl
- Upload date:
- Size: 68.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ead5174a75c776e205064d5a5b439ab4f0c0eaebe3b17ba92bd2b335a5d91fed
|
|
| MD5 |
1e352e70b7fe04b85cddabc4a2174806
|
|
| BLAKE2b-256 |
15ddb526f93080a56cf9e00c9b0d1c188aca65916cb28600ba26fe5dee3cae2d
|
Provenance
The following attestation bundles were made for ultima_sdk_python-1.1.3-py3-none-any.whl:
Publisher:
workflow.yml on UltimaWorks/ultima-sdk-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ultima_sdk_python-1.1.3-py3-none-any.whl -
Subject digest:
ead5174a75c776e205064d5a5b439ab4f0c0eaebe3b17ba92bd2b335a5d91fed - Sigstore transparency entry: 1428858206
- Sigstore integration time:
-
Permalink:
UltimaWorks/ultima-sdk-python@a0fbe46d3a90dd7c7ca6f8458c75f4acfe2c3bc2 -
Branch / Tag:
refs/tags/v1.1.3 - Owner: https://github.com/UltimaWorks
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@a0fbe46d3a90dd7c7ca6f8458c75f4acfe2c3bc2 -
Trigger Event:
release
-
Statement type: