Chickadee
*********

Copyright © 2017-2023  David Thompson dthompson2@worcester.edu

     Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled ``GNU Free Documentation License''.

     A copy of the license is also available from the Free Software Foundation Web site at http://www.gnu.org/licenses/fdl.html.

The document was typeset with GNU Texinfo (http://www.texinfo.org/).

Installation
************

Chickadee is available for download from its website at https://dthompson.us/projects/chickadee.html.  This section describes the software requirements of Chickadee, as well as how to install it.

Requirements
============

Chickadee depends on the following packages:

  * GNU Guile (https://gnu.org/software/guile), version 3.0.0 or later;

  * GNU guile-opengl (https://gnu.org/software/guile-opengl), version 0.1 or later.

  * guile-sdl2 (https://dthompson.us/pages/software/guile-sdl2.html), version 0.7.0 or later;

  * libfreetype

  * libmpg123

  * libopenal

  * libreadline

  * libvorbisfile

If you are using Guix, then this getting all the dependencies is easy: Just run guix shell from the root of the Chickadee Git repository or unpacked release tarball.

Building
========

If you are building from a Git checkout rather than an official release tarball, the first step is to bootstrap the build system:

     ./bootstrap.sh

Release tarballs have a pre-bootstrapped build system and do not require the above step.

Now, build Chickadee:

     ./configure
     make

If you'd like to install Chickadee onto your system, run:

     sudo make install

The GNU build system defaults to /usr/local as the installation prefix.  This can be changed by re-running the configure script:

     ./configure --prefix=/some/where/else
     sudo make install

Getting Started
***************

One of the simplest programs we can make with Chickadee is rendering the text ``Hello, world'' on screen.  Here's what that looks like:

     (define (draw alpha)
       (draw-text "Hello, world!" (vec2 64.0 240.0)))

The draw procedure is called frequently to draw the game scene. For the sake of simplicity, we will ignore the alpha variable in this tutorial.

To run this program, we'll use the chickadee play command:

     chickadee play hello.scm

This is a good start, but it's boring.  Let's make the text move!

     (define position (vec2 0.0 240.0))

     (define (draw alpha)
       (draw-text "Hello, world!" position))

     (define (update dt)
       (set-vec2-x! position (+ (vec2-x position) (* 100.0 dt))))

The vec2 type is used to store 2D coordinates (see Vectors.)  A variable named position contains the position where the text should be rendered.  A new hook called update has been added to handle the animation.  This hook is called frequently to update the state of the game.  The variable dt (short for ``delta-time'') contains the amount of time that has passed since the last update, in seconds.  Putting it all together, this update procedure is incrementing the x coordinate of the position by 100 pixels per second.

This is neat, but after a few seconds the text moves off the screen completely, never to be seen again.  It would be better if the text bounced back and forth against the sides of the window.

     (define position (vec2 0.0 240.0))

     (define (draw alpha)
       (draw-text "Hello, world!" position))

     (define (update dt)
       (update-agenda dt))

     (define (update-x x)
       (set-vec2-x! position x))

     (let ((start 0.0)
           (end 536.0)
           (duration 4.0))
       (script
        (while #t
         (tween duration start end update-x)
         (tween duration end start update-x))))

This final example uses Chickadee's scripting features (see Scripting) to bounce the text between the edges of the window indefinitely using the handy tween procedure.  The only thing the update procedure needs to do now is advance the clock of the ``agenda'' (the thing that runs scripts.)  The script takes care of the rest.

This quick tutorial has hopefully given you a taste of what you can do with Chickadee.  The rest of this manual gets into all of the details that were glossed over, and much more.  Try rendering a sprite, playing a sound effect, or handling keyboard input.  But most importantly: Have fun!

Command Line Interface
**********************

While Chickadee is a library at heart, it also comes with a command line utility to make it easier to get started.

Invoking chickadee play
=======================

The chickadee play command is used to open a window and run the Chickadee game contained within a Scheme source file.

     chickadee play the-legend-of-emacs.scm

In this file, special procedures may be defined to handle various events from the game loop:

  * quit-game

  * draw

  * update

  * key-press

  * key-release

  * text-input

  * mouse-press

  * mouse-release

  * mouse-move

  * mouse-wheel

  * controller-add

  * controller-remove

  * controller-press

  * controller-release

  * controller-move

See The Game Loop for complete information on all of these hooks, such as the arguments that each procedure receives.

In additional to evaluating the specified source file, the directory containing that file is added to Guile's load path so that games can easily be divided into many different files.  Furthermore, that directory is entered prior to evaluating the file so that data files (images, sounds, etc.) can be loaded relative to the main source file, regardless of what the current directory was when chickadee play was invoked.

Many aspects of the initial game window and environment can be controlled via the following options:

--title=TITLE
-t TITLE

     Set the window title to TITLE.

--width=WIDTH
-w WIDTH

     Set the window width to WIDTH pixels.

--height=HEIGHT
-h HEIGHT

     Set the window height to HEIGHT pixels.

--fullscreen
-f

     Open window in fullscreen mode.

--resizable
-r

     Make window resizable.

--update-hz=N
-u N

     Update the game N times per second.

--clear-color=COLOR
-c COLOR

     Set the screen clear color to COLOR, a hex code in the format #RRGGBB.  For example, to set the clear color to black, pass --clear-color=#000000.

--repl

     Launch a REPL in the terminal.  This will allow the game environment to be debugged and modified without having to stop and restart the game after each change.

--repl-server[=PORT]

     Launch a REPL server on port PORT, or 37146 by default.

     telnet localhost 37146 (or whatever port number was given) will do the trick, but using the Geiser (https://www.nongnu.org/geiser/) extension for Emacs is by far the best way to develop at the REPL with Guile.  Use M-x connect-to-guile to connect to the REPL server.

     Note that the REPL server defaults to the (guile-user) module, so you will first need to switch to the (chickadee-user) module like so:

          scheme@(guile-user)> ,module (chickadee-user)
          scheme@(chickadee-user)>

--language=LANGUAGE

     Process the input program using LANGUAGE, the identifier of a language within Guile's language tower.  By default, unsurprisingly, Scheme is used.

     For example, to use the neat Wisp (https://www.draketo.de/software/wisp) language as an alternative to Scheme's parenthetical syntax, pass --language=wisp.  Wisp is not included with Guile and must be installed separately.

-x EXTENSION

     Add EXTENSION to the list of file extensions that Guile will load.

     For example, Wisp files canonically use the .w extension. Here's what a ``hello, world'' Chickadee program looks like in Wisp:

          define : draw alpha
            draw-text "Hello, world!" : vec2 260.0 240.0

     Assuming the above code is saved to a hello.w file, chickadee play be invoked as follows:

          chickadee play --language=wisp -x .w hello.w

Invoking chickadee bundle
=========================

Distributing games is difficult.  While Chickadee games are free software, it would be far too burdensome on the player to ask them to compile a game from source in order to try it out.  Many potential players will simply not even try.  Players expect to be able to download a compressed archive, extract it, and play.  If there are any more steps than that then the chances of the game being played drop dramatically.  If you can't beat 'em, join 'em.  The chickadee bundle tool creates redistributable binary bundles by combining the game code and assets with shared libraries and executables from the host operating system.

Bundling is currently only supported on Linux.  In the future, it may be possible to bundle on MacOS.  Patches very much welcome for that.

It should be noted that bundling is a problematic way to distribute software.  All of the libraries that the bundled application includes are separated from the distribution that was so carefully making sure that they stay up-to-date with regard to security patches.  The bundled libraries are frozen in time, vulnerabilities and all. Unfortunately, the release model used by the most popular distributions, while wonderful for stable, mature software, does not fit the needs of game distribution at all.  So, we compromise, knowing that most games are only played for only a short amount of time before being disposed.  Perhaps, in time, the Linux world will shift to using more robust package management solutions such as GNU Guix (https://guix.gnu.org) which support long-term maintenance of stable software as well as the ``fire and forget'' nature of game releases.  And maybe a game made with Chickadee will become so popular that major distributions decide to package it, but let's get back to reality.

To get started with bundling, simply add a bundle.scm file to the root of the project directory.  It could look something like this:

     '((asset-directories . ("images" "models"))
       (bundle-name . "the-legend-of-emacs-1.0")
       (code . "the-legend-of-emacs.scm")
       (launcher-name . "the-legend-of-emacs"))

To create the bundle, simply run chickadee bundle.  Upon success, the file the-legend-of-emacs-1.0.tar.gz would be created in the current directory.

To maximize the chances that the bundle will work on someone else's computer, it's best to build on the oldest supported Linux distribution available.  As of this writing, Ubuntu 18.04 LTS is a good choice.

In addition to including system libraries and executables, chickadee bundle also includes the compiled Guile bytecode (the .go files) for all modules used by the game.  The module source files are not included, so it's critical that all of the modules used by the game have been compiled.

Available options:

  * asset-directories

     A list of directories that hold static game assets such as images or audio.  Files in these directories will be copied into the bundle archive.

  * binary-directories

     A list of directories to search for system binaries, such as guile.  By default, /usr/bin is searched.

  * bundle-name

     The name of the bundle archive.  By default, the name is "chickadee-bundle".

  * launcher-name

     The name of the launcher script.  By default, the name is "launch-game".

  * libraries

     A list of shared libraries to include in the bundle.  By default, all of the libraries necessary for running Guile, Guile-SDL2, and Chickadee are included.  This list is compatible with the names given to the libraries on Ubuntu, which may be different than on other distributions.  In such cases, this list will need to be customized. See below for more information on the %default-config variable that can be of help.

  * library-directories

     A list of directories to search for system shared libraries.  By default, the list contains common directories used by most distributions.

  * method

     The method by which the game is launched.  Can be either play or manual.  The default is play, which means that chickadee play will be used to launch the game.  For games that do not use chickadee play, opting to start the game loop on their own, the manual method should be used.

  * play-args

     A list of command line arguments to pass to chickadee play. Only used when the method option is set to play.

Default configuration options, such as the list of C shared libaries, can be found in the %default-config variable.  This way they can be programatically modified, if necessary.

 -- Variable: %default-config
     An association list of default configuration options.

Live Coding
***********

One of the biggest appeals of any Lisp dialect is the ability to use the ``read-eval-print loop'' (REPL for short) to build programs iteratively and interactively while the program is running.  However, programs that run in an event loop and respond to user input (such as a game using the Chickadee library!) require special care for this workflow to be pleasant.

If you are using the chickadee play command to run your game, then the --repl or --repl-server arguments are all you need to get a live coding environment running.

If, however, you are using run-game to start the game loop then it's still fairly easy to hook up a special kind of REPL by yourself.

First, create a cooperative REPL server (It's important to use Guile's cooperative REPL server instead of the standard REPL server in (system repl server) to avoid thread synchronization issues). Then, in the game loop's update procedure, call poll-coop-repl-server and pass the REPL object.  Here is a template to follow:

     (use-modules (chickadee)
                  (system repl coop-server))

     (define repl (spawn-coop-repl-server))

     (define (update dt)
       (poll-coop-repl-server repl)
       ...)

     (run-game #:update update ...)

To use the REPL, connect to it via port 37146.  Telnet will do the trick, but using the Geiser (https://www.nongnu.org/geiser/) extension for Emacs is by far the best way to develop at the REPL with Guile.  Use M-x connect-to-guile to connect to the REPL server.

API Reference
*************

     [file api.texi not included]

Copying This Manual
*******************

Apache 2.0 License
==================

     [file apache-2.0.texi not included]