Next: Introduction, Previous: (dir), Up: (dir) [Contents][Index]
This is the escalator Reference Manual, version 0.0, generated automatically by Declt version 4.0 beta 2 "William Riker" on Mon Aug 15 04:30:26 2022 GMT+0.
Next: Systems, Previous: The escalator Reference Manual, Up: The escalator Reference Manual [Contents][Index]
Escalator, aka Entity System for Common Lisp (ESCL), is an experimental object system intended to make it easy to develop high-performance games. ESCL was inspired by this blog post, which outlines the purpose and structure of entity systems and suggests implementations for C++ and SQL. ESCL attempts provide an idiomatic implementation of entity systems for Common Lisp as a high-performance alternative to CLOS.
ESCL is still very experimental, and is not ready for production use. I have not spent much time optimizing it, although it is my hope that it will eventually perform much better than CLOS. My initial micro-benchmarks indicate that ESCL may be up to 50% faster than CLOS for certain kinds of operations. (Note that micro-benchmarks in general are problematic, and mine specifically are probably not very representative, so please take these numbers with a grain of salt.)
For the moment, ESCL isn't stable enough for official releases, so please clone the repository (see above) or download a tarball of master to get the source code. ESCL currently depends on iterate, so be sure to install that too.
In ESCL, entity systems are made of three types of constructs: components, systems, and entities. While there are some parallels between these constructs and those provided by CLOS and traditional object systems, the differences are fundamental enough that it might help to avoid thinking about entity systems in the context of existing object systems.
(defcomponent component-name (&rest dependencies)
(&rest fields))
component-name
is a symbol which specifies the name of the component.dependencies
is a list of names of components upon which this component
depends (see discussion below).fields
is a list of symbols which specify fields in this
component. Fields should not be defined multiple times in different
components: ESCL does not combine fields the way CLOS automatically
combines slots. For each field, defcomponent
automatically defines
accessor macros under the same names which can be used to access the
fields.nil
. Macro has compile-time side effects.(defsystem component-name (entity-var component-var &rest dependency-vars)
&body body)
component-name
is a symbol which specifies the component for which this
system is being defined.entity-var
will be bound to each entity which has the component named
component-name
.component-var
will be bound to the component data for each entity. The
macros defined for the fields above can be used on this variable to access
the individual fields for this entity.dependency-vars
will be bound to the dependencies for each entity. If a
dependency is only a computation dependency and not a data dependency,
that variable can be made nil
.body
is a block of code which will be executed for each entity in the
system. (See discussion on the system loop below.)nil
. Macro has compile-time side effects.(make-entity prototype components &rest initargs)
prototype
is used as the initial basis for this entity. Each component
associated with prototype
is copied into the new entity before adding
new components in components
. Use nil
to specify no prototype.components
is a list of new components to add to this entity.initargs
is a plist of values used to initialize fields, similar to the
CLOS initargs
parameter to make-instance
. Each field is automatically
defined to have a keyword initarg by the same name.(system-loop)
nil
. Macro inserts the combined code for add systems which have
been defined. The order which systems execute is determined by
constructing a total ordering of the components based on their
dependencies. (Dependencies execute before systems that depend on them.)
Each system iterates over all entities which have the associated
component. This is macro is intended to be used in constructing the main
loop of the application.(defcomponent point ()
(x y z))
(defcomponent velocity (point)
(vx vy vz))
(defsystem point (entity point)
(format t "entity ~a at position (~a, ~a, ~a)~%" entity (x point) (y point) (z point)))
(defsystem velocity (entity velocity point)
(incf (x point) (vx velocity))
(incf (y point) (vy velocity))
(incf (z point) (vz velocity)))
(make-entity nil '(point) :x 1 :y 2 :z 3)
(make-entity nil '(point velocity) :x 4 :y 5 :z 6 :vx -1 :vy -2 :vz -3)
(loop repeat 10 do (system-loop))
Output:
entity 1 at position (1, 2, 3)
entity 2 at position (4, 5, 6)
entity 1 at position (1, 2, 3)
entity 2 at position (3, 3, 3)
entity 1 at position (1, 2, 3)
entity 2 at position (2, 1, 0)
entity 1 at position (1, 2, 3)
entity 2 at position (1, -1, -3)
entity 1 at position (1, 2, 3)
entity 2 at position (0, -3, -6)
entity 1 at position (1, 2, 3)
entity 2 at position (-1, -5, -9)
entity 1 at position (1, 2, 3)
entity 2 at position (-2, -7, -12)
entity 1 at position (1, 2, 3)
entity 2 at position (-3, -9, -15)
entity 1 at position (1, 2, 3)
entity 2 at position (-4, -11, -18)
entity 1 at position (1, 2, 3)
entity 2 at position (-5, -13, -21)
Next: Modules, Previous: Introduction, Up: The escalator Reference Manual [Contents][Index]
The main system appears first, followed by any subsystem dependency.
An experimental object system for high-performance games.
Elliott Slaughter <elliottslaughter@gmail.com>
MIT
0.0
iterate (system).
src (module).
Next: Files, Previous: Systems, Up: The escalator Reference Manual [Contents][Index]
Modules are listed depth-first from the system components tree.
escalator (system).
Next: Packages, Previous: Modules, Up: The escalator Reference Manual [Contents][Index]
Files are sorted by type and then listed depth-first from the systems components trees.
Next: escalator/src/package.lisp, Previous: Lisp, Up: Lisp [Contents][Index]
escalator (system).
Next: escalator/src/entity.lisp, Previous: escalator/escalator.asd, Up: Lisp [Contents][Index]
src (module).
Previous: escalator/src/package.lisp, Up: Lisp [Contents][Index]
package.lisp (file).
src (module).
Next: Definitions, Previous: Files, Up: The escalator Reference Manual [Contents][Index]
Packages are listed by definition order.
Previous: escalator-asd, Up: Packages [Contents][Index]
escl
Next: Indexes, Previous: Packages, Up: The escalator Reference Manual [Contents][Index]
Definitions are sorted by export status, category, package, and then by lexicographic order.
Next: Internals, Previous: Definitions, Up: Definitions [Contents][Index]
Next: Ordinary functions, Previous: Public Interface, Up: Public Interface [Contents][Index]
Defines a new component with the given dependencies and fields.
Internal:
* Error if name isn’t a non-nil symbol.
* Error if dependencies contains a non-symbol or nil.
* Error if fields contains a non-symbol or nil.
* Error if dependency doesn’t exist.
* Error if dependencies include self.
* Error if dependencies cause cycle in component precendence list.
* Warn on redefinition of component.
* Warn if field hides a previously defined field for any component.
* Adds component entry to *component-meta*
(name -> deps * fields * initargs * size).
* Defines macros for each field accessor.
* Initializes global hash-table for component in *component-data*.
Defines a system for the given component.
Internal:
* Error if name, entity, and component aren’t non-nil symbols.
* Error if dependencies aren’t symbols (nil allowed).
* Error if name doesn’t refer to a defined component.
* Error if number of dependencies doesn’t match component.
* Warns on redefinition of system.
* Stores code to operate on component data.
Previous: Macros, Up: Public Interface [Contents][Index]
Returns the component instance for entity or nil.
Instantiates an entity from the given prototype (shallow copy) and
additionally associated with the specified components.
Internal:
* Error if any component doesn’t exist.
* Enforce uniqueness of components by pushing into a new list.
* Shallow copy prototype components.
* Instantiate new components (overwrite if they already exist).
* Copy references to dependencies (error if it doesn’t exist).
Previous: Public Interface, Up: Definitions [Contents][Index]
Next: Ordinary functions, Previous: Internals, Up: Internals [Contents][Index]
Previous: Special variables, Up: Internals [Contents][Index]
Previous: Definitions, Up: The escalator Reference Manual [Contents][Index]
Jump to: | (
C D E F M N P S T |
---|
Jump to: | (
C D E F M N P S T |
---|
Next: Data types, Previous: Functions, Up: Indexes [Contents][Index]
Jump to: | *
S |
---|
Jump to: | *
S |
---|
Jump to: | E F M P S |
---|
Jump to: | E F M P S |
---|