Page 1 of 5

[Library] tiny-ecs - Fast Simple Entity Component System

Posted: Sun Mar 29, 2015 1:17 pm
by bakpakin
tiny-ecs: Make Games Faster

CODE
API
COPY/PASTE SOURCE

What is this?

tiny-ecs is a Lua module for implementing entity component systems (ECS) in a fast and flexible way. For those unfamiliar with ECS, I recommend reading the wikipedia page on it. It's the hip, cool, and not-so-new trend in how to structure a game. This should make your games easier to extend, reason about, and scale.

Why?

One of LOVE's greatest strengths and also greatest weaknesses is a lack of defined structure for games. You're just given library calls, a few callbacks to build off of, and told to get going. Without some structure, it's hard to make a medium sized game, let alone a large or marketable product. tiny-ecs is a framework / library that facilitates proven and intelligent ways to structure games.

How?

So I was making a game, and I did what probably every developer and hobbyist has done at some point, and I started making a library rather than a game. :crazy: I made another Entity Component System for Lua (not just LOVE), because all the other's that I found online were either unsatisfactory or not good enough do dissuade me from making my own. I've seen a couple (Fez) around here, but they seem to be mostly ports of things like Artemis, which is a poor fit for Lua IMHO. I spent a few days making a complete library with documentation, and tiny-ecs was born. I've since put some effort into updating it and adding new features.

Demos

I personally have used tiny-ecs in two Ludum Dares successfully. I evolved the syntax and capabilities of tiny-ecs as I realized how I liked to use it and I realized how other people used it. Keep in mind that the demo code is not always a pure example of entity component systems; they are practical examples that show ONE WAY how to use tiny-ecs to make a game. I am sure there is impractical code aplenty in the demos, but don't worry - tiny-ecs.lua itself has much cleaner code.

Also keep in mind that the demos may be using an older version of tiny-ecs that is slightly different than the current one. When there is a disagreement between the API and a demo, the API wins.

DEMO1 - COMMANDO KIBBLES
DEMO2 - WEREGOAT

Feedback is appreciated. :awesome:

Re: tiny-ecs - Another Entity Component System

Posted: Sun Mar 29, 2015 1:48 pm
by Snuux
Nice! I'm like entity-based game structure. Good luck with this lib.

Re: tiny-ecs - Another Entity Component System

Posted: Mon Apr 06, 2015 9:52 pm
by SiENcE
Nice. I have to take a look into it. I also wanted to make my own component system, but i' currently doing a game ;-).

Re: tiny-ecs - Another Entity Component System

Posted: Mon Apr 20, 2015 8:52 am
by bakpakin
I just finished my game for Ludum Dare 32 using tiny-ecs, bump.lua, Simple Tiled Implentation, and several other libraries. Tiny-ecs worked very well, and allowed me to use a class system (30log) on top of the entity Component System. I know that's not really how Entity Component Systems are supposed to work, but it worked well for me. Infact, I just used classes like typical oo, added my instances to the world, and tiny-ecs processed them accordingly. The syntax for creating reusable systems, however, I think is rather ugly, and I may look into that. I want to tiny-ecs to be as flexible as possible, but without assuming or forcing a class system. The game is not exactly fun, but the mechanics are clean and fast. Big shoutout to bump.lua, which is really awesome, and to Simple Tiled Implementation.

Here's the game, and the source can be found at https://github.com/bakpakin/CommandoKibbles.

Re: tiny-ecs - Another Entity Component System

Posted: Mon Apr 20, 2015 12:23 pm
by SiENcE
Nice and good that you used your own library in a field test :). I also used my gametemplate and found some bugs and possible enhancements.

Re: tiny-ecs - Another Entity Component System

Posted: Sun Apr 26, 2015 4:09 am
by bakpakin
Just put tiny-ecs on https://luarocks.org/. Also, I have been updating the library even more, making it faster, cleaner, and improving the syntax. The syntax should be pretty stable now, but I want to add more different types of systems (and examples, of course). :awesome:

Re: tiny-ecs - Another Entity Component System

Posted: Mon Apr 27, 2015 6:41 am
by bakpakin
I just put my example game, Command Kibbles, in the github repository. I've also updated to include the post-compo version of tiny-ecs. The system code is now cleaner, and was very easy to port from the old syntax. Now, almost the entire game is based of 30log classes, and I could easily use middleclass or any other framework if I wanted to.

