Tzopilotl
Docs
GitHub

Tzopilotl — Getting Started

Installing the distribution, setting up your environment, and configuring projects.

1. Installing

Tzopilotl ships as a disk image, Tzopilotl-<version>.dmg. Open it and drag the Tzopilotl folder anywhere you like — /Applications, your home directory, a projects drive. There is no installer and nothing is written outside the folder.

The folder is self-contained and relocatable: the app and the command-line tool find the standard library and examples relative to their own location. The one rule is to keep the folder together — don't move Tzopilotl.app out on its own, or it will no longer find its sibling modules/ directory.

1.1 What's in the folder

Tzopilotl/
  Tzopilotl.app      the app: editor, notebooks, REPL, audio engine
  bin/tzpl           command-line interpreter and REPL (language only)
  modules/           the standard library (std.*, music.*, ugens, ...)
  examples/          runnable demos -- open one in the app
  docs/              this guide and the reference documentation
  editors/           syntax packages for VS Code, TextMate, tree-sitter
  README.txt

Your own work never lives inside this folder (see §5); files opened from examples/ open as unsaved copies, so the originals stay pristine.

1.2 First launch & Gatekeeper

Official releases are signed and notarized, so macOS opens them without complaint. If you are running a build that isn't (for example one you built from source without a signing identity), macOS will refuse the first double-click: right-click Tzopilotl.app and choose Open once, and it runs normally from then on.

1.3 Requirements

1.4 Updating

Replace the whole Tzopilotl/ folder with the new version. Nothing of yours is stored inside it, so this is always safe. Never update pieces of it individually — the app, bin/tzpl, and modules/ are matched to each other.

Don't edit the stdlib in place. Anything you change inside the distribution's modules/ is lost on the next update. To customize a standard module, copy it into your project's modules/ (or a $TZPL_PATH directory) — those are searched first and shadow the stdlib version (§4.1).

2. First Sounds

Launch Tzopilotl.app and pick File > Open Example…. A good first stop is example_synthdefs.x (a corpus of synths with a playExamples() tour) or ui_synth_controls.x (a synth whose control surface materializes as live widgets).

Evaluation is cursor-driven, like other live-coding environments:

ShortcutAction
Cmd+Enterevaluate the selection, or the block under the cursor
Shift+Enterevaluate the current line
Cmd+Shift+Enterevaluate the whole file (in a notebook: run all cells)
Cmd+Kclear the console

Results and prints land in the console pane. For the notebook document format, widgets, and the full shortcut table, see Live Controls & Notebooks in this docs folder.

3. The Command Line

3.1 bin/tzpl

bin/tzpl is the Tzopilotl interpreter on its own: run it with no arguments for a REPL, or pass a .x file to execute it. Arguments after the filename are passed to the script (readable via the programArgs() builtin).

$ tzpl                 # interactive REPL
$ tzpl script.x        # run a script
$ tzpl -I ~/mylibs script.x   # add module search paths

Useful flags: -I <path> adds module search paths (colon-separated), --rt enables real-time-safety enforcement, and -h lists the rest.

Language only. bin/tzpl has no audio engine: it is for scripts, libraries, and learning the language. Modules that talk to the engine (audioEngine, synthdef compilation to a running graph, music.play, the ui widgets) only work inside the app.

To call tzpl from anywhere, add the distribution's bin to your PATH in ~/.zshrc (adjust the path to wherever you put the folder):

export PATH="/Applications/Tzopilotl/bin:$PATH"

Symlinking bin/tzpl into a directory already on your PATH also works — the symlink is resolved before the interpreter looks for its standard library, so it still finds the distribution.

3.2 The app, headless

The app binary itself is scriptable. Launching it from a terminal on a file both opens that file and applies its project's configuration (§5.3):

$ /Applications/Tzopilotl/Tzopilotl.app/Contents/MacOS/Tzopilotl ~/music/mypiece/main.x

With --nogui it runs the same engine without a window, and with --nrt <out.wav> it renders a script offline to a WAV file instead of opening an audio device:

$ .../MacOS/Tzopilotl --nrt out.wav --duration 30 piece.x

All engine settings (§5.2) have matching command-line flags (--sample-rate, --device, --silos, …) that override the project config; run with --help for the full list.

4. Environment Variables

