Skip to main content
Gale

Python3 Pygame2 License PyPI GithubCommits BlackFormatBadge CIBadge

Gale (Game Architecture & Logic Engine) is a modular Python toolkit for building 2D games faster with Pygame.

  • Solves: the parts every Pygame project ends up reinventing – a real game loop, input handling, state machines, AI, physics, networking, UI, save files – so you write your game, not its plumbing.

  • For: Python developers building 2D games (or teaching/learning game programming) who want Pygame’s directness without starting from a blank file every time.

  • Different because: every piece is an independent, opt-in module – import only what a given game needs, on top of plain Pygame, never a replacement for it.

Full documentation: https://r3mmurd.github.io/Gale/

Installation

pip install gale-engine

The package is published on PyPI as gale-engine (gale and several close variants were already taken), but import gale stays exactly the same either way.

To track main directly instead of the latest release:

pip install https://github.com/R3mmurd/Gale/archive/main.zip

Quick start

import pygame

from gale.game import Game
from gale.input_handler import InputHandler, KEY_ESCAPE

InputHandler.set_keyboard_action(KEY_ESCAPE, "quit")


class MyGame(Game):
    def init(self) -> None:
        self.x = 0

    def update(self, dt: float) -> None:
        self.x = (self.x + 150 * dt) % self.virtual_width

    def render(self, surface: pygame.Surface) -> None:
        pygame.draw.circle(surface, "white", (int(self.x), 100), 20)

    def on_input(self, input_id, input_data) -> None:
        if input_id == "quit" and input_data.pressed:
            self.quit()


MyGame(title="Quick Start").exec()

Save that as main.py and run it: a window opens with a white circle sliding across the screen, closes on Escape. Game already gives you the window, the virtual-resolution scaling, and the update/render loop – gale-admin create-project (see Project template) scaffolds this same layout plus a settings.py for a real project.

Why Gale?

  • Modular, not all-or-nothing. gale.ai, gale.net, gale.physics, gale.ui, and every other submodule are independent – a Pong clone only needs gale.net/gale.ui, a platformer only needs gale.physics/gale.tilemap. Nothing is forced on you for using one piece.

  • Batteries-included where it matters. A game loop with fixed/variable timestep, Django-style overridable settings (gale.conf), input handling (keyboard, mouse, gamepad, local co-op), and a save system with schema migrations (gale.save) – the plumbing every project needs, solved once.

  • A real AI toolkit, not a token one. gale.ai covers steering behaviors, behavior/decision trees, A*/HPA*, fuzzy logic, GOAP, Markov chains, tactical influence maps, and minimax – most of a standard “AI for games” curriculum, ready to compose.

  • Physics without the pymunk/Chipmunk2D API leaking through. gale.physics wraps pymunk for real 2D physics (bodies, joints, collisions) behind gale’s own, much smaller API – you never import pymunk directly.

  • Multiplayer building blocks that actually work over the internet. gale.net is a hand-rolled reliable UDP layer with client-side prediction/server reconciliation, entity interpolation, LAN discovery, and shareable room codes – pure Python, no external networking dependency.

  • Tested. 670+ tests, black-formatted, CI across Python 3.9-3.13 on every pull request.

Use cases

  • 2D platformer – examples/leap (all three gale.physics body types) or examples/planks (a Tiled map, one-way platforms, no physics engine at all).

  • Top-down adventure – examples/wayfarer: an intro cutscene, free-roam quests, a victory cutscene.

  • Tactical/AI-heavy game – examples/skirmish: formations, fuzzy logic, GOAP, an influence map, gravity-aware targeting, all driving one squad-tactics demo.

  • Networked multiplayer – examples/rally: an online Pong playable over LAN or the internet.

Examples

Short, focused snippets, one per module:

  • Project template (gale-admin): scaffolds a new project’s directory structure.

  • gale.animation

  • gale.camera: following, zoom, bounds, screen shake.

  • gale.command: Command pattern, bound to input_handler through CommandBindings/CommandControlled.

  • gale.event: decoupled publish/subscribe — Signal, EventEmitter, and a global EventBus.

  • gale.factory

  • gale.frames

  • gale.input_handler: includes keyboard key combos and gamepads.

  • gale.log: console/file defaults, adding Graylog, Sentry, Discord, or any other destination.

  • gale.memoize: Memoized and Memo, a game-time-driven cache (forever, per-frame, or TTL) auto-updated by Game alongside Timer.

  • gale.net: Server/Client, channel choice, RTT, LAN discovery, room codes.

  • gale.particle_system

  • gale.physics: bodies, shapes, joints, collision callbacks, and the scene graph, with pymunk never exposed directly.

  • gale.state

  • gale.stencil: mask an arbitrary shape out of a surface, love2d-stencil style.

  • gale.text

  • gale.tilemap: layers, tilesets, loading a Tiled JSON map, one-way platform collision.

  • gale.timer

  • gale.ui: menus, HUDs, and forms built from panels, buttons, list views, text inputs, closable windows, and more.

  • gale.ai: steering behaviors (and their combination/motor-control variants), behavior tree, decision tree, data-driven scripting, Blackboard, graphs/search/pathfinding, the Agent class, fuzzy logic, learning models, targeting, formations, Markov chains, GOAP, rules, and tactical influence maps.

  • gale.ecs: World, components, queries, and Systems/SystemScheduler.

  • gale.sequence: Step, StepGroup, and Sequence, the shared engine behind quests and cutscenes.

  • gale.quest: Objective, Stage, Quest, and QuestLog.

  • gale.cutscene: Cutscene and its beats — images, “video”, actor movement, dialogue.

  • gale.save: SaveManager, slots, metadata, schema versioning/migrations, pluggable serialization.

