Skip to main content

Encoding and decoding tools for TaleSpire data

Project description

TaleSpire Encoding

This is a Python package for encoding and decoding TaleSpire data.

It currently supports the following encoding types:

  • Slabs (v1, v2)
  • Creature Blueprints (v1, v2, v3)
  • Stats Links (v1)

It also contains tools for reading in TaleSpire Assets. This requires a path to the installation location of TaleSpire on your machine.

The package published on PyPI is talespire-encoding. The Python import package is ts_encoding.

Installation

Install the latest release from PyPI:

pip install talespire-encoding

To upgrade to the latest version:

pip install --upgrade talespire-encoding

To install a specific version

pip install talespire-encoding==1.2.5

Usage

The Python import package is ts_encoding.

# Core API
from ts_encoding import TSSlab, TSCreature, TSStatsLink, TSAssetLib

Most classes expose a mutable dictionary named data. A common workflow is:

  1. Decode a TaleSpire string or URL into data.
  2. Inspect or edit values in data.
  3. Encode the object back into a string or URL that can be pasted into TaleSpire.

Slabs Example Usage

Slabs are the building data copied from TaleSpire. A slab code is not a normal URL; it is the compressed text string that TaleSpire places on the clipboard.

from ts_encoding import TSSlab

# This is an example slab string copied from TaleSpire.
example_slab_code = ("H4sIAAAAAAAACjv369xFJgZGBgYGgUWHGX9Pme/S4z7T7pZ"
                     "doRonUGwCSIKhgRFMS0L4DTwMDCcYwOIsDBDADOZLQsRB8g"
                     "xQPgOcDwD7jJ0vaAAAAA==")

# Create a slab object, then decode the copied slab string into slab.data.
slab = TSSlab()
slab.decode_slab(example_slab_code)

# The slab contents are now in a dictionary named `slab.data`.
# pprint is a Python helper that prints dictionaries in a more readable format.
from pprint import pprint
pprint(slab.data)

"""
{'layout_count': 1,
 'layouts': [{'instance_count': 9,
              'instances': [{'degrees': 90.0,
                             'pos_x': 0.0,
                             'pos_y': 0.0,
                             'pos_z': 4.0},
                            {'degrees': 0.0,
                             'pos_x': 4.0,
                             'pos_y': 0.0,
                             'pos_z': 4.0},
                            {'degrees': 0.0,
                             'pos_x': 2.0,
                             'pos_y': 0.0,
                             'pos_z': 4.0},
                            {'degrees': 270.0,
                             'pos_x': 0.0,
                             'pos_y': 0.0,
                             'pos_z': 2.0},
                            {'degrees': 180.0,
                             'pos_x': 0.0,
                             'pos_y': 0.0,
                             'pos_z': 0.0},
                            {'degrees': 0.0,
                             'pos_x': 4.0,
                             'pos_y': 0.0,
                             'pos_z': 2.0},
                            {'degrees': 0.0,
                             'pos_x': 2.0,
                             'pos_y': 0.0,
                             'pos_z': 2.0},
                            {'degrees': 0.0,
                             'pos_x': 4.0,
                             'pos_y': 0.0,
                             'pos_z': 0.0},
                            {'degrees': 0.0,
                             'pos_x': 2.0,
                             'pos_y': 0.0,
                             'pos_z': 0.0}],
              'reserved': 0,
              'uuid': '01c3a210-94fb-449f-8c47-993eda3e7126'}],
 'magic_num': 3520002766,
 'num_creatures': 0,
 'version': 2}
"""

# To encode the data again, call encode_slab().
new_slab_code = slab.encode_slab()

# The new_slab_code can be pasted into TaleSpire.

Creating a Slab From Scratch

To create slab data manually, start a new TSSlab and edit the data dictionary. Each UUID is a new layout in the dictionary. It is currently up to you to format the dictionary properly so that it encodes correctly. In future versions there may be tools to help build the layouts.

Here is an example of creating a single grass tile:

from ts_encoding import TSSlab

new_slab = TSSlab()

# This slab contains one layout, meaning one type of asset.
new_slab.data["layout_count"] = 1

grass_layout = {
    "instance_count": 1,  # The number of grass tiles in this layout.
    "instances": [{
        "degrees": 0.0,  # Yaw rotation in degrees, 0-360.
        "pos_x": 0.0,    # X position within the slab.
        "pos_y": 0.0,    # Y position within the slab.
        "pos_z": 0.0     # Z position within the slab.
    }],
    "reserved": 0,  # Always set to 0.
    "uuid": "01c3a210-94fb-449f-8c47-993eda3e7126"  # Asset UUID for Grass - Lush.
}

new_slab.data["layouts"].append(grass_layout)
new_slab_code = new_slab.encode_slab()

# You can paste new_slab_code into TaleSpire to see your grass tile.

encode_slab() checks TaleSpire's 30 kB slab-size limit by default. Pass ignore_limit=True to bypass that check.

Creature Blueprint Example Usage

Creature blueprints are copied as talespire://creature-blueprint/... URLs.

from ts_encoding import TSCreature
from pprint import pprint

