a7af1952d336

Update docs
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Tue, 08 Nov 2016 13:27:17 +0000
parents d337c4b0c165
children 42aaba702d24
branches/tags (none)
files Makefile README.markdown docs/01-installation.markdown docs/01-overview.markdown docs/02-overview.markdown docs/02-usage.markdown docs/03-reference.markdown docs/03-usage.markdown docs/04-changelog.markdown docs/04-reference.markdown docs/05-changelog.markdown docs/api.lisp docs/index.markdown

Changes

diff -r d337c4b0c165 -r a7af1952d336 Makefile
--- a/Makefile	Thu Sep 08 14:12:48 2016 +0000
+++ b/Makefile	Tue Nov 08 13:27:17 2016 +0000
@@ -2,7 +2,7 @@
 
 sourcefiles = $(shell ffind --full-path --literal .lisp)
 docfiles = $(shell ls docs/*.markdown)
-apidoc = docs/04-reference.markdown
+apidoc = docs/03-reference.markdown
 
 # Vendor ----------------------------------------------------------------------
 vendor/quickutils.lisp: vendor/make-quickutils.lisp
diff -r d337c4b0c165 -r a7af1952d336 README.markdown
--- a/README.markdown	Thu Sep 08 14:12:48 2016 +0000
+++ b/README.markdown	Tue Nov 08 13:27:17 2016 +0000
@@ -13,6 +13,10 @@
 Lisp.  It's a thin layer of sugar over CLOS that makes it easy to write flexible
 objects for video games.
 
+Beast can be installed with [Quicklisp][]:
+
+    (ql:quickload :beast)
+
 Check out the [Overview](http://sjl.bitbucket.org/beast/overview/) for
 a three-minute description of what this is, or the
 [Usage](http://sjl.bitbucket.org/beast/usage/) for a full rundown.
@@ -24,3 +28,5 @@
 
 The test suite currently passes in SBCL, CCL, ECL, and ABCL on OS X and Debian.
 Further testing is welcome.
+
+[quicklisp]: https://quicklisp.org/
diff -r d337c4b0c165 -r a7af1952d336 docs/01-installation.markdown
--- a/docs/01-installation.markdown	Thu Sep 08 14:12:48 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-Installation
-============
-
-Beast is compatible with Quicklisp, but not *in* Quicklisp (yet?).  You can
-clone the repository into your [Quicklisp local-projects][local] directory for
-now.
-
-[local]: https://www.quicklisp.org/beta/faq.html#local-project
diff -r d337c4b0c165 -r a7af1952d336 docs/01-overview.markdown
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/01-overview.markdown	Tue Nov 08 13:27:17 2016 +0000
@@ -0,0 +1,67 @@
+Overview
+========
+
+When you're making a video game you need a way to model things in the game
+world.  In the past couple of decades Entity/Component systems have become
+popular:
+
+* <http://gameprogrammingpatterns.com/component.html>
+* <http://en.wikipedia.org/wiki/Entity_component_system>
+* <http://www.gamedev.net/page/resources/_/technical/game-programming/understanding-component-entity-systems-r3013>
+
+There are a couple of ECS libraries for Common Lisp already:
+
+* [cl-ecs](https://github.com/lispgames/cl-ecs)
+* [ecstasy](https://github.com/mfiano/ecstasy)
+
+Both of these favor composition over inheritance -- game objects (entities)
+*contain* various components, but they don't *inherit* from components.
+
+Beast takes the opposite approach, favoring (restricted) inheritance over
+composition.
+
+Components in Beast are called "aspects" to try to overload the word "component"
+a little bit less in this crazy world.  Aspects are essentially
+[mixins](https://en.wikipedia.org/wiki/Mixin), with some sugar for defining them
+and running systems over them:
+
+    :::lisp
+    (define-aspect throwable accuracy damage)
+    (define-aspect edible nutrition-value)
+
+    (define-entity dart (throwable))
+    (define-entity cheese (edible))
+    (define-entity pie (throwable edible))
+
+    (define-system rot-food ((e edible))
+      (decf (edible/nutrition-value e))
+      (when (zerop (edible/nutrition-value e))
+        (destroy-entity e)))
+
+    (defparameter *steel-dart* 
+      (create-entity 'dart
+        :throwable/accuracy 0.9
+        :throwable/damage 10))
+
+    (defparameter *hunk-of-swiss*
+      (create-entity 'cheese
+        :edible/nutrition-value 50))
+
+    (defparameter *banana-cream-pie*
+      (create-entity 'pie
+        :throwable/accuracy 0.3
+        :throwable/damage 5
+        :edible/nutrition-value 30))
+
+Beast tries to be just a very thin layer over CLOS, because CLOS is quite
+powerful.  You can use `typep`, generic methods, before/after/around methods,
+and everything else CLOS gives you.
+
+Like every engineering decision this comes with tradeoffs.  You can't (easily)
+add or remove aspects to/from a particular entity at runtime like you can with
+cl-ecs.  And there's no way to give an entity multiple "copies" of a single
+aspect.
+
+The author has found this approach to work well for his needs.  You should take
+a look at both approaches and decide which is best for you.  If you want to read
+more, check out the [Usage](../usage/) document.
diff -r d337c4b0c165 -r a7af1952d336 docs/02-overview.markdown
--- a/docs/02-overview.markdown	Thu Sep 08 14:12:48 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-Overview
-========
-
-When you're making a video game you need a way to model things in the game
-world.  In the past couple of decades Entity/Component systems have become
-popular:
-
-* <http://gameprogrammingpatterns.com/component.html>
-* <http://en.wikipedia.org/wiki/Entity_component_system>
-* <http://www.gamedev.net/page/resources/_/technical/game-programming/understanding-component-entity-systems-r3013>
-
-There are a couple of ECS libraries for Common Lisp already:
-
-* [cl-ecs](https://github.com/lispgames/cl-ecs)
-* [ecstasy](https://github.com/mfiano/ecstasy)
-
-Both of these favor composition over inheritance -- game objects (entities)
-*contain* various components, but they don't *inherit* from components.
-
-Beast takes the opposite approach, favoring (restricted) inheritance over
-composition.
-
-Components in Beast are called "aspects" to try to overload the word "component"
-a little bit less in this crazy world.  Aspects are essentially
-[mixins](https://en.wikipedia.org/wiki/Mixin), with some sugar for defining them
-and running systems over them:
-
-    :::lisp
-    (define-aspect throwable accuracy damage)
-    (define-aspect edible nutrition-value)
-
-    (define-entity dart (throwable))
-    (define-entity cheese (edible))
-    (define-entity pie (throwable edible))
-
-    (define-system rot-food ((e edible))
-      (decf (edible/nutrition-value e))
-      (when (zerop (edible/nutrition-value e))
-        (destroy-entity e)))
-
-    (defparameter *steel-dart* 
-      (create-entity 'dart
-        :throwable/accuracy 0.9
-        :throwable/damage 10))
-
-    (defparameter *hunk-of-swiss*
-      (create-entity 'cheese
-        :edible/nutrition-value 50))
-
-    (defparameter *banana-cream-pie*
-      (create-entity 'pie
-        :throwable/accuracy 0.3
-        :throwable/damage 5
-        :edible/nutrition-value 30))
-
-Beast tries to be just a very thin layer over CLOS, because CLOS is quite
-powerful.  You can use `typep`, generic methods, before/after/around methods,
-and everything else CLOS gives you.
-
-Like every engineering decision this comes with tradeoffs.  You can't (easily)
-add or remove aspects to/from a particular entity at runtime like you can with
-cl-ecs.  And there's no way to give an entity multiple "copies" of a single
-aspect.
-
-The author has found this approach to work well for his needs.  You should take
-a look at both approaches and decide which is best for you.  If you want to read
-more, check out the [Usage](../usage/) document.
diff -r d337c4b0c165 -r a7af1952d336 docs/02-usage.markdown
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/02-usage.markdown	Tue Nov 08 13:27:17 2016 +0000
@@ -0,0 +1,216 @@
+Usage
+=====
+
+Beast aims to be a thin layer over CLOS, and so has a fairly small user-facing
+API.
+
+[TOC]
+
+Aspects
+-------
+
+Aspects are facets/traits of your game objects that you want to model.  Some
+examples could be things like: location, moveable, visible, edible, sentient.
+
+### Defining Aspects
+
+To define an aspect you use `define-aspect`:
+
+    :::lisp
+    (define-aspect location x y)
+    (define-aspect edible nutrition-value)
+
+`define-aspect` takes the name of the aspect and zero or more slot definitions.
+
+The names of aspect slots will be have the aspect name prepended to them with
+a slash to avoid clashing between aspects, and the `initargs` and `accessors`
+will be added for you.  So for example, this:
+
+    :::lisp
+    (define-aspect inspectable text)
+    (define-aspect readable text)
+
+Would macroexpand into something roughly like:
+
+    :::lisp
+    (defclass inspectable ()
+      ((inspectable/text :initarg :inspectable/text
+                         :accessor inspectable/text)))
+
+    (defclass readable ()
+      ((readable/text :initarg :readable/text
+                      :accessor readable/text)))
+
+### Aspect Slot Options
+
+You can include extra slot options when defining an aspect's slots, and they'll
+be passed along to the `defclass`.  This is especially handy for `:initform`
+and `:type`.
+
+    :::lisp
+    (define-aspect container
+      (contents :initform nil))
+
+    (define-aspect throwable
+      (accuracy :type single-float)
+      (damage :type integer))
+
+In the end it's just CLOS though, so if you want to add some `:documentation` or
+use `:allocation :class` then go nuts!
+
+### Aspect Type Predicates
+
+When you define an aspect named `foo` Beast also defines a `foo?` predicate that
+returns `(typep object 'foo)`, which comes in handy when using higher-order
+functions:
+
+    :::lisp
+    (defun whats-for-dinner? ()
+      (remove-if-not #'edible? (container/contents *fridge*)))
+
+Entities
+--------
+
+Once you've got some aspects you'll want to define some entity classes that mix
+them together.
+
+### Defining Entities
+
+You define entity classes using `define-entity`:
+
+    :::lisp
+    (define-entity dart (throwable))
+    (define-entity bread (edible))
+    (define-entity pie (edible throwable))
+    (define-entity icebox (container))
+
+The resulting classes will inherit from `entity` and each of the aspects (in
+order).  This example would expand (roughly) into:
+
+    :::lisp
+    (defclass dart (entity throwable) ())
+    (defun dart? (object) (typep object 'dart))
+
+    (defclass bread (entity edible) ())
+    (defun bread? (object) (typep object 'bread))
+
+    (defclass pie (entity edible throwable) ())
+    (defun pie? (object) (typep object 'pie))
+
+    (defclass icebox (entity container) ())
+    (defun icebox? (object) (typep object 'icebox))
+
+### Entity Slot Definitions
+
+You can also specify slot definitions at the entity level, and they'll be passed
+along to `defclass`:
+
+    :::lisp
+    (define-entity cheese (edible)
+      (variety :type (member :swiss :cheddar :feta)
+               :initarg :variety
+               :reader :cheese-variety))
+
+Note that slot definitions on entities are passed along **raw**, without the
+name-mangling or default-slot-option-adding that's done for aspects.  This may
+change in the future.
+
+### Creating and Destroying Entities
+
+After you've defined your entity classes you can can create some entities using
+`create-entity`:
+
+    :::lisp
+    (defparameter *my-fridge* (create-entity 'icebox))
+
+    (dotimes (i 30)
+      (push (create-entity 'cheese
+              :edible/nutrition-value 10
+              :variety (nth (random 3) '(:swiss :cheddar :feta)))
+            (container/contents *my-fridge*)))
+
+`create-entity` is a thin wrapper around `make-instance` that handles some extra
+bookkeeping.  When you create an entity, Beast will keep track of it in a global
+index.  We'll see the reason for this in the next section.
+
+To destroy an entity (i.e. remove it from Beast's index) you can use
+`(destroy-entity the-entity)`.  You can wipe the slate clean and remove all
+entities at once with `(clear-entities)`.
+
+### Callbacks
+
+Beast also defines two generic functions called `entity-created` and
+`entity-destroyed` which don't do anything by default, but are there for you to
+add methods on if you want.  For example:
+
+    :::lisp
+    (define-aspect location x y)
+
+    (defvar *world* (make-array (100 100) :initial-element nil))
+
+    (defmethod entity-created :after ((e location))
+      (push e (aref *world* (location/x e) (location/y e))))
+
+    (defmethod entity-destroyed :after ((e location))
+      (with-slots ((x location/x) (y location/y)) e
+        (setf (aref *world* x y) (delete e (aref *world* x y)))))
+
+
+Systems
+-------
+
+Beast's aspects and entities are just *very* thin sugar over CLOS, but systems
+provide extra functionality that comes in handy when writing games.
+
+A system is essentially a function that takes an entity as an argument with
+zero or more aspects as type specifiers.  When you run a system the function
+will be run on every entity that meet the requirements.  For example:
+
+    :::lisp
+    ; No specifiers, this just runs on every entity.
+    (define-system log-all-entities (entity)
+      (print entity))
+
+    ; Runs on entities with the lifetime aspect.
+    (define-system age ((entity lifetime))
+      (when (> (incf (lifetime/age entity))
+               (lifetime/lifespan entity))
+        (destroy-entity entity)))
+
+    ; Run on entities with both the visible and location aspects.
+    (define-system render ((entity visible location))
+      (draw entity (location/x entity)
+                   (location/y entity)
+                   (visible/color entity)))
+
+Systems with more than one argument are currently supported, but should be
+considered experimental.  The API may change in the future.
+
+    :::lisp
+    ; Run on all PAIRS of entities that have the appropriate aspects.
+    (define-system detect-collisions ((e1 location collidable)
+                                      (e2 location collidable))
+      ; ...
+      )
+
+`define-system` defines a function with the same name as the system, and
+a `run-...` function that will do the actual running for you:
+
+    :::lisp
+    (define-system log-all-entities (entity)
+      (print entity))
+
+    (run-log-all-entities)
+
+You should always use the `run-...` function, but the other one can be handy to
+have around for tracing/debugging/disassembling purposes.
+
+Next Steps
+----------
+
+That's most of Beast in a nutshell.  If you've gotten this far you can dive in
+and make something, or take a look at the [API Reference](../reference/).
+
+Beast also does some stuff not discussed here like caching entities by
+aspect/system and type-hinting system functions.  If you're curious about how it
+works you can [read the source](http://bitbucket.org/sjl/beast/src/).
diff -r d337c4b0c165 -r a7af1952d336 docs/03-reference.markdown
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/03-reference.markdown	Tue Nov 08 13:27:17 2016 +0000
@@ -0,0 +1,175 @@
+# API Reference
+
+The following is a list of all user-facing parts of Beast.
+
+If there are backwards-incompatible changes to anything listed here, they will
+be noted in the changelog and the author will feel bad.
+
+Anything not listed here is subject to change at any time with no warning, so
+don't touch it.
+
+[TOC]
+
+## Package `BEAST`
+
+### `CLEAR-ENTITIES` (function)
+
+    (CLEAR-ENTITIES)
+
+Destroy all entities.
+
+  `destroy-entity` will be called for each entity.
+
+  Returns a list of all the destroyed entites.
+
+  
+
+### `CREATE-ENTITY` (function)
+
+    (CREATE-ENTITY CLASS &REST INITARGS)
+
+Create an entity of the given entity class and return it.
+
+  `initargs` will be passed along to `make-instance`.
+
+  The `entity-created` generic function will be called just before returning the
+  entity.
+
+  
+
+### `DEFINE-ASPECT` (macro)
+
+    (DEFINE-ASPECT NAME &REST FIELDS)
+
+Define an aspect class.
+
+  `name` should be a symbol that will become the name of the class.
+
+  `fields` should be zero or more field definitions.  Each field definition can
+  be a symbol (the field name), or a list of the field name and extra CLOS slot
+  options.
+
+  Field names will have the aspect name and a slash prepended to them to create
+  the slot names.  `:initarg` and `:accessor` slot options will also be
+  automatically generated.
+
+  Example:
+
+    (define-aspect edible
+      energy
+      (taste :initform nil))
+    =>
+    (defclass edible ()
+      ((edible/energy :initarg :edible/energy
+                      :accessor edible/energy)
+       (edible/taste :initarg :edible/taste
+                     :accessor edible/taste
+                     :initform nil)))
+
+  
+
+### `DEFINE-ENTITY` (macro)
+
+    (DEFINE-ENTITY NAME ASPECTS &REST SLOTS)
+
+Define an entity class.
+
+  `name` should be a symbol that will become the name of the class.
+
+  `aspects` should be a list of the aspects this entity should inherit from.
+
+  `slots` can be zero or more extra CLOS slot definitions.
+
+  Examples:
+
+    (define-entity potion (drinkable))
+
+    (define-entity cheese (edible visible)
+      (flavor :accessor cheese-flavor :initarg :flavor))
+
+  
+
+### `DEFINE-SYSTEM` (macro)
+
+    (DEFINE-SYSTEM NAME-AND-OPTIONS
+        ARGLIST
+      &BODY
+      BODY)
+
+Define a system.
+
+  `name-and-options` should be a list of the system name (a symbol) and any
+  system options.  A bare symbol can be used if no options are needed.
+
+  `arglist` should be a list of system arguments.  Each argument should be
+  a list of the argument name and zero or more aspect/entity classes.
+
+  Defining a system `foo` defines two functions:
+
+  * `foo` runs `body` on a single entity and should only be used for debugging,
+    tracing, or disassembling.
+  * `run-foo` should be called to run the system on all applicable entities.
+
+  Available system options:
+
+  * `:inline`: when true, try to inline the system function into the
+    system-running function to avoid the overhead of a function call for every
+    entity.  Defaults to `nil`.
+
+  Examples:
+
+    (define-system age ((entity lifetime))
+      (when (> (incf (lifetime/age entity))
+               (lifetime/lifespan entity))
+        (destroy-entity entity)))
+
+  
+
+### `DESTROY-ENTITY` (function)
+
+    (DESTROY-ENTITY ENTITY)
+
+Destroy `entity` and return it.
+
+  The `entity-destroyed` generic function will be called after the entity has
+  been destroyed and unindexed.
+
+  
+
+### `ENTITY` (class)
+
+A single entity in the game world.
+
+### `ENTITY-CREATED` (generic function)
+
+    (ENTITY-CREATED ENTITY)
+
+Called after an entity has been created and indexed.
+
+  The default method does nothing, but users can implement their own auxillary
+  methods to run code when entities are created.
+
+  
+
+### `ENTITY-DESTROYED` (generic function)
+
+    (ENTITY-DESTROYED ENTITY)
+
+Called after an entity has been destroyed and unindexed.
+
+  The default method does nothing, but users can implement their own auxillary
+  methods to run code when entities are destroyed.
+
+  
+
+### `MAP-ENTITIES` (function)
+
+    (MAP-ENTITIES FUNCTION &OPTIONAL (TYPE 'ENTITY))
+
+Map `function` over all entities that are subtypes of `type`.
+
+  Normally you should run code on entities using systems, but this function can
+  be handy for debugging purposes.
+
+  
+
diff -r d337c4b0c165 -r a7af1952d336 docs/03-usage.markdown
--- a/docs/03-usage.markdown	Thu Sep 08 14:12:48 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,216 +0,0 @@
-Usage
-=====
-
-Beast aims to be a thin layer over CLOS, and so has a fairly small user-facing
-API.
-
-[TOC]
-
-Aspects
--------
-
-Aspects are facets/traits of your game objects that you want to model.  Some
-examples could be things like: location, moveable, visible, edible, sentient.
-
-### Defining Aspects
-
-To define an aspect you use `define-aspect`:
-
-    :::lisp
-    (define-aspect location x y)
-    (define-aspect edible nutrition-value)
-
-`define-aspect` takes the name of the aspect and zero or more slot definitions.
-
-The names of aspect slots will be have the aspect name prepended to them with
-a slash to avoid clashing between aspects, and the `initargs` and `accessors`
-will be added for you.  So for example, this:
-
-    :::lisp
-    (define-aspect inspectable text)
-    (define-aspect readable text)
-
-Would macroexpand into something roughly like:
-
-    :::lisp
-    (defclass inspectable ()
-      ((inspectable/text :initarg :inspectable/text
-                         :accessor inspectable/text)))
-
-    (defclass readable ()
-      ((readable/text :initarg :readable/text
-                      :accessor readable/text)))
-
-### Aspect Slot Options
-
-You can include extra slot options when defining an aspect's slots, and they'll
-be passed along to the `defclass`.  This is especially handy for `:initform`
-and `:type`.
-
-    :::lisp
-    (define-aspect container
-      (contents :initform nil))
-
-    (define-aspect throwable
-      (accuracy :type single-float)
-      (damage :type integer))
-
-In the end it's just CLOS though, so if you want to add some `:documentation` or
-use `:allocation :class` then go nuts!
-
-### Aspect Type Predicates
-
-When you define an aspect named `foo` Beast also defines a `foo?` predicate that
-returns `(typep object 'foo)`, which comes in handy when using higher-order
-functions:
-
-    :::lisp
-    (defun whats-for-dinner? ()
-      (remove-if-not #'edible? (container/contents *fridge*)))
-
-Entities
---------
-
-Once you've got some aspects you'll want to define some entity classes that mix
-them together.
-
-### Defining Entities
-
-You define entity classes using `define-entity`:
-
-    :::lisp
-    (define-entity dart (throwable))
-    (define-entity bread (edible))
-    (define-entity pie (edible throwable))
-    (define-entity icebox (container))
-
-The resulting classes will inherit from `entity` and each of the aspects (in
-order).  This example would expand (roughly) into:
-
-    :::lisp
-    (defclass dart (entity throwable) ())
-    (defun dart? (object) (typep object 'dart))
-
-    (defclass bread (entity edible) ())
-    (defun bread? (object) (typep object 'bread))
-
-    (defclass pie (entity edible throwable) ())
-    (defun pie? (object) (typep object 'pie))
-
-    (defclass icebox (entity container) ())
-    (defun icebox? (object) (typep object 'icebox))
-
-### Entity Slot Definitions
-
-You can also specify slot definitions at the entity level, and they'll be passed
-along to `defclass`:
-
-    :::lisp
-    (define-entity cheese (edible)
-      (variety :type (member :swiss :cheddar :feta)
-               :initarg :variety
-               :reader :cheese-variety))
-
-Note that slot definitions on entities are passed along **raw**, without the
-name-mangling or default-slot-option-adding that's done for aspects.  This may
-change in the future.
-
-### Creating and Destroying Entities
-
-After you've defined your entity classes you can can create some entities using
-`create-entity`:
-
-    :::lisp
-    (defparameter *my-fridge* (create-entity 'icebox))
-
-    (dotimes (i 30)
-      (push (create-entity 'cheese
-              :edible/nutrition-value 10
-              :variety (nth (random 3) '(:swiss :cheddar :feta)))
-            (container/contents *my-fridge*)))
-
-`create-entity` is a thin wrapper around `make-instance` that handles some extra
-bookkeeping.  When you create an entity, Beast will keep track of it in a global
-index.  We'll see the reason for this in the next section.
-
-To destroy an entity (i.e. remove it from Beast's index) you can use
-`(destroy-entity the-entity)`.  You can wipe the slate clean and remove all
-entities at once with `(clear-entities)`.
-
-### Callbacks
-
-Beast also defines two generic functions called `entity-created` and
-`entity-destroyed` which don't do anything by default, but are there for you to
-add methods on if you want.  For example:
-
-    :::lisp
-    (define-aspect location x y)
-
-    (defvar *world* (make-array (100 100) :initial-element nil))
-
-    (defmethod entity-created :after ((e location))
-      (push e (aref *world* (location/x e) (location/y e))))
-
-    (defmethod entity-destroyed :after ((e location))
-      (with-slots ((x location/x) (y location/y)) e
-        (setf (aref *world* x y) (delete e (aref *world* x y)))))
-
-
-Systems
--------
-
-Beast's aspects and entities are just *very* thin sugar over CLOS, but systems
-provide extra functionality that comes in handy when writing games.
-
-A system is essentially a function that takes an entity as an argument with
-zero or more aspects as type specifiers.  When you run a system the function
-will be run on every entity that meet the requirements.  For example:
-
-    :::lisp
-    ; No specifiers, this just runs on every entity.
-    (define-system log-all-entities (entity)
-      (print entity))
-
-    ; Runs on entities with the lifetime aspect.
-    (define-system age ((entity lifetime))
-      (when (> (incf (lifetime/age entity))
-               (lifetime/lifespan entity))
-        (destroy-entity entity)))
-
-    ; Run on entities with both the visible and location aspects.
-    (define-system render ((entity visible location))
-      (draw entity (location/x entity)
-                   (location/y entity)
-                   (visible/color entity)))
-
-Systems with more than one argument are currently supported, but should be
-considered experimental.  The API may change in the future.
-
-    :::lisp
-    ; Run on all PAIRS of entities that have the appropriate aspects.
-    (define-system detect-collisions ((e1 location collidable)
-                                      (e2 location collidable))
-      ; ...
-      )
-
-`define-system` defines a function with the same name as the system, and
-a `run-...` function that will do the actual running for you:
-
-    :::lisp
-    (define-system log-all-entities (entity)
-      (print entity))
-
-    (run-log-all-entities)
-
-You should always use the `run-...` function, but the other one can be handy to
-have around for tracing/debugging/disassembling purposes.
-
-Next Steps
-----------
-
-That's most of Beast in a nutshell.  If you've gotten this far you can dive in
-and make something, or take a look at the [API Reference](../reference/).
-
-Beast also does some stuff not discussed here like caching entities by
-aspect/system and type-hinting system functions.  If you're curious about how it
-works you can [read the source](http://bitbucket.org/sjl/beast/src/).
diff -r d337c4b0c165 -r a7af1952d336 docs/04-changelog.markdown
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/04-changelog.markdown	Tue Nov 08 13:27:17 2016 +0000
@@ -0,0 +1,11 @@
+Changelog
+=========
+
+Here's the list of changes in each released version.
+
+[TOC]
+
+v1.0.0
+------
+
+Initial version.  It works, but changes may happen in the future.
diff -r d337c4b0c165 -r a7af1952d336 docs/04-reference.markdown
--- a/docs/04-reference.markdown	Thu Sep 08 14:12:48 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,190 +0,0 @@
-# API Reference
-
-The following is a list of all user-facing parts of Beast.
-
-If there are backwards-incompatible changes to anything listed here, they will
-be noted in the changelog and the author will feel bad.
-
-Anything not listed here is subject to change at any time with no warning, so
-don't touch it.
-
-[TOC]
-
-## Package `BEAST`
-
-### `CLEAR-ENTITIES` (function)
-
-    (CLEAR-ENTITIES)
-
-Destroy all entities.
-
-  `destroy-entity` will be called for each entity.
-
-  Returns a list of all the destroyed entites.
-
-  
-
-### `CREATE-ENTITY` (function)
-
-    (CREATE-ENTITY CLASS &REST INITARGS)
-
-Create an entity of the given entity class and return it.
-
-  `initargs` will be passed along to `make-instance`.
-
-  The `entity-created` generic function will be called just before returning the
-  entity.
-
-  
-
-### `DEFINE-ASPECT` (macro)
-
-    (DEFINE-ASPECT NAME &REST FIELDS)
-
-Define an aspect class.
-
-  `name` should be a symbol that will become the name of the class.
-
-  `fields` should be zero or more field definitions.  Each field definition can
-  be a symbol (the field name), or a list of the field name and extra CLOS slot
-  options.
-
-  Field names will have the aspect name and a slash prepended to them to create
-  the slot names.  `:initarg` and `:accessor` slot options will also be
-  automatically generated.
-
-  Example:
-
-    (define-aspect edible
-      energy
-      (taste :initform nil))
-    =>
-    (defclass edible ()
-      ((edible/energy :initarg :edible/energy
-                      :accessor edible/energy)
-       (edible/taste :initarg :edible/taste
-                     :accessor edible/taste
-                     :initform nil)))
-
-  
-
-### `DEFINE-ENTITY` (macro)
-
-    (DEFINE-ENTITY NAME ASPECTS &REST SLOTS)
-
-Define an entity class.
-
-  `name` should be a symbol that will become the name of the class.
-
-  `aspects` should be a list of the aspects this entity should inherit from.
-
-  `slots` can be zero or more extra CLOS slot definitions.
-
-  Examples:
-
-    (define-entity potion (drinkable))
-
-    (define-entity cheese (edible visible)
-      (flavor :accessor cheese-flavor :initarg :flavor))
-
-  
-
-### `DEFINE-SYSTEM` (macro)
-
-    (DEFINE-SYSTEM NAME-AND-OPTIONS
-        ARGLIST
-      &BODY
-      BODY)
-
-Define a system.
-
-  `name-and-options` should be a list of the system name (a symbol) and any
-  system options.  A bare symbol can be used if no options are needed.
-
-  `arglist` should be a list of system arguments.  Each argument should be
-  a list of the argument name and zero or more aspect/entity classes.
-
-  Defining a system `foo` defines two functions:
-
-  * `foo` runs `body` on a single entity and should only be used for debugging,
-    tracing, or disassembling.
-  * `run-foo` should be called to run the system on all applicable entities.
-
-  Available system options:
-
-  * `:inline`: when true, try to inline the system function into the
-    system-running function to avoid the overhead of a function call for every
-    entity.  Defaults to `nil`.
-
-  Examples:
-
-    (define-system age ((entity lifetime))
-      (when (> (incf (lifetime/age entity))
-               (lifetime/lifespan entity))
-        (destroy-entity entity)))
-
-  
-
-### `DESTROY-ENTITY` (function)
-
-    (DESTROY-ENTITY ENTITY)
-
-Destroy `entity` and return it.
-
-  The `entity-destroyed` generic function will be called after the entity has
-  been destroyed and unindexed.
-
-  
-
-### `ENTITY` (class)
-
-A single entity in the game world.
-
-#### Slot `ID`
-
-* Allocation: `:INSTANCE`
-* Initform: `(INCF BEAST::*ENTITY-ID-COUNTER*)`
-* Reader: `ENTITY-ID`
-
-The unique ID of the entity.  This may go away in the future.
-
-#### Slot `%BEAST/ASPECTS`
-
-* Allocation: `:CLASS`
-* Initform: `NIL`
-
-A list of the aspects this entity class inherits.  **Don't touch this.**
-
-### `ENTITY-CREATED` (generic function)
-
-    (ENTITY-CREATED ENTITY)
-
-Called after an entity has been created and indexed.
-
-  The default method does nothing, but users can implement their own auxillary
-  methods to run code when entities are created.
-
-  
-
-### `ENTITY-DESTROYED` (generic function)
-
-    (ENTITY-DESTROYED ENTITY)
-
-Called after an entity has been destroyed and unindexed.
-
-  The default method does nothing, but users can implement their own auxillary
-  methods to run code when entities are destroyed.
-
-  
-
-### `MAP-ENTITIES` (function)
-
-    (MAP-ENTITIES FUNCTION &OPTIONAL (TYPE 'ENTITY))
-
-Map `function` over all entities that are subtypes of `type`.
-
-  Normally you should run code on entities using systems, but this function can
-  be handy for debugging purposes.
-
-  
-
diff -r d337c4b0c165 -r a7af1952d336 docs/05-changelog.markdown
--- a/docs/05-changelog.markdown	Thu Sep 08 14:12:48 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-Changelog
-=========
-
-Here's the list of changes in each released version.
-
-[TOC]
-
-v1.0.0
-------
-
-Initial version.  It works, but changes may happen in the future.
diff -r d337c4b0c165 -r a7af1952d336 docs/api.lisp
--- a/docs/api.lisp	Thu Sep 08 14:12:48 2016 +0000
+++ b/docs/api.lisp	Tue Nov 08 13:27:17 2016 +0000
@@ -4,7 +4,7 @@
   (list "BEAST"))
 
 (defparameter *output-path*
-  #p"docs/04-reference.markdown" )
+  #p"docs/03-reference.markdown" )
 
 (defparameter *header*
   "The following is a list of all user-facing parts of Beast.
diff -r d337c4b0c165 -r a7af1952d336 docs/index.markdown
--- a/docs/index.markdown	Thu Sep 08 14:12:48 2016 +0000
+++ b/docs/index.markdown	Tue Nov 08 13:27:17 2016 +0000
@@ -2,6 +2,10 @@
 Lisp.  It's a thin layer of sugar over CLOS that makes it easy to write flexible
 objects for video games.
 
+Beast can be installed with [Quicklisp][]:
+
+    (ql:quickload :beast)
+
 Check out the [Overview](./overview/) for a three-minute description of what
 this is, or the [Usage](./usage/) for a full rundown.
 
@@ -12,3 +16,5 @@
 
 The test suite currently passes in SBCL, CCL, ECL, and ABCL on OS X and Debian.
 Further testing is welcome.
+
+[quicklisp]: https://quicklisp.org/