Skip to main content

Python toolkit for generating StratoScript files for Nightshade planetarium systems

Project description

pytshade

Python toolkit for generating StratoScript (.sts) files for Digitalis planetarium systems running Nightshade.

pytshade lets you write planetarium shows in Python! Constellations, eclipses, meteor showers, planet tours, etc. and compile them into the linear StratoScript format that Nightshade executes on the dome.

Features

  • Builder pattern - chain method calls, then build() or save() to emit a .sts file.
  • Shadow-state tracking - skips redundant flag/timerate/zoom commands automatically.
  • Version compatibility - targets Nightshade NG (OP3) or Nightshade Legacy (11.12.1) with a single version= switch.
  • Astronomy helpers - PyEphem wrapper for visibility checks, moon phases, eclipse lookups, and sun position calculations.
  • Deterministic resets - every script starts from a known state via init_block() / reset_to_default().
  • Long-pan waypoints - automatically splits camera pans > 170° on NG to work around SLERP shortest-path behavior.
  • Meteor radiant database - built-in RA/Dec for Perseids, Geminids, Leonids, Quadrantids, and Orionids.

Quick Start

# Clone and install with uv
git clone https://github.com/sidereumcorpus/pytshade.git
cd pytshade
uv sync --group dev

If you want the optional astronomy examples as well:

uv sync --group dev --extra examples
import datetime
from pytshade import StratoScriptBuilder

builder = StratoScriptBuilder("location.json")
builder.init_block()

builder.set_date(datetime.datetime.now().replace(hour=21))
builder.flag("atmosphere", False)
builder.constellations(show=True, art=True)
builder.wait(10)
builder.constellations(show=False)
builder.flag("atmosphere", True)

builder.save("my_show.sts")

Copy the .sts file to D:\Nightshade\data\scripts\ and run it from the Nightshade script menu.

uv Workflow

# Install dependencies
uv sync --group dev

# Run tests
uv run python -m unittest discover -s tests -v

# Run the demo generator
uv run python generate_demo_script.py

# Build distributions
uv build

Project Structure

pytshade/
  __init__.py          # Public API: StratoScriptBuilder, AstroHelper, NightshadeVersion
  builder.py           # Public builder import path
  astronomy.py         # Public astronomy import path
  version.py           # Public version import path
digitalis_scripts/
  ...                  # Backward-compatible internal implementation package
examples/
  quickstart.py        # Minimal 30-second constellation demo
  ephem_moon_phases.py # Moon-phase calendar using AstroHelper
  astropy_planet_tour.py  # Planet visibility tour using astropy
  legacy_mode.py       # Targeting Nightshade Legacy syntax
tests/
  test_builder.py      # Builder unit tests (63 tests)
  test_astronomy.py    # AstroHelper unit tests
  test_version.py      # Version profile tests
generate_demo_script.py  # Full 7-scene demo show generator
location.json            # Observer location config

Nightshade Version Targeting

pytshade defaults to Nightshade NG syntax. To generate scripts for Legacy 11.12.1:

from pytshade import StratoScriptBuilder, NightshadeVersion

builder = StratoScriptBuilder("location.json", version=NightshadeVersion.LEGACY)
Feature NG Legacy
Meteors meteors ra/dec + meteors zhr meteors rate
Video video action play external_viewer action play
Movement SLERP shortest path (auto-split > 170°) Linear interpolation

Using with Other Astronomy Libraries

PyEphem (built-in)

from pytshade import AstroHelper

astro = AstroHelper(lat="36.53", lon="-87.35", elevation=155)
moon_time = astro.find_good_moon_time(min_phase=0.5)
phase = astro.get_moon_phase(moon_time)

Astropy (optional)

See examples/astropy_planet_tour.py for a full working example that uses astropy.coordinates.get_body() to check planet altitudes and only visits those above the horizon.

uv sync --group dev --extra examples
uv run python examples/astropy_planet_tour.py

Skyfield / Other Libraries

pytshade's builder is library-agnostic. Compute positions with any library, then feed the results into the builder:

# Pseudocode - works with skyfield, poliastro, etc.
alt_deg, az_deg = my_library.get_planet_position("Mars", time)
if alt_deg > 0:
    builder.select_planet("Mars")
    builder.flag("track_object", True)
    builder.zoom(fov=10, duration=2)

Running Tests

uv run python -m unittest discover -s tests -v

Generating the Demo Show

uv run python generate_demo_script.py

This produces 7 individual .sts scripts plus a combined full show, copies them to the Nightshade scripts directory, and mirrors them in generated_scripts/ for version control.

Key Concepts

State Reset

Every standalone script should call builder.init_block() at the start. This runs clear + reset_to_default() which:

  1. Drops all media (images, video, audio)
  2. Deselects objects and stops tracking
  3. Returns to Earth at your location.json coordinates
  4. Resets all flags to sensible defaults
  5. Resets view direction, FOV, time, and timerate

Gotchas

  • track_object persists - always disable it when done tracking.
  • timerate persists - reset to timerate(1) at scene end.
  • Meteor showers need FOV 180 - meteors spawn at FOV edges; zooming in means they never enter view. Use ZHR 10000+ for visual density.
  • Solar System Observer - disable atmosphere and landscape before switching to "Solar System Observer".
  • Long pans on NG - pans > 170° are automatically split by pan_to(), but if you use set_view() directly you must handle this yourself.

Requirements

  • Python 3.10+
  • uv
  • PyEphem 4.x
  • Astropy (optional, for advanced ephemeris examples)

Publishing

Build locally with:

uv build

Check the artifacts before release:

uv run python -m twine check dist/*

The repo also includes GitHub Actions workflows for:

Before the first real publish, configure PyPI trusted publishing for your repository.

GitHub Upload

The project can be connected to GitHub with:

git add .
git commit -m "Initial pytshade release"
git remote add origin https://github.com/sidereumcorpus/pytshade.git
git push -u origin main

Compatibility Note

The new public import path is pytshade:

from pytshade import StratoScriptBuilder

The older digitalis_scripts imports still work for now so existing scripts do not break immediately.

License

GNU General Public License v3.0 only (GPL-3.0-only). See LICENSE.

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

pytshade-0.1.0.tar.gz (34.8 kB view details)

Uploaded Source

Built Distribution

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

pytshade-0.1.0-py3-none-any.whl (30.0 kB view details)

Uploaded Python 3

File details

Details for the file pytshade-0.1.0.tar.gz.

File metadata

  • Download URL: pytshade-0.1.0.tar.gz
  • Upload date:
  • Size: 34.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pytshade-0.1.0.tar.gz
Algorithm Hash digest
SHA256 9ce425ae8b68f639335d432e163c6010b6b48be945b802f245a128cf0409c93a
MD5 5223676a0298ce483c546ae1e8298a0a
BLAKE2b-256 c81d80f9b11e352d2d42d370d7a072d8927c97a621274c44b658c31defb2cb8f

See more details on using hashes here.

File details

Details for the file pytshade-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: pytshade-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 30.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pytshade-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d446a5e099f1414206e5d610cc833863d0b3ab62e6cc3d41db6b999762745394
MD5 8dd90035e9c0898893d04feac7d34db4
BLAKE2b-256 c2354c1fcced755fa6ea5fd3ad45f525c8c2937585b5b6e742f3348806425e23

See more details on using hashes here.

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