\input texinfo @c -*-texinfo-*- @c %**start of header @setfilename chickadee.info @settitle The Chickadee Game Toolkit @c %**end of header @copying Copyright @copyright{} 2017-2023 David Thompson @email{dthompson2@@worcester.edu} @quotation 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 @url{http://www.gnu.org/licenses/fdl.html}. @end quotation @dircategory The Algorithmic Language Scheme @direntry * Chickadee: (chickadee). Game programming toolkit for Guile. @end direntry The document was typeset with @uref{http://www.texinfo.org/, GNU Texinfo}. @end copying @titlepage @title Chickadee 0.1 @subtitle Using the Chickadee game toolkit @author David Thompson @page @vskip 0pt plus 1filll @insertcopying @end titlepage @c Output the table of the contents at the beginning. @contents @ifnottex @node Top @top Chickadee @insertcopying @end ifnottex @c Generate the nodes for this menu with `C-c C-u C-m'. @menu * Installation:: Installing Chickadee. * Getting Started:: Writing your first Chickadee program. * Command Line Interface:: Run Chickadee programs from the terminal. * Live Coding:: Tips for building games from the REPL. * API Reference:: Chickadee API reference. * Copying This Manual:: * Index:: @end menu @c Update all node entries with `C-c C-u C-n'. @c Insert new nodes with `C-c C-c n'. @node Installation @chapter Installation Chickadee is available for download from its website at @url{dthompson.us/projects/chickadee.html}. This section describes the software requirements of Chickadee, as well as how to install it. The build procedure for Chickadee is the same as for GNU software packages, and is not covered here. Please see the files @file{README} and @file{INSTALL} for additional details. @menu * Requirements:: Software needed to build and run Chickadee. @end menu @node Requirements @section Requirements Chickadee depends on the following packages: @itemize @item @url{https://gnu.org/software/guile, GNU Guile}, version 3.0.0 or later; @item @url{https://gnu.org/software/guile-opengl, GNU guile-opengl}, version 0.1 or later. @item @url{https://dthompson.us/pages/software/guile-sdl2.html, guile-sdl2}, version 0.7.0 or later; @item libfreetype @item libmpg123 @item libopenal @item libreadline @item libvorbisfile @end itemize @node Getting Started @chapter 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: @lisp (define (draw alpha) (draw-text "Hello, world!" (vec2 64.0 240.0))) @end lisp The @code{draw} procedure is called frequently to draw the game scene. For the sake of simplicity, we will ignore the @code{alpha} variable in this tutorial. To run this program, we'll use the @command{chickadee play} command: @example chickadee play hello.scm @end example This is a good start, but it's boring. Let's make the text move! @lisp (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)))) @end lisp The @code{vec2} type is used to store 2D coordinates (@pxref{Vectors}.) A variable named @code{position} contains the position where the text should be rendered. A new hook called @code{update} has been added to handle the animation. This hook is called frequently to update the state of the game. The variable @code{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. @lisp (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)))) @end lisp This final example uses Chickadee's scripting features (@pxref{Scripting}) to bounce the text between the edges of the window indefinitely using the handy @code{tween} procedure. The only thing the @code{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! @node Command Line Interface @chapter 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. @menu * Invoking chickadee play:: Run Chickadee programs * Invoking chickadee bundle:: Create redistributable binary bundles @end menu @node Invoking chickadee play @section Invoking @command{chickadee play} The @command{chickadee play} command is used to open a window and run the Chickadee game contained within a Scheme source file. @example chickadee play the-legend-of-emacs.scm @end example In this file, special procedures may be defined to handle various events from the game loop: @itemize @item quit-game @item draw @item update @item key-press @item key-release @item text-input @item mouse-press @item mouse-release @item mouse-move @item mouse-wheel @item controller-add @item controller-remove @item controller-press @item controller-release @item controller-move @end itemize See @ref{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 @command{chickadee play} was invoked. Many aspects of the initial game window and environment can be controlled via the following options: @table @code @item --title=@var{title} @itemx -t @var{title} Set the window title to @var{title}. @item --width=@var{width} @itemx -w @var{width} Set the window width to @var{width} pixels. @item --height=@var{height} @itemx -h @var{height} Set the window height to @var{height} pixels. @item --fullscreen @itemx -f Open window in fullscreen mode. @item --resizable @itemx -r Make window resizable. @item --update-hz=@var{n} @itemx -u @var{n} Update the game @var{n} times per second. @item --clear-color=@var{color} @itemx -c @var{color} Set the screen clear color to @var{color}, a hex code in the format @code{#RRGGBB}. For example, to set the clear color to black, pass @code{--clear-color=#000000}. @item --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. @item --repl-server[=@var{port}] Launch a REPL server on port @var{port}, or 37146 by default. @command{telnet localhost 37146} (or whatever port number was given) will do the trick, but using the @uref{https://www.nongnu.org/geiser/, Geiser} extension for Emacs is by far the best way to develop at the REPL with Guile. Use @code{M-x connect-to-guile} to connect to the REPL server. Note that the REPL server defaults to the @code{(guile-user)} module, so you will first need to switch to the @code{(chickadee-user)} module like so: @example scheme@@(guile-user)> ,module (chickadee-user) scheme@@(chickadee-user)> @end example @item --language=@var{language} Process the input program using @var{language}, the identifier of a language within Guile's language tower. By default, unsurprisingly, Scheme is used. For example, to use the neat @url{https://www.draketo.de/software/wisp, Wisp} language as an alternative to Scheme's parenthetical syntax, pass @code{--language=wisp}. Wisp is not included with Guile and must be installed separately. @item -x @var{extension} Add @var{extension} to the list of file extensions that Guile will load. For example, Wisp files canonically use the @file{.w} extension. Here's what a ``hello, world'' Chickadee program looks like in Wisp: @example define : draw alpha draw-text "Hello, world!" : vec2 260.0 240.0 @end example Assuming the above code is saved to a @file{hello.w} file, @command{chickadee play} be invoked as follows: @example chickadee play --language=wisp -x .w hello.w @end example @end table @node Invoking chickadee bundle @section Invoking @command{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 @command{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 @url{https://guix.gnu.org, GNU Guix} 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 @file{bundle.scm} file to the root of the project directory. It could look something like this: @lisp '((asset-directories . ("images" "models")) (bundle-name . "the-legend-of-emacs-1.0") (code . "the-legend-of-emacs.scm") (launcher-name . "the-legend-of-emacs")) @end lisp To create the bundle, simply run @command{chickadee bundle}. Upon success, the file @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, @command{chickadee bundle} also includes the compiled Guile bytecode (the @file{.go} files) for all modules used by the game. The module source files are @emph{not} included, so it's critical that all of the modules used by the game have been compiled. Available options: @itemize @item @code{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. @item @code{binary-directories} A list of directories to search for system binaries, such as @command{guile}. By default, @file{/usr/bin} is searched. @item @code{bundle-name} The name of the bundle archive. By default, the name is @code{"chickadee-bundle"}. @item @code{launcher-name} The name of the launcher script. By default, the name is @code{"launch-game"}. @item @code{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 @code{%default-config} variable that can be of help. @item @code{library-directories} A list of directories to search for system shared libraries. By default, the list contains common directories used by most distributions. @item @code{method} The method by which the game is launched. Can be either @code{play} or @code{manual}. The default is @code{play}, which means that @command{chickadee play} will be used to launch the game. For games that do not use @command{chickadee play}, opting to start the game loop on their own, the @code{manual} method should be used. @item @code{play-args} A list of command line arguments to pass to @command{chickadee play}. Only used when the @code{method} option is set to @code{play}. @end itemize Default configuration options, such as the list of C shared libaries, can be found in the @code{%default-config} variable. This way they can be programatically modified, if necessary. @defvar %default-config An association list of default configuration options. @end defvar @node Live Coding @chapter 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 @command{chickadee play} command to run your game, then the @code{--repl} or @code{--repl-server} arguments are all you need to get a live coding environment running. If, however, you are using @code{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 @code{(system repl server)} to avoid thread synchronization issues). Then, in the game loop's update procedure, call @code{poll-coop-repl-server} and pass the REPL object. Here is a template to follow: @lisp (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 ...) @end lisp To use the REPL, connect to it via port 37146. Telnet will do the trick, but using the @uref{https://www.nongnu.org/geiser/, Geiser} extension for Emacs is by far the best way to develop at the REPL with Guile. Use @code{M-x connect-to-guile} to connect to the REPL server. @node API Reference @chapter API Reference @include api.texi @node Copying This Manual @appendix Copying This Manual @menu * Apache 2.0 License:: License for copying this manual. @end menu @c Get fdl.texi from http://www.gnu.org/licenses/fdl.html @node Apache 2.0 License @section Apache 2.0 License @include apache-2.0.texi @node Index @unnumbered Index @syncodeindex tp fn @syncodeindex vr fn @printindex fn @bye @c chickadee.texi ends here