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
Entityand implementupdate(self, dt: float). - Use
self.position(aVector) to move in world space. - Each entity owns a
Sprite(self.sprite) that is rendered by theCamera.
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
\tin the raw art to mark the sprite center (the tab is removed). - Transparency: the engine treats the bell character
\aas transparent (that cell is skipped during rendering).
Camera (spaceship.render.camera.Camera / CameraMode)
The camera transforms world positions into screen positions. Available modes:
CameraMode.CENTERCameraMode.TOP_LEFT,CameraMode.TOP_RIGHTCameraMode.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"), orgame.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_MARGINCELL_WIDTH: terminal columns per cellCHAR_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)
| File | Size | Uploaded | |
|---|---|---|---|
| spaceship_engine-1.0.4.tar.gz | 15.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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 logRelease 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