Skip to main content

Spaceship Engine

Spaceship Engine is a small Python engine for real-time ASCII/terminal games. It provides a fixed-timestep game loop, entity + sprite rendering with z-order, a basic HUD system, and keyboard input via pynput.

Install

From a checkout of this repo:

python -m pip install -e .

Or, if published to PyPI:

python -m pip install spaceship-engine

Requires Python 3.8+.

Quick start

Create a game, add an entity, and run:

from spaceship.game import Game
from spaceship.render.entity import Entity
from spaceship.utils.math import Vector


class Player(Entity):
    def __init__(self, game: Game):
        super().__init__(game, Vector(0, 0))
        self.sprite.load(
            " O \n"
            "/|\\\n"
            "/ \\",
            priority=10,
        )

    def update(self, dt: float):
        speed = 30
        if self.game.input.is_char_held("w"):
            self.position += Vector(0, -speed) * dt
        if self.game.input.is_char_held("s"):
            self.position += Vector(0, speed) * dt
        if self.game.input.is_char_held("a"):
            self.position += Vector(-speed, 0) * dt
        if self.game.input.is_char_held("d"):
            self.position += Vector(speed, 0) * dt
        if self.game.input.is_char_held("q"):
            raise SystemExit(0)


def init():
    game.add_entity(Player(game))


def update(dt: float):
    pass


game = Game(init_hook=init, update_hook=update, border=True)
game.run()

Core concepts

Game loop (spaceship.game.Game)

  • Fixed-timestep updates at 60 Hz (fixed_dt = 1/60), with a cap to avoid runaway catch-up after long stalls.
  • Rendering runs as fast as possible and uses a terminal diff to redraw only changed cells.
  • Add/remove world objects with game.add_entity(entity) / entity.kill().

Entities (spaceship.render.entity.Entity)

  • Subclass Entity and implement update(self, dt: float).
  • Use self.position (a Vector) to move in world space.
  • Each entity owns a Sprite (self.sprite) that is rendered by the Camera.

Sprites (spaceship.render.sprite.Sprite)

  • Load ASCII art via sprite.load(raw_string, priority=1).
  • Z-order: sprite.priority (higher numbers render on top).
  • Center marker: include exactly one \t in the raw art to mark the sprite center (the tab is removed).
  • Transparency: the engine treats the bell character \a as transparent (that cell is skipped during rendering).

Camera (spaceship.render.camera.Camera / CameraMode)

The camera transforms world positions into screen positions. Available modes:

  • CameraMode.CENTER
  • CameraMode.TOP_LEFT, CameraMode.TOP_RIGHT
  • CameraMode.BOT_LEFT, CameraMode.BOT_RIGHT

HUD (spaceship.render.hud.HUD, HUDElement, HUDAlignment)

HUD elements are templated strings with backtick-delimited placeholders:

from spaceship.render.hud import HUDElement, HUDAlignment

score_hud = HUDElement(
    template="Score: `score`",
    values={"score": "0"},
    align=HUDAlignment.RIGHT,
)
game.hud.add_bottom_hud(score_hud)

# Later:
score_hud.set_value("score", "123")

Top HUD height is computed automatically based on alignment groups; bottom HUD renders one line per element.

Input (spaceship.input.input.Input)

  • Check held keys: game.input.is_char_held("w"), or game.input.is_key_held(key) for special keys.
  • Register callbacks: hook_to_keypress(fn) / hook_to_keyrelease(fn) (and unhook variants).

Configure the playfield

The grid size and margins live in spaceship.utils.constants:

  • SIZE_X, SIZE_Y: logical grid dimensions (characters)
  • LEFT_MARGIN, RIGHT_MARGIN, TOP_MARGIN
  • CELL_WIDTH: terminal columns per cell
  • CHAR_ASPECT: used by camera Y scaling

There is also spaceship.utils.constants.configure(...), but note that many engine modules import these constants at import time. For best results, set constants before importing/constructing the engine (or edit constants.py in a fork).

Run the demo

After pip install -e .:

python -m spaceship.demo.demo

Controls: WASD to move the rock, Q to quit.

Notes / limitations

  • Keyboard input uses pynput, which may require accessibility permissions (macOS) or an active desktop session (some Linux setups).
  • ANSI escape codes are used for rendering; use a modern terminal (Windows Terminal, iTerm2, etc.).

Metadata

Release files for spaceship-engine 1.0.4

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

Source distribution (sdist)

Source distribution for spaceship-engine 1.0.4
File Size Uploaded
spaceship_engine-1.0.4.tar.gz 15.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for spaceship-engine 1.0.4
File Interpreter ABI Platform
spaceship_engine-1.0.4-py3-none-any.whl Python 3 none any Details

Total release size: 31.7 kB

Release files / spaceship_engine-1.0.4.tar.gz

Download URL spaceship_engine-1.0.4.tar.gz
Size 15.2 kB
Tags Source
SHA-256 checksum
How to use checksums
0ff7b34649fd22b2f4d7ca1965beb3d059718c62c17a791cdf7651625b1d91f8
BLAKE2b-256 checksum
How to use checksums
7d3745f01f40aa8da59fa58ddf30c1833c5870595da501737610db09c04f702f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Feb 6, 2026.

Transparency log

Release files / spaceship_engine-1.0.4-py3-none-any.whl

Download URL spaceship_engine-1.0.4-py3-none-any.whl
Size 16.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3ac35ac92683dc6396ac0f7c2cbfb8063f178444c7087add5843e30e8042e8d8
BLAKE2b-256 checksum
How to use checksums
5237286023af9a432013816f0da46512b1efda6e36deb1df200a3338d913e554
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Feb 6, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.4 This release

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.0

2 release files

0.2.0

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.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