For full running games built with gale, see examples/space_trip and, in particular for gale.ai, examples/nightwatch, a small stealth demo whose guards patrol, chase, and coordinate through a shared behavior tree, blackboard, and pathfinding, and examples/skirmish, a small squad-tactics demo covering the rest of the toolkit: a formation of allies following an anchor, guards whose alertness is driven by fuzzy logic and whose decisions come from a data-driven behavior tree, a Markov state machine varying their patrol routine, an influence map guiding where they take up position, GOAP planning for an objective-driven captain, and gravity-aware projectile targeting; for gale.net/gale.ui, examples/rally, a small online Pong playable over a LAN or the internet; for gale.physics, examples/leap, a platformer using all three body types, and examples/hillclimb, a small vehicle-physics demo built on motorized wheel joints; for gale.camera, examples/scavenger, a coin-collecting game with a scrolling/zooming camera; and, for gale.stencil, examples/lantern, a top-down exploration game where the room is only revealed in a circle around the player; and, for gale.tilemap, examples/planks, a platformer loading a level made in Tiled, with one-way platforms and a scrolling camera.

Three more full games showcase the isometric tilemap, perception, HFSM, minimax, networked prediction/interpolation, and ECS additions: examples/outpost, a small isometric stealth prototype where patrolling guards spot the player through a vision cone and a hierarchical state machine, and a terminal minigame is defended by a minimax AI; examples/circuit, a small online racing prototype with client-side prediction/server reconciliation, entity interpolation, lag compensation, and an AI racer following the track with A*/steering; and examples/futsal, a small futsal match simulation where each team’s behavior tree/Blackboard-driven roles decide intent that a gale.ecs World/SystemScheduler simulates in bulk (movement, fatigue, ball/player collisions).

examples/wayfarer showcases the gale.sequence/gale.quest/gale.cutscene additions: a small top-down adventure where an intro cutscene (a character walking to a mark, pose changes, input-advanced dialogue) hands off into free-roam play, collecting herbs, defeating a wolf, and reporting back to an NPC progress a two-stage QuestLog-tracked quest, completing it triggers a victory cutscene.

Each example under examples/ is a standalone project (its own settings.py and src/), so it doesn’t see the copy of gale inside this repository unless it’s actually installed. From the repository root, run pip install -e . once, then cd into the example’s directory and run python main.py from there.

