1 Getting Started
dxtr edited this page 2026-10-18 21:50:46 +02:00

Getting Started

What Pyssel needs

  • SBCL, the only Lisp Pyssel runs on.
  • Vulkan 1.4: a GPU's driver, or Mesa's lavapipe (mesa-vulkan-drivers on Debian), which needs no GPU and draws offscreen engines as well as windows.
  • Wayland or Windows for windows: libwayland-client0 and libxkbcommon0 on Linux. An offscreen engine needs neither.
  • FreeType, HarfBuzz and ICU for text: libfreetype6, libharfbuzz0b and libicu-dev.
  • stift, the workspace's package manager, which fetches the libraries Pyssel is built from at the commits its stiftfile pins.

In Pyssel's checkout, stift exec sbcl starts SBCL with those libraries found, and (asdf:load-system :pyssel) loads the core.

The systems

Pyssel's parts are ASDF systems named pyssel/..., each loading what it needs:

System What it holds
pyssel The core: engines, popups and dialogs, render targets, sessions and live pipelines.
pyssel/2d The 2D renderer and its painters.
pyssel/resource Resources and their files.
pyssel/font Fonts as resources.
pyssel/scene The scene tree, input and actions, and saved scenes.
pyssel/scene-2d The scene tree's 2D nodes, and run, which starts an engine running a scene.
pyssel/ui The user interface's controls, containers and themes.
pyssel/project Projects and their settings.
pyssel/play Games played in your Lisp.
pyssel/editor The editor, its project manager and histories of edits.
pyssel/program The pyssel program, which stift build writes as bin/pyssel.
pyssel/export The player image exported games will start from, with pyssel/player, its toplevel.

A first program

The core draws with live pipelines of shaders written in Lisp:

(asdf:load-system :pyssel)

(defpackage #:triangle
  (:use #:cl #:clsl)
  (:local-nicknames (#:gfx #:cl-gfx)))
(in-package #:triangle)

(define-shader triangle-vertex :vertex ((position :vec2) (color :vec3))
  (values (vec4 position 0 1) color))

(define-shader triangle-fragment :fragment ((color :vec3))
  (vec4 color 1))

(define-program triangle
  "A triangle in its vertices' colours."
  :vertex triangle-vertex :fragment triangle-fragment)

(defvar *pipeline*)
(defvar *vertices*)

(defun setup (engine)
  (setf *pipeline* (pyssel:make-pipeline engine 'triangle)
        *vertices* (gfx:create-buffer (pyssel:engine-device engine)
                                      :size 60 :usage '(:vertex)))
  (gfx:write-buffer *vertices*
                    (make-array 15 :element-type 'single-float
                                   :initial-contents '( 0.0 -0.5  1.0 0.0 0.0
                                                       -0.5  0.5  0.0 1.0 0.0
                                                        0.5  0.5  0.0 0.0 1.0))))

(defun draw (engine pass)
  (declare (ignore engine))
  (pyssel:use-pipeline pass *pipeline*)
  (gfx:set-vertex-buffer pass 0 *vertices*)
  (gfx:draw pass 3))

(defvar *engine* (pyssel:start :title "Triangle" :setup 'setup :draw 'draw))

A window opens with a triangle in it, and the REPL stays free. Redefine the fragment shader there:

(define-shader triangle-fragment :fragment ((color :vec3))
  (vec4 (- 1 color) 1))

The next frame draws the triangle in the inverted colours. Redefine draw and the next frame calls the new one. Close the window, or call (pyssel:stop *engine*), to stop.

The REPL's way in

The triangle keeps its pipeline and its vertices in variables, as it has no node to keep them in. A game keeps its state in its nodes and resources, which the editor shows and saves, and each run of it its own: a game played in the editor's image shares the image's global variables with the editor and with every play after it (see Sessions). The examples of this manual keep one variable each for what they start, as *engine* above, an engine's scene tree as *tree* or a play as *play*: the REPL's way in to what runs, to reach it from there, as with call-in-tree.

Running the tests

stift test

The tests run engines offscreen on a Vulkan driver, such as Mesa's lavapipe, and, where Wayland is, in a window on headless Weston (weston). They draw text in DejaVu Sans (fonts-dejavu-core); to use it from another location, set PYSSEL_TEST_FONT to its path. Two runs of the suite at once would share the test game and the player image they build in ~/.cache/pyssel/, so run one at a time.