No environment variables are required. The distribution is self-locating; the two below exist for customizing where modules come from. Set them in ~/.zshrc for terminal use. (The Finder-launched app does not read your shell profile, but it doesn't need to — it finds everything relative to itself.)

VariableMeaning
TZPL_PATHColon-separated list of extra module directories, searched before the standard library. Use it for personal libraries you want available in every script: export TZPL_PATH="$HOME/tzpl-libs"
TZPL_HOMEExplicit path to a distribution root (a folder containing modules/). Overrides the executable-relative discovery. Rarely needed — only when you want a binary to use a stdlib other than the one it shipped with, e.g. pointing a dev build at an installed distribution or vice versa.

Each import is resolved by searching, in order:

  1. the directory of the importing file
  2. -I paths from the command line
  3. the project's modules/ directory (§5.4)
  4. $TZPL_PATH directories
  5. the standard library: $TZPL_HOME/modules if set, otherwise the distribution's modules/ found relative to the executable
  6. the distribution's examples/ (so examples can import each other, and your scripts can import instrument_synthdefs.*)

Earlier entries win, so a file with the same module name in your project shadows the stdlib version. This is the supported way to customize standard modules — copy, then edit the copy.

5. Projects & Configuration

A project is any folder containing a file named tzpl-config. That file is the marker and the engine configuration; the folder may also contain a modules/ directory for project-local modules, plus your .x sources and .tzd notebooks laid out however you like.

File > New Project… creates one for you: a folder with a commented-out tzpl-config template, an empty modules/ directory, and a starter main.tzd notebook. File > Open Recent Project reopens a project at its last document.

When you open any file inside a project (the app walks up from the file to the nearest ancestor folder with a tzpl-config), the project is recognized: its modules/ joins the import path and its engine settings are applied at launch.

5.1 The tzpl-config file

Plain text, one key = value per line; -- starts a comment; string values may be quoted. Unknown keys are reported, not fatal. Every key is optional — an empty file is a valid project marker that changes no settings.

-- Tzopilotl project config
sampleRate = 44100
bufferFrames = 256
device = "MacBook Pro Speakers"
inputChannels = 2

5.2 Configuration keys

KeyDefaultMeaning
device"default"Audio output device, by name (as shown in Audio MIDI Setup). "default" follows the system output.
inputDevicesame as outputAudio input device, by name.
sampleRate48000Sample rate in Hz.
bufferFrames512Audio buffer size in frames. Lower is less latency, higher is more headroom.
channels2Number of output channels.
firstChannel0First output channel on the device (for multichannel interfaces).
inputChannels0Number of input channels. 0 disables audio input.
firstInputChannel0First input channel on the device.
silos4Number of parallel audio processing units (silos). Each runs its own graph and scheduler.
tempoClocks1Number of tempo-clock slots per silo.
oscPort0 (off)UDP port for the OSC server, in builds with OSC support.
natsUrloffNATS server URL (e.g. "nats://127.0.0.1:4222"), in builds with NATS support.
engineNamenoneEngine name for namespaced NATS subjects when several engines share a server.

5.3 When settings apply

Engine settings are read once, at app startup, from the project of the file the app is launched on. They cannot change while the engine is running, so:

Finder launches. Currently, when a double-clicked document starts the app, macOS delivers the file only after the engine is already up, so the project's engine settings are not applied — module paths are. To launch with a project's engine settings, start the app from the terminal on a file in the project (§3.2).

5.4 Project modules

Any .x file in the project's modules/ directory is importable by name from anywhere in the project. Because project modules are searched before the standard library, this is also where a copied-and-customized stdlib module goes. File > Reveal Modules Folder shows the distribution's own modules/ when you want to read (or copy) the originals.

6. Editor Support

The editors/ folder ships syntax highlighting for external editors:

7. Where to Go Next

DocumentWhat it covers
Tzopilotl by ExampleThe language, syntax-first: types, functions, auto-mapping, pattern matching, modules.
Tzopilotl Music CookbookTask-oriented recipes for making sound and music — the best second stop after this guide.
Live Controls & NotebooksThe ui widget module and notebook documents in the app.
Builtin FunctionsReference for every built-in function.
CoroutinesCoroutines, scheduling, and time.
FFI GuideThe foreign-function interface, including the audio engine FFI.

8. Troubleshooting

“Tzopilotl.app can't be opened” / “unverified developer”

An unsigned (source-built) copy: right-click the app and choose Open once. See §1.2.

Synthdef compilation fails with a compiler error

Install the Xcode Command Line Tools: xcode-select --install. Synth definitions are compiled to native code with the system C++ compiler.

An import isn't found, or the wrong version loads

Walk the search order in §4.1 — the first match wins. Check for a same-named file earlier in the chain (project modules/, a $TZPL_PATH directory) shadowing the one you expect, and check echo $TZPL_PATH for stale entries.

Audio imports fail in bin/tzpl

Expected: the command-line interpreter has no audio engine (§3.1). Use the app, or its headless mode (§3.2).

No sound

Check that the device in your project's tzpl-config names an existing output (or leave it at "default"), and remember engine settings apply at launch (§5.3). The console reports the device and sample rate the engine actually opened.

The app can't find the standard library

Tzopilotl.app or bin/tzpl was separated from the distribution folder. Put it back next to modules/, or set TZPL_HOME to a distribution root (§4).