url_from_TS = ("talespire://creature-blueprint/"
              "AgAMV2hpdGUgTWVlcGxlAQAAACMAYnI6MDAwMDAwMDAwMDAwMDAwMD"
              "AwMDAwMDAwMDQ3MDQxMDABAAAAAI49u_vNJQRDrZctETEJKR8ABAAA"
              "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgQQAAIEEAACBBAAAgQQ"
              "AAIEEAACBBAAAgQQAAIEEAACBBAAAgQQAAIEEAACBBAAAgQQAAIEEA"
              "ACBBAAAgQQAAIEEAACBBAAAA")

# Decode the TaleSpire URL into bp.data.
bp = TSCreature()
bp.decode_url(url_from_TS)
pprint(bp.data)

# You can change any of the data in `bp.data`.
bp.data["name"] = "New Name"

# The first stat is HP, so this changes the creature's HP to 100/100.
bp.data["stats"][0] = {"max": 100.0, "value": 100.0}

# To re-encode the data, call encode_url().
new_url = bp.encode_url()

print(new_url)  # You can copy/paste this new URL into TaleSpire.

By default, encode_url() preserves the decoded version. You can pass force_encode_version=1 or force_encode_version=2 when you need a specific schema.

Stats Link Example Usage

Stat links are copied as talespire://stat-names/... URLs. They define the custom stat names used by a TaleSpire board.

from ts_encoding import TSStatsLink
from pprint import pprint

# Example from the TaleSpire 5e Creature Blueprint Database.
stats_link_url = "talespire://stat-names/AQAIAkFDBVNwZWVkB1NUUiBNb2QHREVYIE1vZAdDT04gTW9kB0lOVCBNb2QHV0lTIE1vZAdDSEEgTW9k"

# Decode the copied URL into stats.data.
stats = TSStatsLink()
stats.decode_url(stats_link_url)
pprint(stats.data)

# To create a stats link from scratch, start with a new TSStatsLink.
new_stats = TSStatsLink()

# Tell TaleSpire how many stat names are in this link.
new_stats.data["num_stats"] = 8

# These are the names that will appear in TaleSpire.
new_stats.data["names"] = [
    "AC", "CMD", "STR", "DEX", "CON", "INT", "WIS", "CHA"
]

new_url = new_stats.encode_url()

print(new_url)  # You can copy/paste this URL into TaleSpire to import your stats.

Use None in names for a null stat name.

Asset Library Example Usage

TSAssetLib reads TaleSpire asset metadata from a local TaleSpire installation. The supplied path should be the base TaleSpire install directory that contains the Taleweaver folder.

from ts_encoding import TSAssetLib

# Change this path to match where TaleSpire is installed on your computer.
talespire_path = r"C:\Program Files (x86)\Steam\steamapps\common\TaleSpire"

# Load all supported asset types: Tiles, Props, Creatures, and Music.
library = TSAssetLib(talespire_path)

# Look up an asset by UUID.
grass = library.asset("01c3a210-94fb-449f-8c47-993eda3e7126")
print(grass.name)
print(grass.asset_type)

# Get a list of every asset that was loaded.
all_assets = library.assets()

You can limit the loaded asset types:

library = TSAssetLib(talespire_path, asset_filter=["Tiles", "Props"])

Valid asset types are Tiles, Props, Creatures, and Music.

Exceptions

The public exception classes are available from ts_encoding:

from ts_encoding import (
    BadSlabCode,
    InvalidAssetType,
    InvalidTaleSpireDirectory,
    SlabExceedsSizeLimit,
    UnsupportedSlabVersion,
)

All package-specific exceptions inherit from TSEncodingException.

Development

Install the project locally with test dependencies:

python -m pip install -e .[dev]

Run the test suite:

python -m pytest

Asset-library tests need a local TaleSpire installation. They look for common Steam install paths and also respect the TALESPIRE_PATH environment variable. When TaleSpire is not found, those tests are skipped.

More development notes are in CONTRIBUTING.md.

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

talespire_encoding-1.3.0.tar.gz (21.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

talespire_encoding-1.3.0-py3-none-any.whl (18.6 kB view details)

Uploaded Python 3

File details

Details for the file talespire_encoding-1.3.0.tar.gz.

File metadata

  • Download URL: talespire_encoding-1.3.0.tar.gz
  • Upload date:
  • Size: 21.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for talespire_encoding-1.3.0.tar.gz
Algorithm Hash digest
SHA256 c2ddda46535758d339faa8196b6f1de3bf6923a19a5daed900b20035bcd98bcd
MD5 d7ebcb2cef07e3b0ae5c07ac67ae8781
BLAKE2b-256 a2b1f99414d01ebdcacf13961171a9f18b7bab0771c3f1c376398f3830d73c4d

See more details on using hashes here.

Provenance

The following attestation bundles were made for talespire_encoding-1.3.0.tar.gz:

Publisher: python-publish.yml on Baldrax/TaleSpire-Encoding-Python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file talespire_encoding-1.3.0-py3-none-any.whl.

File metadata

File hashes

Hashes for talespire_encoding-1.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1569b4bfa9f47561c6976547151171463fe08b0f837f803e9b4f389112782b59
MD5 302bce7b3f8db4c82c56268f8352b6fb
BLAKE2b-256 4a67d8d7b044ffef7a402ed75a25e1da79618c48499d4a280071318c9e2803d0

See more details on using hashes here.

Provenance

The following attestation bundles were made for talespire_encoding-1.3.0-py3-none-any.whl:

Publisher: python-publish.yml on Baldrax/TaleSpire-Encoding-Python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page