Tiny-ecs is also now quite performant, and iterates through entities as fast as any other framework, or faster. Adding and Removing Systems and Entities is as fast as I can get up it without injecting ids into Entities, which I don't want to do as Entities should just be arbitrary tables. I haven't done any profiling, but the demo performs quite well, even when I add lots of Entities. Safe to say, all operations with Entities are constant time.

Re: [Library] tiny-ecs - Fast Simple Entity Component System

Posted: Thu Aug 27, 2015 5:27 am
by WetDesertRock
Sorry for the gravedig, but as I'm interested in using ecs and learning more about it, I have a few questions.

How does a separation between update and draw get handled? Just different systems with different indices?

I noticed in the example you used a combination of systems and entity methods to do the logic. Slightly confused why someone may do this, is it just sloppy programming, or are the entity methods used because they are specific to that one entity and nothing else?

When filters are used, does it cache the results? For example, if I had a fadeout system that required "fadeout" and "opacity", would just adding those fields to an entity cause it to start using the fadeout system?

Re: [Library] tiny-ecs - Fast Simple Entity Component System

Posted: Thu Aug 27, 2015 8:12 am
by shakesoda
WetDesertRock wrote:When filters are used, does it cache the results? For example, if I had a fadeout system that required "fadeout" and "opacity", would just adding those fields to an entity cause it to start using the fadeout system?
Filters aren't updated until you cycle an entity in the world (i.e. world:removeEntity(foo); world:addEntity(foo)) - although I'd very much like a world:modifyEntity as well which indicates an entity getting new components without being removed (I've got some systems which make/remove caches on add/remove - and cycling the entity means losing their data)

Re: [Library] tiny-ecs - Fast Simple Entity Component System

Posted: Thu Aug 27, 2015 2:40 pm
by bakpakin
Filters do cache results for preformance reasons; systems that iterate through entities only iterate through a sequence when they update. Unless you add or remove a lot of entities every update cycle, there is very little overhead. In fact, a vanilla 'tiny.system' doesn't even iterate through it's entities by default, it just calls its 'update' function.

As for my example, it is a little bit of sloppy programming (considering that game was made in 48 for a game jam), but also an acknowledgement that sometimes entity methods are just easier than systems. This hybrid approach is actually what is used in many major game engines, like Unity. If I had more time and needed to scale the project more, I would moved more logic to systems and out of the the entities. tiny-ecs is completely compatible with most major Lua class systems including middleclass and 30log, to name two, so entity methods don't interfere with other more traditional system based logic. This one of the benefits of a dynamic language, as I see it.

shakesoda is correct in saying that caches aren't updated every frame for already existing entities. Right now, you just re-add entities to the world to update them if you add or remove components that would make them valid or invalid for certain systems. shakesoda's suggestion is valid, however.

Example on how to change an entities components:

Code: Select all

myEntity.newComponent = {1, 3, 5, 7, 42}
myEntity.oldComponent = nil

-- re-add myEntity to the World to refresh caches for that entity.
world:add(myEntity)
Separating drawing and update logic is another thing I added after the fact. In LOVE, you don't actually have to separate them (you could just put all of your update logic in love.draw), but it's often useful to make SURE that your update code gets called before your draw code. tiny.update takes an optional parameter after deltaTime called 'filter' that only selects certain systems. you can make two different filters for updateSystems and drawSystems and update only the correct systems in love.update and love.draw.

Code: Select all

-- Create drawing systems
myDrawSystem = tiny.system({isDrawingSystem = true})
myDrawSystem2 = tiny.system({isDrawingSystem = true})

-- Create update systems
myUpdateSystem = tiny.system()
myUpdateSystem2 = tiny.system()

-- Make system filters
drawSystemFilter = tiny.requireAll("isDrawingSystem")
updateSystemFilter = tiny.rejectAll("isDrawingSystem")

-- Initialize world
world = tiny.world(myDrawSystem, myDrawSystem2, myUpdateSystem, myUpdateSystem2)

function love.update(dt)
   world:update(dt, updateSystemFilter)
end

function love.draw()
   world:update(love.timer.getDelta(), drawSystemFilter)
end

In the above example, Update Systems will be called love.update, and Drawing Systems in love.draw.

For more info and examples, check the api here, and a newer example here. In the newer example in particular, check love.update and love.draw in main.lua for an example on how to separate update and draw systems. I do apologize, however, for the messy code.

Hope that helps and is not too confusing.

As its seems a few people are using tiny-ecs, I'm glad this thread is coming out of the grave.