Coder Social home page Coder Social logo

pecs's Introduction


PECS

Entity Component System (ECS) for PICO-8 & Picotron in 567 tokens.
(Based on KatrinaKitten's excellent Tiny ECS Framework v1.1)



Usage

Everything is part of a World. Create one with pecs():

local world = pecs()

Components describe data containers that can be instantiated:

local Position = world.component()
local Velocity = world.component()

An Entity is a collection of instantiated Components.

local player = world.entity()
player += Position({ x=10, y=0 })
player += Velocity({ x=0, y=1 })

All data within an Entity can be accessed as long as you know the Component it belongs to:

print(player[Position].x, 10, 10, 7)

Systems allow specifying game logic (as a function) which applies to Entities that have a certain set of Components (ie; a filter).

The game logic function of a System is executed once per matched Entity, ensuring performance is maintained when there are many entities. The function receives any arguments passed when calling the method. Useful for passing in elapsed time, etc.

local move = world.system({ Position, Velocity }, function(entity, ticks)
  entity[Position].x += entity[Velocity].x * ticks
  entity[Position].y += entity[Velocity].y * ticks
end)

-- Run the system method against all matched entities
-- Any args passed will be available in the system callback function
local ticks = 1
move(ticks)

Example

local world = pecs()

local Position = world.component()
local Velocity = world.component()

local player = world.entity({ name="Jess" })

player += Position({ x=10, y=0 })
player += Velocity({ x=0, y=1 })

local move = world.system({ Position, Velocity }, function(entity, ticks)
  entity[Position].x += entity[Velocity].x * ticks
  entity[Position].y += entity[Velocity].y * ticks
end)

local lastTime = time()
function _update()
  move(time() - lastTime)
  lastTime = time()
end

function _draw()
  cls()
  print(player[Position].x.." "..player[Position].y, 10, 10, 7)
end

For more complete & practical examples, see the example/ folder:

  • example/particles.p8: A Particle Emitter showing how to spawn entities and adding/removing components (the type of Emitter) on a button press.
  • example/camera-follow.p8: A camera follow/window technique built using Components & Systems. This example has a visual representation of the "camera" to see the effect.

API

pecs() => World

Everything in PECS happens within a world.

Can be called multiple times to create multiple worlds:

local world1 = pecs()
local world2 = pecs()

Each world has its own Components and Entities.

World#update()

Must be called at the start of each _update() before anything else.

World#entity([attr[, Component, ...]]) => Entity

local player = world.entity()

local trap = world.entity({ type="spikes" })

local enemy = world.entity({}, Position({ x=10, y=10 }), Rotation({ angle=45 })
Adding a Component to an Entity
player += Position({ x=100, y=20 })
Removing a Component from an Entity
player -= Position

World#component([defaults]) => Component

local Position = world.component()

local Drawable = world.component({ color: 8 })

World#system(filter, callback) => Function

Where filter is a table of Components, and callback is a function that's passed the entity to operate on.

Returns a function that when called will execute the callback once per Entity that contains all the specified Components.

When executing the function, any parameters are passed through to the callback.

local move = world.system({ Position, Velocity }, function(entity, ticks)
  entity[Position].x += entity[Velocity].x * ticks
  entity[Position].y += entity[Velocity].y * ticks
end)

-- Run the system method against all matched entities
-- Any args passed will be available in the system callback function
local ticks = 1
move(ticks)

Systems efficiently maintain a list of filtered entities that is only updated when needed. It is safe to create many systems that operate over large lists of Entities (within PICO-8's limits).

World#query(filter) => Table<Entity>

โš ๏ธ It is recommended to use World#system (which calls query internally).

Where filter is a table of Components, eg; { Position, Velocity }.

Return a reference to a filtered table of Entitys. The table is automatically updated when new entities match or old entities no longer match. Modifying this table can cause Systems to misbehave; treat it as read-only.

local entities = world.query({ Position })
for _, ent in pairs(entities) do
  printh(ent[Position].x .. "," ..ent[Position].y)
end

Queries efficiently maintain a list of filtered entities that is only updated when needed. It is safe to create many queries that operate over large lists of Entities (within PICO-8's limits).

World#remove(Entity)

Remove the given entity from the world.

Any Systems or Queries which previously matched this entity will no longer operate on it.

World#queue(Function)

Useful for delaying actions until the next turn of the update loop. Particularly when the action would modify a list that's currently being iterated on such as removing an item due to collision, or spawning new items.

pecs's People

Contributors

jesstelford avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

p01 josiebb tanyyt

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.