--- 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
--- 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/
--- 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
--- /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.
--- 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.
--- /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/).
--- /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.
+
+
+
--- 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/).
--- /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.
--- 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.
-
-
-
--- 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.
--- 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.
--- 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/