What Gale includes

  • gale.ai: Contains a modular toolkit to build autonomous characters: the Kinematic body and a full set of steering behaviors (seek/flee/arrive/align/pursue/evade/wander/wall & obstacle & collision avoidance/path following) plus combination (blending, priority, cooperative arbitration) and motor-control (output filtering, capability limits) variants; a behavior tree, a decision tree, and data-driven scripting to build either from a plain dict; a shared Blackboard; generic graphs with search algorithms — flat, hierarchical, interruptible/time-sliced, and open-goal; the Agent class that ties them together; a vision-cone Perception system; fuzzy logic; naive-Bayes/n-gram learning models; projectile aiming/targeting (including under drag); coordinated-movement formations; Markov chains/state machines; goal-oriented action planning (GOAP); a forward-chaining rule engine; tactical influence maps; and minimax search with alpha-beta pruning for turn-based adversarial decisions. (example)

  • gale.animation: Contains the class Animation. (example)

  • gale.camera: Contains the class Camera, a 2D scrolling/zooming camera — following a target, screen shake, bounds clamping, and screen/world coordinate conversion. (example)

  • gale.command: Contains Command, a stateless, reusable Command-pattern action (and its __call__ alias, so it can also be used directly as a gale.ai callable), CommandBindings (maps an input_handler action id to a press/release pair of commands), and CommandControlled, an InputListener mixin that dispatches on_input through a CommandBindings. (example)

  • gale.conf: Contains settings, a lazily-loaded, overridable settings object. It reads your project’s own settings.py first, falling back to gale.conf.global_settings (the same defaults gale.game.Game used to hardcode directly) for anything you don’t override, and lets you define your own extra settings the same way. (example)

  • gale.cutscene: Contains Cutscene (a gale.sequence.Sequence of beats that also ticks/renders any actors involved every frame) and its beats — ShowImage, PlayAnimation (a dependency-free stand-in for video playback), MoveActor, SetActorAnimation, Dialogue, Wait — each lasting a fixed duration or advancing on a specific input. (example)

  • gale.ease_functions: Contains the 30 standard easing functions (linear, sine/quad/cubic/quart/quint/expo/circ/back/elastic/bounce, each with an in/out/in_out variant) used by gale.timer.Tween, plus an EASE_FUNCTIONS dict looking them up by name.

  • gale.ecs: Contains a Data-Oriented Design (ECS) toolkit — a World storing entities (plain integer ids) and components (plain Python objects), queried by System/SystemScheduler to process them in bulk every frame. (example)

  • gale.event: Contains a decoupled publish/subscribe toolkit — Signal (a single event channel: connect/disconnect/emit, priority-ordered, with a once option), EventEmitter (a mixin/composable object owning any number of ad hoc, string-named Signals), and EventBus (a ready-to-use global EventEmitter, classmethods over a single instance, the same shape InputHandler uses). Every emit isolates each listener’s exceptions (logged through gale.log, never propagated), so one broken subscriber never breaks another. (example)

  • gale.factory: Contains the classes Factory and Abstract Factory. (example)

  • gale.frames: Contains a util function to generate rectangle frames from a sprite sheet. (example)

  • gale.game: Contains a base class Game to be inherited to ease your game building — a variable-rate update/render pair driven by real elapsed time, plus a fixed_update that steps at a constant rate regardless of frame rate, for anything that needs to be frame-rate-independent (e.g. driving a gale.physics.World). Every constructor argument (title, window/virtual size, fps, …) defaults to whatever gale.conf.settings resolves it to when omitted.

  • gale.input_handler: Contains key definitions, mouse button definitions, mouse wheel input definitions, mouse move input definitions, gamepad button/axis definitions (local multiplayer included), classes to store the information about an input, an interface to listen the input handler and the class InputHandler. (example)

  • gale.log: Contains logging configuration for gale games — printed to the terminal and written to a plain-text file by default, extensible to Graylog, Sentry, a Discord channel, or anywhere else by attaching another logging.Handler. (example)

  • gale.management: Contains gale-admin, the create-project/create-state command-line tool that scaffolds a new game’s main.py/settings.py/src/ layout, or a new BaseState subclass inside one. (example)

  • gale.memoize: Contains Memoized (wraps a function, caching its return value per distinct argument combination) and Memo (a process-wide registry of every Memoized created through Memo.memoize, aged by Memo.update(dt) the same way Timer ages Every/After/Tween — gale.game.Game calls both automatically). ttl is measured in seconds of game time, not the wall clock: None caches forever, 0 caches for the rest of the current frame, and a positive number expires the entry after that much accumulated dt — so, unlike functools.lru_cache, an entry decorating an instance method doesn’t pin that instance in memory forever. (example)

  • gale.math_util: Contains real_equal, a tolerance-based float equality check used by gale.ease_functions to detect t=0/t=1 exactly despite floating-point drift.

  • gale.net: Contains a pure-Python, pygame-free toolkit for LAN/internet multiplayer: Server, Client, a hand-rolled reliability layer over UDP, per-peer round-trip-time tracking, LAN discovery, configurable-format room codes (encode/decode) for sharing a host/port pair as a short, human-typeable string, a PredictionBuffer for client-side prediction/server reconciliation, and a SnapshotInterpolator/lag_compensated_position for entity interpolation and lag compensation. (example)

  • gale.particle_system: Contains classes to handle particle systems in your game. (example)

  • gale.physics: Contains a pymunk-backed 2D physics toolkit — World, Body, body types, shapes, joints — that never exposes pymunk itself, plus a lightweight scene graph (Node) for organizing physics entities. (example)

  • gale.quest: Contains a customizable-per-game quest system built on gale.sequence — Objective, Stage (a group of objectives), Quest (a sequence of stages), and QuestLog (tracks/starts every quest and broadcasts progress events to whichever are active). (example)

  • gale.save: Contains SaveManager, a general-purpose save-game system — persists whatever JSON-serializable dict a game gives it into named slots on disk, with per-slot metadata for a save-select screen, a pluggable serializer/deserializer for the wire format, and a schema version/migrations mapping for evolving what a save contains across releases without breaking old saves. (example)

  • gale.sequence: Contains Step, StepGroup, and Sequence — the generic “do this until it’s done, then do the next thing” engine shared by gale.quest and gale.cutscene; a step completes after a fixed duration, on a specific input, or by a subclass’s own condition. (example)

  • gale.state: Contains the class BaseState, a basic class StateMachine, a basic class StateStack, and HierarchicalState for nesting a sub-StateMachine inside a state (HFSM). (example)

  • gale.stencil: Contains the class Stencil, a CPU-side equivalent of love.graphics.stencil to mask an arbitrary shape (a circle, a polygon, a sprite) out of a surface’s alpha channel — handy for a top-down game’s fog-of-war/vision reveal, a circular minimap crop, and similar effects. (example)

  • gale.text: Contains a util function to ease text rendering and a class Text. (example)

  • gale.tilemap: Contains TileMap/Tileset (grid-of-tiles rendering with gale.camera culling built in), IsometricTileMap (the same kind of map rendered in a diamond/isometric projection, plus the standalone cartesian_to_isometric/isometric_to_cartesian transforms, reusable for isometric coordinate math outside of tile maps too), load_tiled_map (loads a map exported as JSON from Tiled, tilesets/object layers included), and an optional move_and_collide platformer collision helper (solid walls, one-way platforms) that never depends on gale.physics. (example)

  • gale.timer: Contains classes to handle timers that execute action every x seconds, after x seconds, and tweening. (example)

  • gale.ui: Contains a widget toolkit for menus, HUDs, and forms — panels, labels, buttons, progress bars, checkboxes, list views, containers, text boxes (click/Enter-paginated, or button-paginated through PaginatedTextBox), text inputs, cursors, and closable Window\ s, styled through a shared theme. (example)

