mirror of
https://github.com/Keyslam-Group/Concord.git
synced 2025-09-02 04:13:58 -04:00
Finish first version of documentation
This commit is contained in:
parent
cf51bccb81
commit
3b52f28fe0
1 changed files with 234 additions and 11 deletions
243
README.md
243
README.md
|
@ -9,6 +9,25 @@ This readme will explain how to use Concord.
|
||||||
Additionally all of Concord is documented using the LDoc format.
|
Additionally all of Concord is documented using the LDoc format.
|
||||||
Auto generated docs for Concord can be found in `docs` folder, or on the [Github page](https://tjakka5.github.io/Concord/).
|
Auto generated docs for Concord can be found in `docs` folder, or on the [Github page](https://tjakka5.github.io/Concord/).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
[Installation](#installation)
|
||||||
|
[ECS](#ecs)
|
||||||
|
[API](#api) :
|
||||||
|
- [Components](#components)
|
||||||
|
- [Entities](#entities)
|
||||||
|
- [Systems](#systems)
|
||||||
|
- [Worlds](#worlds)
|
||||||
|
- [Assemblages](#assemblages)
|
||||||
|
|
||||||
|
[Quick Example](#quick-example)
|
||||||
|
[Contributors](#contributors)
|
||||||
|
[License](#licence)
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
Download the repository and copy the 'src' folder in your project. Rename it to something that makes sense (Probably 'concord'), then require it in your project like so:
|
Download the repository and copy the 'src' folder in your project. Rename it to something that makes sense (Probably 'concord'), then require it in your project like so:
|
||||||
```lua
|
```lua
|
||||||
|
@ -32,6 +51,8 @@ local Worlds = Concord.worlds
|
||||||
local Assemblages = Concord.assemblages
|
local Assemblages = Concord.assemblages
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## ECS
|
## ECS
|
||||||
Concord is an Entity Component System (ECS for short) library.
|
Concord is an Entity Component System (ECS for short) library.
|
||||||
This is a coding paradigm where _composition_ is used over _inheritance_.
|
This is a coding paradigm where _composition_ is used over _inheritance_.
|
||||||
|
@ -104,13 +125,16 @@ Or what if the enemy shot bullets with a `health` Component? It would create bul
|
||||||
|
|
||||||
And all that without writing a single extra line of code. Just reusing code that already existed and is guaranteed to be reuseable.
|
And all that without writing a single extra line of code. Just reusing code that already existed and is guaranteed to be reuseable.
|
||||||
|
|
||||||
## Documentation
|
---
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
### General design
|
### General design
|
||||||
|
|
||||||
#### Classes
|
|
||||||
Concord does a few things that might not be immediately clear. This segment should help understanding.
|
Concord does a few things that might not be immediately clear. This segment should help understanding.
|
||||||
|
|
||||||
|
#### Classes
|
||||||
|
|
||||||
When you define a Component or System you are actually defining a `ComponentClass` and `SystemClass` respectively. From these instances of them can be created. They also act as identifiers for Concord.
|
When you define a Component or System you are actually defining a `ComponentClass` and `SystemClass` respectively. From these instances of them can be created. They also act as identifiers for Concord.
|
||||||
|
|
||||||
For example. If you want to get a specific Component from an Entity, you'd do `Component = Entity:get(ComponentClass)`.
|
For example. If you want to get a specific Component from an Entity, you'd do `Component = Entity:get(ComponentClass)`.
|
||||||
|
@ -147,6 +171,26 @@ local componentName_class = Components.componentName
|
||||||
|
|
||||||
All the above applies the same to all the other containers.
|
All the above applies the same to all the other containers.
|
||||||
|
|
||||||
|
#### Method chaining
|
||||||
|
```lua
|
||||||
|
-- All functions that do something ( eg. Don't return anything ) will return self
|
||||||
|
-- This allowes you to chain methods
|
||||||
|
|
||||||
|
entity
|
||||||
|
:give(position, 100, 50)
|
||||||
|
:give(velocity, 200, 0)
|
||||||
|
:remove(position)
|
||||||
|
:destroy()
|
||||||
|
|
||||||
|
--
|
||||||
|
|
||||||
|
world
|
||||||
|
:addEntity(fooEntity)
|
||||||
|
:addEntity(barEntity)
|
||||||
|
:clear()
|
||||||
|
:emit("test")
|
||||||
|
```
|
||||||
|
|
||||||
### Components
|
### Components
|
||||||
When defining a ComponentClass you usually pass in a `populate` function. This will fill the Component with values.
|
When defining a ComponentClass you usually pass in a `populate` function. This will fill the Component with values.
|
||||||
|
|
||||||
|
@ -166,10 +210,10 @@ local pushableComponentClass = Concord.component()
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
-- Manually register the Component to the container if we want
|
-- Manually register the ComponentClass to the container if we want
|
||||||
Concord.components.register("positionComponent", positionComponentClass)
|
Concord.components.register("positionComponent", positionComponentClass)
|
||||||
|
|
||||||
-- Otherwise return the Component so it can be required
|
-- Otherwise return the ComponentClass so it can be required
|
||||||
return positionComponentClass
|
return positionComponentClass
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -283,10 +327,10 @@ local mySystemClass = Concord.system(
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
-- Manually register the Component to the container if we want
|
-- Manually register the SystemClass to the container if we want
|
||||||
Concord.system.register("mySystem", mySystemClass)
|
Concord.system.register("mySystem", mySystemClass)
|
||||||
|
|
||||||
-- Otherwise return the Component so it can be required
|
-- Otherwise return the SystemClass so it can be required
|
||||||
return mySystemClass
|
return mySystemClass
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -350,15 +394,192 @@ local world = System:getWorld()
|
||||||
|
|
||||||
### Worlds
|
### Worlds
|
||||||
|
|
||||||
TODO
|
Worlds are the thing your System and Entities live in.
|
||||||
|
With Worlds you can `:emit` a callback. All Systems with this callback will then be called.
|
||||||
|
|
||||||
|
Worlds can have 1 instance of every SystemClass.
|
||||||
|
Worlds can have any number of Entities.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
-- Create World
|
||||||
|
local myWorld = Concord.world()
|
||||||
|
```
|
||||||
|
|
||||||
|
```lua
|
||||||
|
-- Manually register the World to the container if we want
|
||||||
|
Concord.worlds.register("myWorld", myWorld)
|
||||||
|
|
||||||
|
-- Otherwise return the World so it can be required
|
||||||
|
return myWorld
|
||||||
|
```
|
||||||
|
|
||||||
|
```lua
|
||||||
|
-- Add an Entity to the World
|
||||||
|
myWorld:addEntity(myEntity)
|
||||||
|
|
||||||
|
-- Remove an Entity from the World
|
||||||
|
myWorld:removeEntity(myEntity)
|
||||||
|
```
|
||||||
|
|
||||||
|
```lua
|
||||||
|
-- Add a System to the World
|
||||||
|
myWorld:addSystem(mySystemClass)
|
||||||
|
|
||||||
|
-- Add multiple Systems to the World
|
||||||
|
myWorld:addSystems(moveSystemClass, renderSystemClass, controlSystemClass)
|
||||||
|
```
|
||||||
|
|
||||||
|
```lua
|
||||||
|
-- Check if the World has a System
|
||||||
|
local hasSystem = myWorld:hasSystem(mySystemClass)
|
||||||
|
|
||||||
|
-- Get a System from the World
|
||||||
|
local mySystem = myWorld:getSystem(mySystemClass)
|
||||||
|
```
|
||||||
|
|
||||||
|
```lua
|
||||||
|
-- Emit an event
|
||||||
|
|
||||||
|
-- This will call the 'update' function of any added Systems
|
||||||
|
-- They will be called in the order they were added
|
||||||
|
myWorld:emit("update", dt)
|
||||||
|
|
||||||
|
-- You can emit any event with any parameters
|
||||||
|
myWorld:emit("customCallback", 100, true, "Hello World")
|
||||||
|
```
|
||||||
|
|
||||||
|
```lua
|
||||||
|
-- Remove all Entities from the World
|
||||||
|
myWorld:clear()
|
||||||
|
```
|
||||||
|
|
||||||
|
```lua
|
||||||
|
-- Override-able callbacks
|
||||||
|
|
||||||
|
-- Called when an Entity is added to the World
|
||||||
|
-- e is the Entity added
|
||||||
|
function myWorld:onEntityAdded(e)
|
||||||
|
-- Do something
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Called when an Entity is removed from the World
|
||||||
|
-- e is the Entity removed
|
||||||
|
function myWorld:onEntityRemoved(e)
|
||||||
|
-- Do something
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
### Assemblages
|
### Assemblages
|
||||||
|
|
||||||
TODO
|
Assemblages are helpers to 'make' Entities something.
|
||||||
|
An important distinction is that they _append_ Components.
|
||||||
|
|
||||||
### Type
|
```lua
|
||||||
|
-- Make an Assemblage
|
||||||
|
-- e is the Entity being assembled.
|
||||||
|
-- cuteness and legs are variables passed in
|
||||||
|
local animalAssemblage(function(e, cuteness, legs)
|
||||||
|
e
|
||||||
|
:give(cutenessComponentClass, cuteness)
|
||||||
|
:give(limbs, legs, 0) -- Variable amount of legs. 0 arm.
|
||||||
|
end)
|
||||||
|
|
||||||
TODO
|
-- Make an Assemblage that used animalAssemblage
|
||||||
|
-- cuteness is a variables passed in
|
||||||
|
local catAssemblage(function(e, cuteness)
|
||||||
|
e
|
||||||
|
:assemble(animalAssemblage, cuteness * 2, 4) -- Cats are twice as cute, and have 4 legs.
|
||||||
|
:give(soundComponent, "meow.mp3")
|
||||||
|
end)
|
||||||
|
```
|
||||||
|
|
||||||
|
```lua
|
||||||
|
-- Use an Assemblage
|
||||||
|
myEntity:assemble(catAssemblage, 100) -- 100 cuteness
|
||||||
|
-- or
|
||||||
|
catAssemblage:assemble(myEntity, 100) -- 100 cuteness
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Quick Example
|
||||||
|
```lua
|
||||||
|
local Concord = require("concord")
|
||||||
|
|
||||||
|
-- Defining ComponentClasses
|
||||||
|
-- I use UpperCamelCase to indicate its a class
|
||||||
|
local Position = Concord.component(function(c, x, y)
|
||||||
|
c.x = x or 0
|
||||||
|
c.y = y or 0
|
||||||
|
end)
|
||||||
|
|
||||||
|
local Velocity = Concord.component(function(c, x, y)
|
||||||
|
c.x = x or 0
|
||||||
|
c.y = y or 0
|
||||||
|
end)
|
||||||
|
|
||||||
|
local Drawable = Concord.component()
|
||||||
|
|
||||||
|
|
||||||
|
-- Defining Systems
|
||||||
|
local MoveSystem = Concord.system({Position, Velocity})
|
||||||
|
|
||||||
|
function MoveSystem:update(dt)
|
||||||
|
for _, e in ipairs(self.pool) do
|
||||||
|
-- I use lowerCamelCase to indicate its an instance
|
||||||
|
local position = e[Position]
|
||||||
|
local velocity = e[Velocity]
|
||||||
|
|
||||||
|
position.x = position.x + velocity.x * dt
|
||||||
|
position.y = position.y + velocity.y * dt
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local DrawSystem = Concord.System({Position, Drawable})
|
||||||
|
|
||||||
|
function DrawSystem:draw()
|
||||||
|
for _, e in ipairs(self.pool) do
|
||||||
|
local position = e[Position]
|
||||||
|
|
||||||
|
love.graphics.circle("fill", position.x, position.y, 5)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Create the World
|
||||||
|
local world = World()
|
||||||
|
|
||||||
|
-- Add the Systems
|
||||||
|
world:addSystems(MoveSystem, DrawSystem)
|
||||||
|
|
||||||
|
-- This Entity will be rendered on the screen, and move to the right at 100 pixels a second
|
||||||
|
local entity_1 = Concord.entity(world)
|
||||||
|
:give(Position, 100, 100)
|
||||||
|
:give(Velocity, 100, 0)
|
||||||
|
:give(Drawable)
|
||||||
|
|
||||||
|
-- This Entity will be rendered on the screen, and stay at 50, 50
|
||||||
|
local entity_2 = Concord.entity(world)
|
||||||
|
:give(Position, 50, 50)
|
||||||
|
:give(Drawable)
|
||||||
|
|
||||||
|
-- This Entity does exist in the World, but since it doesn't match any System's filters it won't do anything
|
||||||
|
local entity_2 = Concord.entity(world)
|
||||||
|
:give(Position, 200, 200)
|
||||||
|
|
||||||
|
|
||||||
|
-- Emit the events
|
||||||
|
function love.update(dt)
|
||||||
|
world:emit(dt)
|
||||||
|
end
|
||||||
|
|
||||||
|
function love.draw()
|
||||||
|
world:draw()
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Contributors
|
## Contributors
|
||||||
- __Positive07__: Constant support and a good rubberduck
|
- __Positive07__: Constant support and a good rubberduck
|
||||||
|
@ -368,5 +589,7 @@ TODO
|
||||||
- __Speak__: Lots of testing for new features of Concord
|
- __Speak__: Lots of testing for new features of Concord
|
||||||
- __Tesselode__: Brainstorming and helpful support
|
- __Tesselode__: Brainstorming and helpful support
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Licence
|
## Licence
|
||||||
MIT Licensed - Copyright Justin van der Leij (Tjakka5)
|
MIT Licensed - Copyright Justin van der Leij (Tjakka5)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue