Page 1 of 2

HooECS, the wise choice!

Posted: Sat Oct 21, 2017 8:21 am
by erasio
I'm happy to share the first release of HooECS!

HooECS is a fork of lovetoys with a bunch of new functionality.
Lovetoys projects are 100% compatible. So if you've been developing with lovetoys so far. Feel free to give this one a try!

Most notable changes:
  • Activating and deactivating entities. Remove entities from your systems without removing them from the engine!
  • Give entities an update function to be called before any systems! Update your component data to your hearts desire!
  • Entity:copy() & Entity:shallowCopy(). Create easy duplicates of your entities!
  • More callbacks! React to what's happening!
  • A bit of syntactic suggar.
But lets back off for a moment. I know not everyone is familiar with lovetoys and ECS in general. So.

What is ECS?

ECS or Entity, Component, System is a development paradigm that focuses on composition.
In other words. It's a way to structure your code and make sure you write as little duplicate code as possible all while not using inheritance.

Entities are containers for components.
Components are named data bags. Potentially containing some util functions.
Systems get a list of entities which have specific components and execute draw or update functionality on those entities.

This allows for example for an animationComponent and an animationSystem. Create a animationComponent, fill it with quads, an image and a duration and let the animationSystem do all the work. No mixins. No inheritance. Just tag on functionality!

What's lovetoys?

Lovetoys is the original project this library is based upon. All core functionality is the same and any lovetoys project can be used with HooECS.

You can check out the original here

Why create a fork?

Lovetoys implements the basics but there's a bunch of very useful functionality that I found to be very valuable indeed.
The name is also a bit of an issue for some. Googling for lovetoys at uni or school is not really all that fantastic ;)
So I've started to maintain a fork which offers solutions for both.

Some final words

The framework will see some continuous updates. I've labeled it v0.1 intentionally. v1.0 is still a bit out. Not because it's not stable. But because I'm not satisfied enough with it yet.

If you wanna contribute please do submit a pull request anytime. CI tests will automatically run on every pull request. Pull requests won't be accepted if any test fails.

Suggestions, bugs and / or questions are more than welcome! Create an issue on github, respond to this thread or PM me either on this forum or the discord server.

Happy developing! I hope it'll be a hoot!

https://github.com/Hooodini/HooECS

Re: HooECS, the wise choice!

Posted: Fri Nov 03, 2017 4:45 pm
by ivan
https://github.com/Hooodini/HooECS/blob ... ty.lua#L10
"self.active = active or true" might not work as you intended.
I suggets:
self.active = (active == true)

Re: HooECS, the wise choice!

Posted: Sat Nov 04, 2017 1:13 pm
by Fuzzlix
ivan wrote: Fri Nov 03, 2017 4:45 pm https://github.com/Hooodini/HooECS/blob ... ty.lua#L10
"self.active = active or true" might not work as you intended.
I suggets:
self.active = (active == true)
In this special case you mean probably this?:

Code: Select all

self.active = (type(active) == "boolean") and active or true;
The intended default for the ommited parameter is true here.

But thats only one question i have about lovetoys and/or HooECS.

For Instance:
If you add/register a entity in the engine, the system gets a ID assigned in the engine:addEntity() function:

Code: Select all

    local newId = #self.entities + 1;
    entity.id = newId;
Then you remove the entity later by calling engine:removeEntity(). engine.entities[id] gets nil-ed out and we got in the worst case a hole in the list, making later "#entities" unstable. In case we nil out the last entry in this list, a new added Entity gets a already choosen id assigned.
Looks very strange to me. (or i simply did not grasp the idea).

I think, there is a lot more wrong with lovetoys. Shure it worked out for some games but i am not shure i can trust this code in all situations. (like this id stuff)

I think erasio's work can help to make the lovetoys library much more stable and usefull.

Re: HooECS, the wise choice!

Posted: Sat Nov 04, 2017 3:09 pm
by bartbes
ivan wrote: Fri Nov 03, 2017 4:45 pm I suggets:
self.active = (active == true)
Fuzzlix wrote: Sat Nov 04, 2017 1:13 pm In this special case you mean probably this?:

Code: Select all

self.active = (type(active) == "boolean") and active or true;
The intended default for the ommited parameter is true here.
I can't believe neither of you posted the obvious solution:

Code: Select all

self.active = active ~= false
Note that Fuzzlix's suggestion always returns true

Re: HooECS, the wise choice!

Posted: Sat Nov 04, 2017 3:19 pm
by Fuzzlix
Bartbes: 10 points :)

Re: HooECS, the wise choice!

Posted: Sat Nov 04, 2017 3:20 pm
by ivan
bartbes wrote: Sat Nov 04, 2017 3:09 pm I can't believe neither of you posted the obvious solution:
True, good catch there. :)
It should re-asserted that your solution works when the default value is supposed to be "true", mine defaults to "false".

Re: HooECS, the wise choice!

Posted: Sat Nov 04, 2017 6:36 pm
by erasio
True point ivan. I did expect correct input (a bool). But since that data is only used for checks from there on out aka:

Code: Select all

if entity.active then
it ultimately doesn't matter. If it's a table. It will still work as intended.

---

The entity list is not intended as array list. But as unique identifier. It's used with pairs across the core code. Users are not expected to use the ID or entity list directly.

It should be outlined in docs that the target container isn't a list but just contains the entities at arbitrary indexes. That's true and I should fix that.

But I don't think that's a serious issue. Especially not a deal breaking one ;)

Re: HooECS, the wise choice!

Posted: Sat Nov 04, 2017 8:43 pm
by Fuzzlix
erasio wrote: Sat Nov 04, 2017 6:36 pm The entity list is not intended as array list. But as unique identifier. It's used with pairs across the core code. Users are not expected to use the ID or entity list directly.
Thats all true. But HooECS uses this list internally to calculate the next free ID.
erasio wrote: Sat Nov 04, 2017 6:36 pm But I don't think that's a serious issue. Especially not a deal breaking one ;)
Depending on the real use case the "#" operator may give back (in rare situations) false results.
There are 2 solutions:
1. use a static counter and increment this counter each new addEntity()
2. use the entity itself as ID like "entity.id = entity"

This make sense?

Re: HooECS, the wise choice!

Posted: Sat Nov 04, 2017 10:43 pm
by Fuzzlix
in EventManager.lua:

Code: Select all

function EventManager:removeListener(eventName, listener)
  if self.eventListeners[eventName] then
    for key, registeredListener in pairs(self.eventListeners[eventName]) do
      if registeredListener[1].class.name == listener then  -- << BUG!
        table.remove(self.eventListeners[eventName], key)
        return
      end
    end
    ...
  end
  ...
end
The test should be:

Code: Select all

if registeredListener[1].class == listener.class then

Re: HooECS, the wise choice!

Posted: Sat Nov 04, 2017 10:48 pm
by yetneverdone
I suggest that a source code be available on how to use this library in an actual game would really help beginners (or like me, who is unfamiliar/inexperienced) with this system. Like just a simple pong or snake game would really do :)