Development

To work on this library, install the development dependencies, which include the runtime dependencies plus pytest and pre-commit:

pip install -r requirements/dev.txt

Then install the git hook so that black and the test suite run automatically before every commit:

pre-commit install

You can also run both checks manually at any time:

black .
pytest

Git workflow

main and develop are protected: nobody (including admins) can push to them directly, so every change has to go through a pull request.

  • New work branches off develop and is merged back into develop through a pull request.

  • Releases are cut by opening a pull request from develop into main. See PACKAGING.md for the full release/publishing process — publishing a GitHub Release automatically pushes the new version to PyPI.

Every pull request (and every push to a branch with an open pull request) triggers the CI workflow defined in .github/workflows/ci.yml, which installs the dependencies (including pytest, since GitHub-hosted runners don’t ship it) and runs:

  • black --check --diff . to enforce the code style.

  • pytest to run the whole test suite.

Both checks are required status checks on main and develop: a pull request cannot be merged until they pass.

Contributors

https://contrib.rocks/image?repo=R3mmurd/Gale

Dependencies

Gale is obviously strongly dependent on Python and Pygame. It also depends on Click for the gale-admin command line tool, NumPy for gale.particle_system, and pymunk for gale.physics.

Changelog

See CHANGELOG.md for the history of notable changes across releases.

License

This library is distributed under the MIT License, which can be found in the file LICENSE. We reserve the right to place future versions of this library under a different license.

See docs/licenses for licenses of dependencies.

Metadata

Release files for gale-engine 1.17.1

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

Source distribution (sdist)

Source distribution for gale-engine 1.17.1
File Size Uploaded
gale_engine-1.17.1.tar.gz 226.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for gale-engine 1.17.1
File Interpreter ABI Platform
gale_engine-1.17.1-py3-none-any.whl Python 3 none any Details

Total release size: 429.6 kB

Release files / gale_engine-1.17.1.tar.gz

Download URL gale_engine-1.17.1.tar.gz
Size 226.7 kB
Tags Source
SHA-256 checksum
How to use checksums
bcb762fc5781668dc040c473fb191d1053fd1d916422c840307e16eeb1f6aaa4
BLAKE2b-256 checksum
How to use checksums
5b399727449f82612398ebda908c7d3c8afd634caac63e8f04fa20c1a09f33fa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 17, 2026.

Transparency log

Release files / gale_engine-1.17.1-py3-none-any.whl

Download URL gale_engine-1.17.1-py3-none-any.whl
Size 202.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
93415cce18b8e2be3cc386e8d832225ec15c942bd476da687d9a60b61221d8f0
BLAKE2b-256 checksum
How to use checksums
7650e761f8d591ea8108b49e06aaed8a73070065f8ea7f8627a3614f43416576
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 17, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.17.1 This release

2 release files

1.17.0

2 release files

1.16.0

2 release files

1.15.0

2 release files

1.14.3

2 release files

1.14.2

2 release files

1.14.1

2 release files

1.14.0

2 release files

1.13.0

2 release files

1.12.1

2 release files

1.12.0

2 release files

1.11.0

2 release files

1.10.0

2 release files

1.9.2

2 release files

1.9.1

2 release files

1.9.0

2 release files

1.8.0

2 release files

1.7.0

2 release files

1.6.2

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