Page 2 of 2

Re: Entities tutorial?

Posted: Fri Jun 07, 2013 4:02 pm
by markgo
Seems like a mixin system to me. I use something similar to that. Instead of inheritance, I copy values from other tables to extend an object. For duplicate method names, I put similar funcs in a subtables and the method would call all of them.

Code: Select all

character()
 :mixin(animation)
 :mixin(box)
 :mixin(sound)

Re: Entities tutorial?

Posted: Fri Jun 07, 2013 4:44 pm
by Eamonn
Inny wrote:As an example of the idea that you add components to entities, here's some code I've been fiddling with lately:

Code: Select all

local Colored = Component {
  _color = {0, 0, 0, 255}
}

function Colored:color(r, g, b, a)
  if r==nil and g==nil and b==nil and a==nil then
    return self._color[1], self._color[2], self._color[3], self._color[4]
  else
    local old = self._color
    self._color = { r or old[1], g or old[2], b or old[3], a or old[4] }
  end
  return self
end
In this piece of code, I establish a component, Colored, that carries this one function that lets me define or access the color for an entity.

Code: Select all

local ColoredDraw = Component {
}

function ColoredDraw:init()
  self:import(Colored):import(Rectangular)
  self:on('draw', self.drawColoredRect)
end

function ColoredDraw:drawColoredRect(offset)
  local ox, oy = offset and offset.x or 0, offset and offset.y or 0
  local x, y, w, h = self:rectangle()
  Graphics:setColor(self:color())
  love.graphics.rectangle("fill", x+ox, y+oy, w, h)
  return self
end
This next piece is a component that depends on Colored and Rectangular, that will make use of those two components to draw a colored rectangle on the screen.

The definition of the abstract "Component" is trivial enough that you don't need to see it, it's basically just a way to copy everything from one table to another, sans the key "init" which has the special meaning that it'll be called when an entity imports the component the first time, and a __call metamethod to make it easier to use. Also, the "on" function is that Observer thing I mentioned in my earlier post, which I've actually open sourced that code here.

What this gets me is that I can declare things like so:

Code: Select all

local things = ColoredDraw(Entity())
    :rectangle(200, 100, 64, 64)
    :color(255, 0, 0)
And thats it in a nutshell. Instead of complex declarations, I create tables that are copied into the final entity table.

I'm still learning this stuff myself, but I'm please with what I've been experimenting with. To get a better feel for how to do this stuff, I'd say you should cross the void and look at http://craftyjs.com/ to see how they explain Entity systems. It's very interesting stuff.
Thanks! I do have a good understanding of entities now! I'll check out that site after I finish writing this :D

Re: Entities tutorial?

Posted: Fri Jun 07, 2013 8:00 pm
by Inny
markgo wrote:Seems like a mixin system to me.
It seems to be the easiest way to to think about it. The only sidebar is that the entity in question needs to know what mixins/components it already has, so that the components can depend on each other without mixing in the same components over and over and having the individual init functions called repeatedly. The idea for multiple functions with the same name automatically becoming a table that can call of those functions is a very interesting one.

Re: Entities tutorial?

Posted: Fri Jun 07, 2013 10:26 pm
by markgo
Well the subtable is like a table of observers and the method would pass the event and args to all the observers. Right now I haven't found a nice solution to handle duplicate functions (getters) which return values. I have to manually define the function for my object and the mixin would not override any existing key-value. It's that or redefine the function after mixin.

Re: Entities tutorial?

Posted: Fri Jun 07, 2013 11:15 pm
by Inny
markgo wrote:Right now I haven't found a nice solution to handle duplicate functions (getters) which return values.
Not to be flippant, but in my design I decided that all of the functions across components should have different names. As a for instance, my Rectangular component is based off of the Rectangle snippet I made public just over a week ago, and then I ran into a case where the name "values" was a terrible ambiguity, so I renamed it to "rectangle". This does lead to the case where the generic "draw" and "update" becomes "drawPlayer" and "updatePlayer". It does make pretty printing an entity into the debug log easier to read.

Re: Entities tutorial?

Posted: Sat Jun 08, 2013 12:49 am
by markgo
Ah I see! Attaching the component name to functions is a nice idea. I'm probably gonna modify it to something like this:

Code: Select all

character()
	:mixin(animation)
	:mixin(box)
	:mixin(sound)
 
 -- To access a specific component, attach the component name as a prefix
 x,y,w,h = character:box_getSize()
-- or maybe something like this
 x,y,w,h = character['box']:getSize()
Cool! Thanks for the idea. Good discussion.