The Keel command-line interface gives you three subcommands for your entire development workflow:Documentation Index
Fetch the complete documentation index at: https://mintlify.com/VKSFY/keel/llms.txt
Use this file to discover all available pages before exploring further.
keel new to scaffold a fresh project in seconds, keel run to start a file-watching dev loop that restarts your game on every .py save, and keel build (a stub for v1) as a placeholder for future packaging support. The CLI is installed automatically as part of keelpy — no extra install step needed.
keel new
keel new <project_name> creates a complete project directory structure and populates it with starter files. The directory name is the project name.
Generated file tree
main.py
A working entry point that creates an
App, calls setup_renderer_2d and setup_assets, registers stub update and render systems, and calls app.run().pyproject.toml
A minimal PEP 517 build descriptor with
keelpy as a dependency and a [project.scripts] entry pointing at main:app.run.assets/
Watched by the asset hot-reload system (
setup_assets). Drop textures (PNG, JPG, BMP, TGA) and JSON data files here.scenes/
Conventional home for
Scene.save JSON output. Not watched automatically — reference it explicitly in save/load calls.Scaffolded main.py
Error: directory already exists
If the target directory exists, the command prints an error to stderr and exits with code1. It never overwrites an existing project.
keel run
keel run [entry] starts your entry script in a subprocess and restarts it automatically whenever any .py file in the project directory changes. The default entry point is main.py.
.py file is saved:
Ctrl+C to exit the dev loop:
How the watcher works
Start subprocess
Launches the entry script as
python <entry> using the same Python interpreter that is running keel run. The process starts immediately.Watch for .py changes
A
watchdog Observer monitors the project directory recursively. It reacts to on_modified, on_created, and on_moved events and enqueues the changed path when the file ends in .py.Debounce burst saves
After the first change is queued, the loop sleeps for 50 ms and drains any additional events that arrived during that window. Multiple rapid saves (editor auto-save flushes, formatting passes) are coalesced into one single reload.
Restart
Terminates the old process (SIGTERM → 3-second wait → SIGKILL), then spawns a fresh subprocess from the entry script. No state is preserved between restarts.
Process termination sequence
keel run tries to terminate it, the step is a no-op.
Entry file not found
If the entry script does not exist, the command prints an error and exits with code1 without starting a subprocess or observer:
What triggers a reload
| Event type | Triggers reload? |
|---|---|
.py file saved (modified) | ✅ Yes |
.py file created | ✅ Yes |
.py file renamed / moved | ✅ Yes (uses destination path) |
Any non-.py file change | ❌ No |
| Directory events | ❌ No |
keel build
keel build is a stub for v1. It prints a hint and exits cleanly with code 0.
Packaging support is on the roadmap. For now, distribute your project as a Python package and have users run it with
python main.py or the script entry point defined in pyproject.toml. The [project.scripts] section generated by keel new already provides a named command when the package is installed with pip install -e ..Quick-start workflow
.py file and save — the game restarts within 50 ms. Press F1 for the world inspector, F2 for the profiler, and F3 for the physics debug draw (if keel.dev_tools(app) is called in your main.py).