82cde8f4fa0dce4c8d7e4a40f7335b497a2a5b2e
[chickadee.git] / doc / api.texi
1 @menu
2 * Kernel:: The fundamental components.
3 * Input:: Keyboard, mouse, and controller input.
4 * Math:: Linear algebra and more.
5 * Graphics:: Eye candy.
6 * Audio:: Sound effects and music.
7 * Buffers:: Splitting games into logical components.
8 * Scripting:: Bringing the game world to life.
9 @end menu
10
11 @node Kernel
12 @section Kernel
13
14 At the very core of Chickadee, in the @code{(chickadee)} module, lies
15 an event loop. This loop, or ``kernel'', is responsible for creating
16 and managing the game window, dispatching input events, ensuring that
17 the game is updated at the desired interval, and rendering graphics.
18 The kernel implements what is known as a ``fixed timestep'' game loop,
19 meaning that the game simulation will be advanced by a fixed interval
20 of time and will never vary from frame to frame, unlike some other
21 styles of game loops. The appropriately named @code{run-game} and
22 @code{abort-game} procedures are the entry and exit points to the
23 Chickadee kernel.
24
25 On its own, the kernel does not do very much at all. In order to
26 actually respond to input events, update game state, or draw something
27 to the game window, a hacker with a penchant for game development must
28 latch onto extension points built into the kernel, called ``hooks'',
29 and specify what action ought to be taken for any given event. For
30 example, the @code{key-press-hook} can be used to respond to the
31 @code{a} key being pressed by swinging the player's mighty sword.
32 There are many hooks available, so read on to learn about all of them.
33 For information about using Guile's hook API, see @xref{Hooks,,,
34 guile, GNU Guile Reference Manual}.
35
36 @deffn {Procedure} run-game [#:window-title "Chickadee!"] @
37 [#:window-width 640] [#:window-height 480] [#:window-fullscreen? #f] @
38 [#:update-hz 60]
39
40 Start the event loop. This procedure will not return until
41 @code{abort-game} is called.
42
43 The @code{update-hook} will be run @var{update-hz} times per second.
44
45 A new graphical window will be opened with @var{window-width} x
46 @var{window-height} as its dimensions, @var{window-title} as its
47 title, and in fullscreen mode if @var{window-fullscreen?} is
48 @code{#t}.
49 @end deffn
50
51 @deffn {Procedure} abort-game
52 Stop the currently running Chickadee event loop.
53 @end deffn
54
55 @deffn {Procedure} time
56 Return the current game time in milliseconds.
57 @end deffn
58
59 @defvr {Variable} load-hook
60 A hook that is run once when the event loop boots, before any other
61 hook is run. This hook is run with zero arguments.
62
63 @example
64 (add-hook! load-hook (lambda () (display "hello!\n")))
65 @end example
66
67 @end defvr
68
69 @defvr {Variable} update-hook
70 A hook that is run every time the game simulation should be advanced.
71 This hook is run with a single argument @var{dt}, the fixed timestep
72 that was configured when the event loop was started, in milliseconds.
73
74 @example
75 (add-hook! update-hook (lambda (dt) (display "tick!\n")))
76 @end example
77
78 @end defvr
79
80 @defvr {Variable} before-draw-hook
81 A hook that is run before a frame is rendered. This hook is run with
82 zero arguments.
83
84 @example
85 (add-hook! before-draw-hook (lambda () (display "about to draw!\n")))
86 @end example
87
88 @end defvr
89
90 @defvr {Variable} after-draw-hook
91 A hook that is run after a frame is rendered. This hook is run with
92 zero arguments.
93
94 @example
95 (add-hook! after-draw-hook (lambda () (display "done drawing!\n")))
96 @end example
97
98 Combined with @code{before-draw-hook}, one can perform a frames per
99 second calculation to monitor game performance and stability.
100
101 @end defvr
102
103 @defvr {Variable} draw-hook
104 A hook that is run each time a frame should be rendered. This hook is
105 run with a single argument @var{alpha}, a value in the range [0, 1]
106 which represents how much time has past since the last game state
107 update relative to the upcoming game state update, as a percentage.
108 Because the game state is updated independent of rendering, it is
109 often the case that rendering is occuring between two updates. If the
110 game is rendered as it was during the last update, a strange
111 side-effect will occur that makes animation appear rough or
112 ``choppy''. To counter this, the @var{alpha} value can be used to
113 perfrom a linear interpolation of a moving object between its current
114 position and its previous position. This odd trick has the pleasing
115 result of making the animation look smooth again, but requires keeping
116 track of previous state.
117
118 @c TODO: Add example of linear interpolation
119
120 @example
121 (add-hook! draw-hook (lambda (alpha) (display "<(._.<) \n")))
122 @end example
123
124 @end defvr
125
126 @defvr {Variable} quit-hook
127 A hook that is run when the user clicks the close button on the game
128 window. This hook is run with zero arguments.
129
130 @example
131 (add-hook! quit-hook (lambda () (display "bye!\n")))
132 @end example
133
134 @end defvr
135
136 @defvr {Variable} key-press-hook
137 A hook that is run when a key is pressed on the keyboard. This hook
138 is run with four arguments:
139
140 @enumerate
141 @item
142 @var{key}: The symbolic name of the ``virtual'' key that was pressed.
143 For example: @code{backspace}. It's called a virtual key because the
144 operating system may map a physical keyboard key to another key
145 entirely, such as how the author binds the ``caps lock'' key to mean
146 ``control''.
147
148 @item
149 @var{scancode}: The symbolic name of the physical key that was
150 pressed.
151
152 @item
153 @var{modifiers}: A list of the symbolic names of modifier keys that
154 were being held down when the key was pressed. Possible values
155 include @code{ctrl}, @code{alt}, and @code{shift}.
156
157 @item
158 @var{repeat?}: @code{#t} if this is a repeated press of the same key.
159
160 @end enumerate
161
162 @example
163 (add-hook! key-press-hook
164 (lambda (key scancode modifiers repeat?)
165 (display "pressed key: ")
166 (display key)
167 (newline)))
168 @end example
169
170 @end defvr
171
172 @defvr {Variable} key-release-hook
173 A hook that is run when a key is released on the keyboard. This hook
174 is run with three arguments:
175
176 @enumerate
177 @item
178 @var{key}: The symbolic name of the ``virtual'' key that was released.
179
180 @item
181 @var{scancode}: The symbolic name of the physical key that was
182 released.
183
184 @item
185 @var{modifiers}: A list of the symbolic names of modifier keys that
186 were being held down when the key was released.
187
188 @end enumerate
189
190 @end defvr
191
192 @defvr {Variable} text-input-hook
193 A hook that is run when printable text is typed on the keyboard. This
194 hook is run with a single argument, @var{text}, a string containing
195 the text that was entered.
196 @end defvr
197
198 @defvr {Variable} mouse-press-hook
199 A hook that is run when a mouse button is pressed. This hook is run
200 with four arguments:
201
202 @enumerate
203
204 @item
205 @var{button}: The symbolic name of the button that was pressed, such
206 as @code{left}, @code{middle}, or @code{right}.
207
208 @item
209 @var{clicks}: The number of times the button has been clicked in a row.
210
211 @item
212 @var{x}: The x coordinate of the mouse cursor.
213
214 @item
215 @var{y}: The y coordinate of the mouse cursor.
216
217 @end enumerate
218
219 @end defvr
220
221 @defvr {Variable} mouse-release-hook
222 A hook that is run when a mouse button is released. This hook is run
223 with three arguments:
224
225 @enumerate
226
227 @item
228 @var{button}: The symbolic name of the button that was released.
229
230 @item
231 @var{x}: The x coordinate of the mouse cursor.
232
233 @item
234 @var{y}: The y coordinate of the mouse cursor.
235
236 @end enumerate
237
238 @end defvr
239
240 @defvr {Variable} mouse-move-hook
241 A hook that is run when the mouse is moved. This hook is run with
242 five arguments:
243
244 @enumerate
245
246 @item
247 @var{x}: The x coordinate of the mouse cursor.
248
249 @item
250 @var{y}: The y coordinate of the mouse cursor.
251
252 @item
253 @var{dx}: The amount the mouse has moved along the x axis since the
254 last mouse move event.
255
256 @item
257 @var{dy}: The amount the mouse has moved along the y axis since the
258 last mouse move event.
259
260 @item
261 @var{buttons}: A list of the buttons that were pressed down when the
262 mouse was moved.
263
264 @end enumerate
265
266 @end defvr
267
268 @defvr {Variable} controller-add-hook
269 A hook that is run when a game controller is connected. This hook is
270 run with a single argument, @var{controller}, the controller that was
271 connected.
272 @end defvr
273
274 @defvr {Variable} controller-remove-hook
275 A hook that is run when a game controller is disconnected. This hook
276 is run with a single argument, @var{controller}, the controller that
277 was disconnected.
278 @end defvr
279
280 @defvr {Variable} controller-press-hook
281 A hook that is run when a button on a game controller is pressed.
282 This hook is run with two arguments:
283
284 @enumerate
285
286 @item
287 @var{controller}: The controller that triggered the event.
288
289 @item
290 @var{button}: The symbolic name of the button that was pressed.
291 Possible buttons are:
292
293 @itemize
294 @item
295 @code{a}
296 @item
297 @code{b}
298 @item
299 @code{x}
300 @item
301 @code{y}
302 @item
303 @code{back}
304 @item
305 @code{guide}
306 @item
307 @code{start}
308 @item
309 @code{left-stick}
310 @item
311 @code{right-stick}
312 @item
313 @code{left-shoulder}
314 @item
315 @code{right-shoulder}
316 @item
317 @code{dpad-up}
318 @item
319 @code{dpad-down}
320 @item
321 @code{dpad-left}
322 @item
323 @code{dpad-right}
324
325 @end itemize
326
327 @end enumerate
328
329 @end defvr
330
331 @defvr {Variable} controller-release-hook
332 A hook that is run when a button on a game controller is released.
333
334 This hook is run with two arguments:
335
336 @enumerate
337
338 @item
339 @var{controller}: The controller that triggered the event.
340
341 @item
342 @var{button}: The symbolic name of the button that was released.
343
344 @end enumerate
345
346 @end defvr
347
348 @defvr {Variable} controller-move-hook
349 A hook that is run when an analog stick or trigger on a game
350 controller is moved. This hook is run with three arguments
351
352 @enumerate
353
354 @item
355 @var{controller}: The controller that triggered the event.
356
357 @item
358 @var{axis}: The symbolic name of the axis that was moved. Possible
359 values are:
360
361 @itemize
362 @item
363 @code{left-x}
364 @item
365 @code{left-y}
366 @item
367 @code{right-x}
368 @item
369 @code{right-y}
370 @item
371 @code{trigger-left}
372 @item
373 @code{trigger-right}
374 @end itemize
375
376 @end enumerate
377
378 @end defvr
379
380 @node Input
381 @section Input
382
383 Chickadee can handle input events from the keyboard, mouse, and game
384 controllers.
385
386 @menu
387 * Keyboard:: Keyboard input.
388 @end menu
389
390 @node Keyboard
391 @subsection Keyboard
392
393 @deffn {Procedure} key-pressed? @var{key}
394 Return @code{#t} if @var{key} is currently being pressed.
395 @end deffn
396
397 @deffn {Procedure} key-released? @var{key}
398 Return @code{#t} if @var{key} is not currently being pressed.
399 @end deffn
400
401 @node Math
402 @section Math
403
404 Chickadee contains data types and procedures for performing the most
405 common computations in video game simulations such as linear algebra
406 with vectors and matrices and axis-aligned bounding box collision
407 detection.
408
409 @menu
410 * Basics:: Commonly used, miscellaneous things.
411 * Vectors:: Euclidean vectors.
412 * Matrices:: Transformation matrices.
413 * Quaternions:: Rotations.
414 * Rectangles:: Axis-aligned bounding boxes.
415 * Easings:: Easing functions for interesting animations.
416 @end menu
417
418 @node Basics
419 @subsection Basics
420
421 @defvar pi
422 An essential constant for all trigonometry. @code{@U{03C0}} is the ratio
423 of a circle's circumferences to its diameter. Since @code{@U{03C0}} is an
424 irrational number, the @var{pi} in Chickadee is a mere floating point
425 approximation that is ``good enough.''
426 @end defvar
427
428 @defvar pi/2
429 Half of @var{pi}.
430 @end defvar
431
432 @deffn {Procedure} cotan @var{z}
433 Return the cotangent of @var{z}.
434 @end deffn
435
436 @node Vectors
437 @subsection Vectors
438
439 @node Matrices
440 @subsection Matrices
441
442 @node Quaternions
443 @subsection Quaternions
444
445 In game development, the quaternion is most often used to represent
446 rotations. Why not use a matrix for that, you may ask. Unlike
447 matrices, quaternions can be interpolated (animated) and produce a
448 meaningful result. When interpolating two quaternions, there is a
449 smooth transition from one rotation to another, whereas interpolating
450 two matrices would yield garbage.
451
452 @deffn {Procedure} quaternion @var{x} @var{y} @var{z} @var{w}
453 Return a new quaternion with values @var{x}, @var{y}, @var{z}, and
454 @var{w}.
455 @end deffn
456
457 @deffn {Procedure} quaternion? @var{obj}
458 Return @code{#t} if @var{obj} is a quaternion.
459 @end deffn
460
461 @deffn {Procedure} quaternion-w @var{q}
462 Return the W component of the quaternion @var{q}.
463 @end deffn
464
465 @deffn {Procedure} quaternion-x @var{q}
466 Return the X component of the quaternion @var{q}.
467 @end deffn
468
469 @deffn {Procedure} quaternion-y @var{q}
470 Return the Y component of the quaternion @var{q}.
471 @end deffn
472
473 @deffn {Procedure} quaternion-z @var{q}
474 Return the Z component of the quaternion @var{q}.
475 @end deffn
476
477 @deffn {Procedure} make-identity-quaternion
478 Return the identity quaternion.
479 @end deffn
480
481 @node Rectangles
482 @subsection Rectangles
483
484 @node Easings
485 @subsection Easings
486
487 @deffn {Procedure} linear @var{t}
488 @end deffn
489
490 @deffn {Procedure} smoothstep @var{t}
491 @end deffn
492
493 @deffn {Procedure} ease-in-quad @var{t}
494 @end deffn
495
496 @deffn {Procedure} ease-out-quad @var{t}
497 @end deffn
498
499 @deffn {Procedure} ease-in-out-quad @var{t}
500 @end deffn
501
502 @deffn {Procedure} ease-in-cubic @var{t}
503 @end deffn
504
505 @deffn {Procedure} ease-out-cubic @var{t}
506 @end deffn
507
508 @deffn {Procedure} ease-in-out-cubic @var{t}
509 @end deffn
510
511 @deffn {Procedure} ease-in-quart @var{t}
512 @end deffn
513
514 @deffn {Procedure} ease-out-quart @var{t}
515 @end deffn
516
517 @deffn {Procedure} ease-in-out-quart @var{t}
518 @end deffn
519
520 @deffn {Procedure} ease-in-quint @var{t}
521 @end deffn
522
523 @deffn {Procedure} ease-out-quint @var{t}
524 @end deffn
525
526 @deffn {Procedure} ease-in-out-quint @var{t}
527 @end deffn
528
529 @deffn {Procedure} ease-in-sine @var{t}
530 @end deffn
531
532 @deffn {Procedure} ease-out-sine @var{t}
533 @end deffn
534
535 @deffn {Procedure} ease-in-out-sine @var{t}
536 @end deffn
537
538 @node Graphics
539 @section Graphics
540
541 Chickadee aims to make hardware-accelerated graphics rendering as
542 simple and efficient as possible by providing high-level APIs that
543 interact with the low-level OpenGL API under the hood. Anyone that
544 has worked with OpenGL directly knows that it has a steep learning
545 curve and a lot of effort is needed to render even a single triangle.
546 The Chickadee rendering engine attempts to make it easy to do common
547 tasks like rendering a sprite while also providing all of the building
548 blocks to implement additional rendering techniques.
549
550 @menu
551 * Rendering Engine:: Rendering state management.
552 * Textures:: 2D images.
553 * Sprites:: Draw 2D images.
554 * Tile Maps:: Draw 2D tile maps.
555 * Lines and Shapes:: Draw line segments and polygons.
556 * Fonts:: Drawing text.
557 * Blending and Depth Testing:: Control how pixels are combined.
558 * Vertex Arrays:: Create 2D/3D models.
559 * Shaders:: Create custom GPU programs.
560 * Framebuffers:: Render to texture.
561 * Viewports:: Restrict rendering to
562 @end menu
563
564 @node Rendering Engine
565 @subsection Rendering Engine
566
567 Chickadee defines rendering using a metaphor familiar to Scheme
568 programmers: procedure application. A shader (@pxref{Shaders}) is
569 like a procedure for the GPU to apply. Shaders are passed arguments:
570 A vertex array containing the geometry to render (@pxref{Vertex
571 Arrays}) and zero or more keyword arguments that the shader
572 understands. Similar to how Scheme has @code{apply} for calling
573 procedures, Chickadee provides @code{gpu-apply} for calling shaders.
574
575 Additionally, there is some dynamic state that effects how
576 @code{gpu-apply} will behave. Things like the current viewport,
577 framebuffer, and blend mode are stored as dynamic state because it
578 would be tedious to have to have to specify them each time
579 @code{gpu-apply} is called.
580
581 The following procedures and syntax can be found in the
582 @code{(chickadee render)} module.
583
584 @deffn {Syntax} gpu-apply @var{shader} @var{vertex-array} @
585 [#:uniform-key @var{uniform-value} ...]
586 @deffnx {Syntax} gpu-apply* @var{shader} @var{vertex-array} @
587 @var{count} [#:uniform-key @var{uniform-value} ...]
588
589 Render @var{vertex-array} using @var{shader} with the uniform values
590 specified in the following keyword arguments.
591
592 While @code{gpu-apply} will draw every vertex in @var{vertex-array},
593 @code{gpu-apply*} will only draw @var{count} vertices.
594
595 @end deffn
596
597 @deffn {Procedure} current-viewport
598 Return the currently bound viewport. @xref{Viewports} for more
599 details about using viewports.
600 @end deffn
601
602 @deffn {Procedure} current-framebuffer
603 Return the currently bound framebuffer. @xref{Framebuffers} for more
604 details about using framebuffers.
605 @end deffn
606
607 @deffn {Procedure} current-blend-mode
608 Return the currently bound blend mode. @xref{Blending and Depth
609 Testing} for more details about using blend modes.
610 @end deffn
611
612 @deffn {Procedure} current-depth-test
613 Return @code{#t} if depth testing is currently enabled.
614 @xref{Blending and Depth Testing} for more details about using the
615 depth test.
616 @end deffn
617
618 @deffn {Procedure} current-texture
619 Return the currently bound texture. @xref{Textures} for more details
620 about using textures.
621 @end deffn
622
623 @deffn {Procedure} current-projection
624 Return the currently bound projection matrix. @xref{Matrices} for
625 more details about matrices.
626 @end deffn
627
628 @deffn {Syntax} with-viewport @var{viewport} @var{body} ...
629 Evaluate @var{body} with the current viewport bound to @var{viewport}.
630 @end deffn
631
632 @deffn {Syntax} with-framebuffer @var{framebuffer} @var{body} ...
633 Evaluate @var{body} with the current framebuffer bound to
634 @var{framebuffer}.
635 @end deffn
636
637 @deffn {Syntax} with-blend-mode @var{blend-mode} @var{body} ...
638 Evaluate @var{body} with the current blend mode bound to
639 @var{blend-mode}.
640 @end deffn
641
642 @deffn {Syntax} with-depth-test @var{depth-test?} @var{body} ...
643 Evaluate @var{body} with the depth-test disabled if @var{depth-test?}
644 is @code{#f}, or enabled otherwise.
645 @end deffn
646
647 @deffn {Syntax} with-texture @var{texture} @var{body} ...
648 Evaluate @var{body} with the current texture bound to @var{texture}.
649 @end deffn
650
651 @deffn {Syntax} with-projection @var{projection} @var{body} ...
652 Evaluate @var{body} with the current projection matrix bound to
653 @var{projection}.
654 @end deffn
655
656 @node Textures
657 @subsection Textures
658
659 @deffn {Procedure} load-image @var{file} [#:min-filter nearest] @
660 [#:mag-filter nearest] [#:wrap-s repeat] [#:wrap-t repeat]
661
662 Load the image data from @var{file} and return a new texture object.
663
664 @var{min-filter} and @var{mag-filter} describe the method that should
665 be used for minification and magnification when rendering,
666 respectively. Possible values are @code{nearest} and @code{linear}.
667
668 @var{wrap-s} and @var{wrap-t} describe how to interpret texture
669 coordinates that are greater than @code{1.0}. Possible values are
670 @code{repeat}, @code{clamp}, @code{clamp-to-border}, and
671 @code{clamp-to-edge}.
672
673 @end deffn
674
675 @node Sprites
676 @subsection Sprites
677
678 For those who are new to this game, a sprite is a 2D rectangular
679 bitmap that is rendered to the screen. For 2D games, sprites are the
680 most essential graphical abstraction. They are used for drawing maps,
681 players, NPCs, items, particles, text, etc. In Chickadee, bitmaps are
682 stored in textures (@pxref{Textures}) and can be used to draw sprites
683 via the @code{draw-sprite} procedure.
684
685 @deffn {Procedure} draw-sprite @var{texture} @var{position} @
686 [#:origin] [#:scale] [#:rotation] [#:blend-mode alpha] @
687 [#:rect] [#:shader]
688
689 Draw @var{texture} at @var{position}.
690
691 Optionally, other transformations may be applied to the sprite.
692 @var{rotation} specifies the angle to rotate the sprite, in radians.
693 @var{scale} specifies the scaling factor as a 2D vector. All
694 transformations are applied relative to @var{origin}, a 2D vector,
695 which defaults to the lower-left corner.
696
697 Alpha blending is used by default but the blending method can be
698 changed by specifying @var{blend-mode}.
699
700 The area drawn to is as big as the texture, by default. To draw to an
701 arbitrary section of the screen, specify @var{rect}.
702
703 Finally, advanced users may specify @var{shader} to change the way the
704 sprite is rendered entirely.
705 @end deffn
706
707 It's not uncommon to need to draw hundreds or thousands of sprites
708 each frame. However, GPUs (graphics processing units) are tricky
709 beasts that prefer to be sent few, large chunks of data to render
710 rather than many, small chunks. Using @code{draw-sprite} on its own
711 will involve at least one GPU call @emph{per sprite}, which will
712 quickly lead to poor performance. To deal with this, a technique
713 known as ``sprite batching'' can be used. Instead of drawing each
714 sprite immediately, the sprite batch will build up a large of buffer
715 of sprites to draw and defer rendering until the last possible moment.
716 Batching isn't a panacea, though. Batching only works if the sprites
717 being drawn share as much in common as possible. Every time you draw
718 a sprite with a different texture or blend mode, the batch will be
719 sent off to the GPU. Therefore, batching is most useful if you
720 minimize such changes. A good strategy for reducing texture changes
721 is to stuff many bitmaps into a single image file and create a
722 ``texture atlas'' (@pxref{Textures}) to access the sub-images within.
723
724 Taking advantage of sprite batching in Chickadee is easy, just wrap
725 the code that is calling @code{draw-sprite} a lot in the
726 @code{with-batched-sprites} form.
727
728 @deffn {Syntax} with-batched-sprites @var{body} @dots{}
729 Use batched rendering for all @code{draw-sprite} calls within
730 @var{body}.
731 @end deffn
732
733 With a basic sprite abstraction in place, it's possible to build other
734 abstractions on top of it. One such example is the ``nine patch''. A
735 nine patch is a sprite that can be rendered at various sizes without
736 becoming distorted. This is achieved by diving up the sprite into
737 nine regions:
738
739 @itemize
740 @item
741 the center, which can be scaled horizontally and vertically
742 @item
743 the four corners, which can never be scaled
744 @item
745 the left and right sides, which can be scaled vertically
746 @item
747 the top and bottom sides, which can be scaled horizontally
748 @end itemize
749
750 The one caveat is that the bitmap regions must be designed in such a
751 way so that they are not distorted when stretched along the affected
752 axes. For example, that means that the top and bottom sides could
753 have varying colored pixels vertically, but not horizontally.
754
755 The most common application of this technique is for graphical user
756 interface widgets like buttons and dialog boxes. By using a nine
757 patch, they can be rendered at any size without unappealing scaling
758 artifacts.
759
760 @deffn {Procedure} draw-nine-patch @var{texture} @var{rect} @
761 [#:margin 0] [#:top-margin margin] [#:bottom-margin margin] @
762 [#:left-margin margin] [#:right-margin margin] @
763 [#:origin] [#:scale] [#:rotation] [#:blend-mode alpha] @
764 [#:shader]
765
766 Draw a nine patch sprite. A nine patch sprite renders @var{texture}
767 as a @var{width} x @var{height} rectangle whose stretchable areas are
768 defined by the given margin measurements @var{top-margin},
769 @var{bottom-margin}, @var{left-margin}, and @var{right-margin}. The
770 @var{margin} argument may be used to configure all four margins at
771 once.
772
773 Refer to @code{draw-sprite} (@pxref{Sprites}) for information about
774 the other arguments.
775 @end deffn
776
777 @node Tile Maps
778 @subsection Tile Maps
779
780 A tile map is a scene created by composing lots of small sprites,
781 called ``tiles'', into a larger image. One program for editing such
782 maps is called @url{http://mapeditor.org,Tiled}. Chickadee has native
783 support for loading and rendering Tiled maps in the @code{(chickadee
784 render tiled)} module.
785
786 @deffn {Procedure} load-tile-map @var{file-name}
787 Load the Tiled formatted map in @var{file-name} and return a new tile
788 map object.
789 @end deffn
790
791 @deffn {Procedure} draw-tile-map @var{tile-map} [#:layers] [#:region] @
792 [#:origin] [#:position] [#:scale] [#:rotation]
793
794 Draw the layers of @var{tile-map}. By default, all layers are drawn.
795 To draw a subset of the available layers, pass a list of layer ids
796 using the @var{layers} keyword argument.
797
798 Refer to @code{draw-sprite} (@pxref{Sprites}) for information about
799 the other arguments.
800 @end deffn
801
802 @node Lines and Shapes
803 @subsection Lines and Shapes
804
805 Sprites are fun, but sometimes simple, untextured lines and polygons
806 are desired. That's where the @code{(chickadee render shapes)} module
807 comes in!
808
809 @deffn {Procedure} draw-line @var{start} @var{end} @
810 [#:thickness 0.5] [#:feather 1.0] [#:cap round] [#:color] @
811 [#:shader]
812
813 Draw a line segment from @var{start} to @var{end}. The line will be
814 @var{thickness} pixels thick with an antialiased border @var{feather}
815 pixels wide. The line will be colored @var{color}. @var{cap}
816 specifies the type of end cap that should be used to terminate the
817 lines, either @code{none}, @code{butt}, @code{square}, @code{round},
818 @code{triangle-in}, or @code{triangle-out}. Advanced users may use
819 the @var{shader} argument to override the built-in line segment
820 shader.
821 @end deffn
822
823 @node Fonts
824 @subsection Fonts
825
826 Unlike the traditional TrueType font format that many are accustomed
827 to, Chickadee loads and renders bitmap fonts in the
828 @url{http://www.angelcode.com/products/bmfont/doc/file_format.html,
829 Angel Code format}. But why use this seemingly obscure format? It's
830 easy to find TTFs but not easy to find FNTs (the canonical file
831 extension used for Angel Code fonts) and bitmap fonts don't scale
832 well. The reason is efficiency.
833
834 If all of the glyphs of a font are pre-rendered and packed into an
835 image file then it becomes possible to use a texture atlas
836 (@pxref{Textures}) and a sprite batch (@pxref{Sprites}) when
837 rendering, which is a more efficient way to render fonts than using,
838 say, @url{https://www.libsdl.org/projects/SDL_ttf/, SDL_ttf} or other
839 solutions that involve using the FreeType library directly.
840
841 Now what about scaling? In libraries that use TTF fonts, one must
842 choose the size that the glyphs will be rasterized at up front. To
843 use @code{n} sizes of the same font, one must load @code{n} variants
844 of that font. If the size of the text is dynamic, some kind of
845 texture scaling algorithm must be used and the text will inevitably
846 look blurry. At first glance, using bitmap fonts seem to have an even
847 worse issue. Instead of just loading the same font @code{n} times at
848 different sizes, one would need to generate @code{n} image files for
849 each font size needed. This is where the ``signed distance field''
850 rendering technique comes in. Introduced by
851 @url{http://www.valvesoftware.com/.../2007/SIGGRAPH2007_AlphaTestedMagnification.pdf,
852 Valve} in 2007, signed distance field fonts can be efficiently stored
853 in a bitmap and be rendered at arbitrary scale factors with good
854 results.
855
856 While Chickadee does not yet offer a tool for converting TTF fonts
857 into FNT fonts, tools such as
858 @url{https://github.com/libgdx/libgdx/wiki/Hiero, Hiero} may be used
859 in the meantime.
860
861 The following procedures can be found in the @code{(chickadee render
862 font)} module.
863
864 @deffn {Procedure} load-font @var{file}
865 Load the Angel Code formatted XML document in @var{file} and return a
866 new font object.
867 @end deffn
868
869 @deffn {Procedure} font? @var{obj}
870 Return @code{#t} if @var{obj} is a font object.
871 @end deffn
872
873 @deffn {Procedure} font-face @var{font}
874 Return the name of @var{font}.
875 @end deffn
876
877 @deffn {Procedure} font-line-height @var{font}
878 Return the line height of @var{font}.
879 @end deffn
880
881 @deffn {Procedure} font-line-height @var{font}
882 Return the line height of @var{font}.
883 @end deffn
884
885 @deffn {Procedure} font-bold? @var{font}
886 Return @code{#t} if @var{font} is a bold font.
887 @end deffn
888
889 @deffn {Procedure} font-italic? @var{font}
890 Return @code{#t} if @var{font} is an italicized font.
891 @end deffn
892
893 @deffn {Procedure} draw-text @var{font} @var{text} @var{position}
894 [#:origin] [#:scale] [#:rotation] [#:blend-mode]
895
896 Draw the string @var{text} with the first character starting at
897 @var{position} using @var{font}.
898
899 @example
900 (draw-text font "Hello, world!" (vec2 128.0 128.0))
901 @end example
902
903 Refer to @code{draw-sprite} (@pxref{Sprites}) for information about
904 the other arguments.
905 @end deffn
906
907 @node Blending and Depth Testing
908 @subsection Blending and Depth Testing
909
910 @node Vertex Arrays
911 @subsection Vertex Arrays
912
913 @node Shaders
914 @subsection Shaders
915
916 Shaders are programs for the GPU to evaluate. They are written in the
917 OpenGL Shading Language, or GLSL. Chickadee does not currently
918 provide a Scheme-like domain specific language for writing shaders.
919 Since shaders must be written in GLSL and not Scheme, they are
920 considered an advanced feature.
921
922 @node Framebuffers
923 @subsection Framebuffers
924
925 @node Viewports
926 @subsection Viewports
927
928 @node Audio
929 @section Audio
930
931 Chickadee has two data types for audio: samples and music. Samples
932 are for short sound effects like explosions. Music is for, well,
933 uh@dots{}, music.
934
935 Supported file formats include WAV and OGG.
936
937 @deffn {Procedure} load-sample @var{file}
938 Load audio sample from @var{file}.
939 @end deffn
940
941 @deffn {Procedure} set-sample-volume! @var{volume}
942 Set the volume that all samples are played at to @var{volume}, an
943 integer value between 0 and 128.
944 @end deffn
945
946 @deffn {Procedure} play-sample @var{sample}
947 Play @var{sample}. Pretty straightforward!
948 @end deffn
949
950 @deffn {Procedure} load-music @var{file}
951 Load music from @var{file}.
952 @end deffn
953
954 @deffn {Procedure} music-volume
955 Return the volume level for music, an integer value between 0 and 128.
956 @end deffn
957
958 @deffn {Procedure} set-music-volume! @var{volume}
959 Set the volume that music is played at to @var{volume}, an integer
960 value between 0 and 128.
961 @end deffn
962
963 @deffn {Procedure} play-music @var{music} [@var{loop?}]
964 Play @var{music}. If @var{loop?}, play it over and over and over and
965 over and@dots{}
966 @end deffn
967
968 @deffn {Procedure} pause-music
969 Pause the current music track.
970 @end deffn
971
972 @deffn {Procedure} resume-music
973 Resume the current music track.
974 @end deffn
975
976 @deffn {Procedure} rewind-music
977 estart the current music track from the beginning.
978 @end deffn
979
980 @deffn {Procedure} stop-music
981 Stop playing the current music track.
982 @end deffn
983
984 @deffn {Procedure} music-playing?
985 Return @code{#t} if music is currently playing.
986 @end deffn
987
988 @deffn {Procedure} music-paused?
989 Return @code{#t} if music is currently paused.
990 @end deffn
991
992 @node Buffers
993 @section Buffers
994
995 Games are big state machines and they can get complex quickly, thus we
996 need tools to manage that complexity. One useful technique is to
997 separate the many ``screens'' of a game (such as the main menu, player
998 select screen, high score table, game over screen, etc.) from each
999 other, so that it is possible to program the logic for one section of
1000 the game independent of another. In Chickadee, these ``screens'' are
1001 called ``buffers''. In other game engines this same construct may be
1002 called a ``scene'' or ``room''.
1003
1004 A buffer knows how to update its state, render, handle input events,
1005 etc. Only one buffer is ever active at a time, and the current buffer
1006 can be changed with procedures like @code{push-buffer},
1007 @code{replace-buffer}, and @code{pop-buffer}.
1008
1009 Buffers are implemented using Guile's object oriented programming
1010 system (@pxref{GOOPS,,, guile, GNU Guile Reference Manual}). Each
1011 type of buffer is represented as a subclass of the @code{<buffer>}
1012 class. Once a new buffer class has been created, there are many
1013 methods that can be specialized for that class.
1014
1015 To install buffer support and set the initial buffer, call the
1016 @code{use-buffers!} procedure.
1017
1018 Let's take a look at a simple example to see how it all comes
1019 together:
1020
1021 @example
1022 (use-modules (chickadee)
1023 (chickadee buffer)
1024 (chickadee math vector)
1025 (chickadee render sprite)
1026 (chickadee render texture)
1027 (oop goops))
1028
1029 ;; Define a new buffer type.
1030 (define-class <splash-screen> (<buffer>)
1031 (chickadee #:accessor chickadee #:init-value #f))
1032
1033 ;; Define the logic for when the buffer is first activated.
1034 (define-method (start (splash <splash-screen>))
1035 (set! (chickadee splash) (load-image "images/chickadee.png")))
1036
1037 ;; Define how the buffer should be rendered.
1038 (define-method (draw (splash <splash-screen>) alpha)
1039 (draw-sprite (chickadee splash) (vec2 256.0 176.0)))
1040
1041 ;; Hook into the game engine and make the splash screen the initial buffer.
1042 (use-buffers! (make <splash-screen>))
1043
1044 ;; Start the game!
1045 (run-game)
1046 @end example
1047
1048 @deffn {Class} <buffer>
1049 The parent class for all buffers.
1050 @end deffn
1051
1052 @deffn {Method} started? @var{buffer}
1053 Return @code{#t} if @var{buffer} has been activated by the game engine.
1054 @end deffn
1055
1056 @deffn {Method} start @var{buffer}
1057 Called when @var{buffer} becomes the current buffer for the first time.
1058 @end deffn
1059
1060 @deffn {Method} stop @var{buffer}
1061 Called when @var{buffer} is no longer in use.
1062 @end deffn
1063
1064 @deffn {Method} pause @var{buffer}
1065 Called when @var{buffer} is no longer the current buffer but still in
1066 use.
1067 @end deffn
1068
1069 @deffn {Method} resume @var{buffer}
1070 Called when @var{buffer} becomes the current buffer after having been
1071 suspended.
1072 @end deffn
1073
1074 The following methods are simply wrappers around the hooks described
1075 in @xref{Kernel}, so see that section for more detail about the
1076 arguments to these methods. The engine calls these methods with the
1077 current buffer as the first argument.
1078
1079 @deffn {Method} update @var{buffer} @var{dt}
1080 Advance the simulation running in @var{buffer} by @var{dt} units of
1081 time.
1082 @end deffn
1083
1084 @deffn {Method} abort @var{buffer}
1085 Called when the user tries to close the game window.
1086 @end deffn
1087
1088 @deffn {Method} before-draw @var{buffer}
1089 Called before @var{buffer} is rendered.
1090 @end deffn
1091
1092 @deffn {Method} after-draw @var{buffer}
1093 Called after @var{buffer} is rendered.
1094 @end deffn
1095
1096 @deffn {Method} draw @var{buffer} @var{alpha}
1097 Render @var{buffer}.
1098 @end deffn
1099
1100 @deffn {Method} key-press @var{buffer} @var{key} @var{scancode} @var{modifiers} @var{repeat?}
1101 Handle key press event.
1102 @end deffn
1103
1104 @deffn {Method} key-release @var{buffer} @var{key} @var{scancode} @var{modifiers}
1105 Handle key release event.
1106 @end deffn
1107
1108 @deffn {Method} text-input @var{buffer} @var{text}
1109 Handle text input event.
1110 @end deffn
1111
1112 @deffn {Method} mouse-press @var{buffer} @var{button} @var{clicks} @var{x} @var{y}
1113 Handle mouse press event.
1114 @end deffn
1115
1116 @deffn {Method} mouse-release @var{buffer} @var{button} @var{x} @var{y}
1117 Handle mouse release event.
1118 @end deffn
1119
1120 @deffn {Method} mouse-move @var{buffer} @var{x} @var{y} @var{x-rel} @var{y-rel} @var{buttons}
1121 Handle mouse move event.
1122 @end deffn
1123
1124 @deffn {Method} controller-add @var{buffer} @var{controller}
1125 Handle controller add event.
1126 @end deffn
1127
1128 @deffn {Method} controller-remove @var{buffer} @var{controller}
1129 Handle controller remove event.
1130 @end deffn
1131
1132 @deffn {Method} controller-press @var{buffer} @var{controller} @var{button}
1133 Handle controller press event.
1134 @end deffn
1135
1136 @deffn {Method} controller-release @var{buffer} @var{controller} @var{button}
1137 Handle controller release event.
1138 @end deffn
1139
1140 @deffn {Method} controller-move @var{buffer} @var{controller} @var{axis} @var{value}
1141 Handle controller move event.
1142 @end deffn
1143
1144 The following procedures are used to manage the buffer stack:
1145
1146 @deffn {Procedure} use-buffers! @var{initial-buffer}
1147 Install buffers into the game engine and set the current buffer to
1148 @var{initial-buffer}.
1149 @end deffn
1150
1151 @deffn {Procedure} push-buffer! @var{buffer}
1152 Pause the current buffer and switch to @var{buffer}.
1153 @end deffn
1154
1155 @deffn {Procedure} pop-buffer!
1156 Stop the current buffer and switch back to the previously active
1157 buffer, or terminate the game loop if the buffer stack is empty.
1158 @end deffn
1159
1160 @deffn {Procedure} replace-buffer! @var{buffer}
1161 Stop the current buffer and switch to @var{buffer}
1162 @end deffn
1163
1164 @deffn {Procedure} current-buffer
1165 Return the current buffer.
1166 @end deffn
1167
1168 @node Scripting
1169 @section Scripting
1170
1171 Game logic is a web of asynchronous events that are carefully
1172 coordinated to bring the game world to life. In order to make an
1173 enemy follow and attack the player, or move an NPC back and forth in
1174 front of the item shop, or do both at the same time, a scripting
1175 system is a necessity. Chickadee comes with an asynchronous
1176 programming system in the @code{(chickadee scripting)} module.
1177 Lightweight, cooperative threads known as ``scripts'' allow the
1178 programmer to write asynchronous code as if it were synchronous, and
1179 allow many such ``threads'' to run concurrently.
1180
1181 But before we dig deeper into scripts, let's discuss the simple act
1182 of scheduling tasks.
1183
1184 @menu
1185 * Agendas:: Scheduling tasks.
1186 * Scripts:: Cooperative multitasking.
1187 * Tweening:: Animations.
1188 * Channels:: Publish data to listeners.
1189 @end menu
1190
1191 @node Agendas
1192 @subsection Agendas
1193
1194 To schedule a task to be performed later, an ``agenda'' is used.
1195 There is a default, global agenda that is ready to be used, or
1196 additional agendas may be created for different purposes. The
1197 following example prints the text ``hello'' when the agenda has
1198 advanced to time unit 10.
1199
1200 @example
1201 (at 10 (display "hello\n"))
1202 @end example
1203
1204 Most of the time it is more convenient to schedule tasks relative to
1205 the current time. This is where @code{after} comes in handy:
1206
1207 @example
1208 (after 10 (display "hello\n"))
1209 @end example
1210
1211 Time units in the agenda are in no way connected to real time. It's
1212 up to the programmer to decide what agenda time means. A simple and
1213 effective approach is to map each call of the update hook
1214 (@pxref{Kernel}) to 1 unit of agenda time, like so:
1215
1216 @example
1217 (add-hook! update-hook (lambda (dt) (update-agenda 1)))
1218 @end example
1219
1220 It is important to call @code{update-agenda} periodically, otherwise
1221 no tasks will ever be run!
1222
1223 In addition to using the global agenda, it is useful to have multiple
1224 agendas for different purposes. For example, the game world can use a
1225 different agenda than the user interface, so that pausing the game is
1226 a simple matter of not updating the world's agenda while continuing to
1227 update the user interface's agenda. The current agenda is dynamically
1228 scoped and can be changed using the @code{with-agenda} special form:
1229
1230 @example
1231 (define game-world-agenda (make-agenda))
1232
1233 (with-agenda game-world-agenda
1234 (at 60 (spawn-goblin))
1235 (at 120 (spawn-goblin))
1236 (at 240 (spawn-goblin-king)))
1237 @end example
1238
1239 @deffn {Procedure} make-agenda
1240 Return a new task scheduler.
1241 @end deffn
1242
1243 @deffn {Procedure} agenda? @var{obj}
1244 Return @code{#t} if @var{obj} is an agenda.
1245 @end deffn
1246
1247 @deffn {Procedure} current-agenda
1248 @deffnx {Procedure} current-agenda @var{agenda}
1249 When called with no arguments, return the current agenda. When called
1250 with one argument, set the current agenda to @var{agenda}.
1251 @end deffn
1252
1253 @deffn {Syntax} with-agenda @var{agenda} @var{body} @dots{}
1254 Evaluate @var{body} with the current agenda set to @var{agenda}.
1255 @end deffn
1256
1257 @deffn {Procedure} agenda-time
1258 Return the current agenda time.
1259 @end deffn
1260
1261 @deffn {Procedure} update-agenda @var{dt}
1262 Advance the current agenda by @var{dt}.
1263 @end deffn
1264
1265 @deffn {Procedure} schedule-at @var{time} @var{thunk}
1266 Schedule @var{thunk}, a procedure of zero arguments, to be run at
1267 @var{time}.
1268 @end deffn
1269
1270 @deffn {Procedure} schedule-after @var{delay} @var{thunk}
1271 Schedule @var{thunk}, a procedure of zero arguments, to be run after
1272 @var{delay}.
1273 @end deffn
1274
1275 @deffn {Procedure} schedule-every @var{interval} @var{thunk} [@var{n}]
1276 Schedule @var{thunk}, a procedure of zero arguments, to be run every
1277 @var{interval} amount of time. Repeat this @var{n} times, or
1278 indefinitely if not specified.
1279 @end deffn
1280
1281 @deffn {Syntax} at @var{time} @var{body} @dots{}
1282 Schedule @var{body} to be evaluated at @var{time}.
1283 @end deffn
1284
1285 @deffn {Syntax} after @var{delay} @var{body} @dots{}
1286 Schedule @var{body} to be evaluated after @var{delay}.
1287 @end deffn
1288
1289 @deffn {Syntax} every @var{interval} @var{body} @dots{}
1290 @deffnx {Syntax} every (@var{interval} @var{n}) @var{body} @dots{}
1291 Schedule @var{body} to be evaluated every @var{interval} amount of
1292 time. Repeat this @var{n} times, or indefinitely if not specified.
1293 @end deffn
1294
1295 @node Scripts
1296 @subsection Scripts
1297
1298 Now that we can schedule tasks, let's take things to the next level.
1299 It sure would be great if we could make procedures that described a
1300 series of actions that happened over time, especially if we could do
1301 so without contorting our code into a nest of callback procedures.
1302 This is where scripts come in. With scripts we can write code in a
1303 linear way, in a manner that appears to be synchronous, but with the
1304 ability to suspend periodically in order to let other scripts have a
1305 turn and prevent blocking the game loop. Building on top of the
1306 scheduling that agendas provide, here is a script that models a child
1307 trying to get their mother's attention:
1308
1309 @example
1310 (script
1311 (while #t
1312 (display "mom!")
1313 (newline)
1314 (sleep 60))) ; where 60 = 1 second of real time
1315 @end example
1316
1317 This code runs in an endless loop, but the @code{sleep} procedure
1318 suspends the script and schedules it to be run later by the agenda.
1319 So, after each iteration of the loop, control is returned back to the
1320 game loop and the program is not stuck spinning in a loop that will
1321 never exit. Pretty neat, eh?
1322
1323 Scripts can suspend to any capable handler, not just the agenda.
1324 The @code{yield} procedure will suspend the current script and pass
1325 its ``continuation'' to a handler procedure. This handler procedure
1326 could do anything. Perhaps the handler stashes the continuation
1327 somewhere where it will be resumed when the user presses a specific
1328 key on the keyboard, or maybe it will be resumed when the player picks
1329 up an item off of the dungeon floor; the sky is the limit.
1330
1331 Sometimes it is necessary to abruptly terminate a script after it has
1332 been started. For example, when an enemy is defeated their AI routine
1333 needs to be shut down. When a script is spawned, a handle to that
1334 script is returned that can be used to cancel it when desired.
1335
1336 @example
1337 (define script (script (while #t (display "hey\n") (sleep 60))))
1338 ;; sometime later
1339 (cancel-script script)
1340 @end example
1341
1342 @deffn {Procedure} spawn-script @var{thunk}
1343 Apply @var{thunk} as a script and return a handle to it.
1344 @end deffn
1345
1346 @deffn {Syntax} script @var{body} @dots{}
1347 Evaluate @var{body} as a script and return a handle to it.
1348 @end deffn
1349
1350 @deffn {Procedure} script? @var{obj}
1351 Return @code{#t} if @var{obj} is a script handle.
1352 @end deffn
1353
1354 @deffn {Procedure} script-cancelled? @var{obj}
1355 Return @code{#t} if @var{obj} has been cancelled.
1356 @end deffn
1357
1358 @deffn {Procedure} script-running? @var{obj}
1359 Return @code{#t} if @var{obj} has not yet terminated or been
1360 cancelled.
1361 @end deffn
1362
1363 @deffn {Procedure} script-complete? @var{obj}
1364 Return @code{#t} if @var{obj} has terminated.
1365 @end deffn
1366
1367 @deffn {Procedure} cancel-script @var{co}
1368 Prevent further execution of the script @var{co}.
1369 @end deffn
1370
1371 @deffn {Procedure} yield @var{handler}
1372 Suspend the current script and pass its continuation to the
1373 procedure @var{handler}.
1374 @end deffn
1375
1376 @deffn {Procedure} sleep @var{duration}
1377 Wait @var{duration} before resuming the current script.
1378 @end deffn
1379
1380 @deffn {Procedure} channel-get @var{channel}
1381 Wait for a message from @var{channel}.
1382 @end deffn
1383
1384 @deffn {Syntax} forever @var{body} @dots{}
1385 Evaluate @var{body} in an endless loop.
1386 @end deffn
1387
1388 @node Tweening
1389 @subsection Tweening
1390
1391 Tweening is the process of transitioning something from an initial
1392 state to a final state over a pre-determined period of time. In other
1393 words, tweening is a way to create animation. The @code{tween}
1394 procedure can be used within any script like so:
1395
1396 @example
1397 (define x 0)
1398 (script
1399 ;; 0 to 100 in 60 ticks of the agenda.
1400 (tween 60 0 100 (lambda (y) (set! x y))))
1401 @end example
1402
1403 @deffn {Procedure} tween @var{duration} @var{start} @var{end} @var{proc} [#:step 1 #:ease @code{smoothstep} #:interpolate @code{lerp}]
1404 Transition a value from @var{start} to @var{end} over @var{duration},
1405 sending each succesive value to @var{proc}. @var{step} controls the
1406 amount of time between each update of the animation.
1407
1408 To control how the animation goes from the initial to final state, an
1409 ``easing'' procedure may be specified. By default, the
1410 @code{smoothstep} easing is used, which is a more pleasing default
1411 than a simplistic linear function. @xref{Easings} for a complete list
1412 of available easing procedures.
1413
1414 The @var{interpolate} procedure computes the values in between
1415 @var{start} and @var{end}. By default, linear interpolation (``lerp''
1416 for short) is used.
1417 @end deffn
1418
1419 @node Channels
1420 @subsection Channels
1421
1422 Channels are a tool for communicating amongst different scripts. One
1423 script can write a value to the channel and another can read from it.
1424 Reading or writing to a channel suspends that script until there is
1425 someone on the other end of the line to complete the transaction.
1426
1427 Here's a simplistic example:
1428
1429 @example
1430 (define c (make-channel))
1431
1432 (script
1433 (forever
1434 (let ((item (channel-get c)))
1435 (pk 'got item))))
1436
1437 (script
1438 (channel-put c 'sword)
1439 (channel-put c 'shield)
1440 (channel-put c 'potion))
1441 @end example
1442
1443 @deffn {Procedure} make-channel
1444 Return a new channel
1445 @end deffn
1446
1447 @deffn {Procedure} channel? @var{obj}
1448 Return @code{#t} if @var{obj} is a channel.
1449 @end deffn
1450
1451 @deffn {Procedure} channel-get @var{channel}
1452 Retrieve a value from @var{channel}. The current script suspends
1453 until a value is available.
1454 @end deffn
1455
1456 @deffn {Procedure} channel-put @var{channel} @var{data}
1457 Send @var{data} to @var{channel}. The current script suspends until
1458 another script is available to retrieve the value.
1459 @end deffn