Page 1 of 2

Entities tutorial?

Posted: Wed Jun 05, 2013 7:37 pm
by Eamonn
I've been looking into a lot of things in LÖVE, and one of the things I found out about was entities. Is there a tutorial on it anywhere? I tried learning from Goature's tutorials but didn't understand it. Is it an advantage to have them? Is there a tutorial on them other than Goature?

Thanks! Any help is appreciated!

Re: Entities tutorial?

Posted: Wed Jun 05, 2013 8:19 pm
by EvilSheepLord
I just started building a framework, literally today. Right now it doesn't have much going on but I plan to complete it.
If you have some questions or need some pointers I am sure I can point you in the right direction. The discussion could be rather long for a forum post.
Send me a PM if you like.

Re: Entities tutorial?

Posted: Wed Jun 05, 2013 9:08 pm
by Inny
Here's a little primer.

Under a Classical system, you come up with a taxonomy of classes so that common classes share code. For instance, imagine a tree of sprite types:
  • Sprite
    • Mobile
      • Player
      • Enemy
    • Item
      • Coins
      • Hearts
Looks good and all. Now you want to add bullets so that the player can shoot the enemy types. Problem. Is a Bullet a Mobile or an Item? Would you add a third type, Projectile, to the Mobiles? Now you want to add Platforming physics. Do you add it to the Mobile class? Will bullets now react to gravity? This kind of design consideration is very common in classical systems.

Under an Entity-Component system, you don't make that distinction between your classes. Instead, you have a base type, Entity, and all behaviors are added to the entities in realtime. That system looks like this kind of layout, where each entity type has components added to it:
  • Player
    • Mobile
    • Controllable
    • Jumper Physics
  • Enemy
    • Mobile
    • AI Controlled
    • Jumper Physics
  • Bullet
    • Mobile
    • Projectile Movement
  • Coin
    • Collectable
  • Heart
    • Collectable
Lua lends itself more toward the Entity style system, because everything already is a table. The functions that make something "Collectable" can easily just be added to the entity table. The one complication that comes up is when multiple things want to add a function to a commonly named slot, like "update" or "draw", in which case you need some kind of Observer or Publish-Subscribe system in your entities.

Re: Entities tutorial?

Posted: Thu Jun 06, 2013 1:17 am
by davisdude
I don't know if this exactly what you wanted, but here you go:

You can make a 'class' sort of thing. I'm not very good at explaining so here's a basic example of a rectangle 'class' builder:

rectangle.lua:

Code: Select all

rectangle = {} --creates a table called rectangle to store all of your variables
rectangle.__index = rectangle --creates a 'path' to take 

function rectangle.create( x, y, width, height, mode, color ) --creates the rectangles that you want, with the x, y, width, height, mode ( "fill", line" ) and color (as a table)
local rect = {} --creates a local table that puts all the values in a table
setmetatable( rect, rectangle )

rect.x, rect.y, rect.width, rect.height, rect.mode, rect.color = x, y, width, height, mode, color

return rect
end

function rectangle:draw()
  love.graphics.setColor( self.color )
  love.graphics.rectangle( self.mode, self.x, self.y, self.width, self.height )
end
main.lua

Code: Select all

require "rectangle.lua"

function love.load()
  rectangle = rectangle.create( 32, 32, 32, 32, "fill", { 255, 0, 0 } ) --makes a rectangle with the name 'rectangle'
end

function love.draw()
  rectangle:draw()
end

Re: Entities tutorial?

Posted: Thu Jun 06, 2013 6:19 pm
by Eamonn
davisdude wrote:I don't know if this exactly what you wanted, but here you go:

You can make a 'class' sort of thing. I'm not very good at explaining so here's a basic example of a rectangle 'class' builder:

rectangle.lua:

Code: Select all

rectangle = {} --creates a table called rectangle to store all of your variables
rectangle.__index = rectangle --creates a 'path' to take 

function rectangle.create( x, y, width, height, mode, color ) --creates the rectangles that you want, with the x, y, width, height, mode ( "fill", line" ) and color (as a table)
local rect = {} --creates a local table that puts all the values in a table
setmetatable( rect, rectangle )

rect.x, rect.y, rect.width, rect.height, rect.mode, rect.color = x, y, width, height, mode, color

return rect
end

function rectangle:draw()
  love.graphics.setColor( self.color )
  love.graphics.rectangle( self.mode, self.x, self.y, self.width, self.height )
end
main.lua

Code: Select all

require "rectangle.lua"

function love.load()
  rectangle = rectangle.create( 32, 32, 32, 32, "fill", { 255, 0, 0 } ) --makes a rectangle with the name 'rectangle'
end

function love.draw()
  rectangle:draw()
end
....that's all an entity is!??! I thought it was something really complicated! So if I had a player 'class'(a player file) and required it and used it's update and draw functions, the player is an entity? If I had a ball falling, is that an entity? I think what Inny was saying was that you would have a generic type of entity base, and you would derive from that and in another file and make a more specific type of entity. It seems kind of like inheritance in C++ or Objective C. Anyway, I think I understand it now! Thanks everyone!

Re: Entities tutorial?

Posted: Thu Jun 06, 2013 7:02 pm
by davisdude
That's just my version of entities. I'm not sure if that's really what they are, but it's easy for me to understand, so that's what I use.

Re: Entities tutorial?

Posted: Thu Jun 06, 2013 7:08 pm
by EvilSheepLord
Eamonn wrote:
davisdude wrote:I don't know if this exactly what you wanted, but here you go:

You can make a 'class' sort of thing. I'm not very good at explaining so here's a basic example of a rectangle 'class' builder:

rectangle.lua:

Code: Select all

rectangle = {} --creates a table called rectangle to store all of your variables
rectangle.__index = rectangle --creates a 'path' to take 

function rectangle.create( x, y, width, height, mode, color ) --creates the rectangles that you want, with the x, y, width, height, mode ( "fill", line" ) and color (as a table)
local rect = {} --creates a local table that puts all the values in a table
setmetatable( rect, rectangle )

rect.x, rect.y, rect.width, rect.height, rect.mode, rect.color = x, y, width, height, mode, color

return rect
end

function rectangle:draw()
  love.graphics.setColor( self.color )
  love.graphics.rectangle( self.mode, self.x, self.y, self.width, self.height )
end
main.lua

Code: Select all

require "rectangle.lua"

function love.load()
  rectangle = rectangle.create( 32, 32, 32, 32, "fill", { 255, 0, 0 } ) --makes a rectangle with the name 'rectangle'
end

function love.draw()
  rectangle:draw()
end
....that's all an entity is!??! I thought it was something really complicated! So if I had a player 'class'(a player file) and required it and used it's update and draw functions, the player is an entity? If I had a ball falling, is that an entity? I think what Inny was saying was that you would have a generic type of entity base, and you would derive from that and in another file and make a more specific type of entity. It seems kind of like inheritance in C++ or Objective C. Anyway, I think I understand it now! Thanks everyone!
No, not even close. The Entity/Component model is exactly as described above, so I won't go into it again but give another brief example. A "Player" entity or a "Bad Guy" entity is made of components. Each component gives that entity certain properties. Examples of components could be Movement, Animation, Collision, Controllable.

A VERY rough example:

Code: Select all

Entity = {}

function Entity.new(id, tag, grouptag)
	local o = {}
	o.Id = id
	o.Tag = tag
	o.GroupTag = grouptag
	o.Components = {}
	setmetatable(o, { __index = Entity }) 
  return o
end

function Entity:Add(component)
	self.Components[component.Id] = component
end

Movement = {}

function Movement.new(id, x, y, xv, yv)
  local o = {}
  o.Id = id
  o.X = x
  o.Y = y
  o.Xv = xv
  o.Yv = yv
  setmetatable(o, { __index = Movement }) 
  return o
end

function love.load()
	-- Create Player Entity
	entity = Entity.new(1, "Player", "")
        -- Add Movement Component to Player Entity
	entity:Add(Movement.new(1,100,100,5,5))
	
	
end
The idea behind this is you have a Player Entity which contains a component that gives this entity an X, Y coordinate position and an X, Y velocity(Xv, Yv)
This is just an example of the concept. You may wish to move X, Y into a position Component or just give all entities the X, Y property. It depends on the needs of the system and how complex you want to go. You would also create a 'System' or 'Manager' object(table) that will perform operations on your entity, for example a MovementSystem would take the Xv, and Yv, values and apply it to the x, y values. The 'DrawSystem' would draw the the entity based on the X, Y in the Movement/Position Component or however you want to break it down. As I said a very ROUGH Example. :)

Disclaimer: I have only been looking at Love2d and Lua for a couple of days now. If there is a better way to do things in the code I post please let me know. Thanks!

Re: Entities tutorial?

Posted: Thu Jun 06, 2013 8:25 pm
by Eamonn
EvilSheepLord wrote:
Eamonn wrote:
davisdude wrote:I don't know if this exactly what you wanted, but here you go:

You can make a 'class' sort of thing. I'm not very good at explaining so here's a basic example of a rectangle 'class' builder:

rectangle.lua:

Code: Select all

rectangle = {} --creates a table called rectangle to store all of your variables
rectangle.__index = rectangle --creates a 'path' to take 

function rectangle.create( x, y, width, height, mode, color ) --creates the rectangles that you want, with the x, y, width, height, mode ( "fill", line" ) and color (as a table)
local rect = {} --creates a local table that puts all the values in a table
setmetatable( rect, rectangle )

rect.x, rect.y, rect.width, rect.height, rect.mode, rect.color = x, y, width, height, mode, color

return rect
end

function rectangle:draw()
  love.graphics.setColor( self.color )
  love.graphics.rectangle( self.mode, self.x, self.y, self.width, self.height )
end
main.lua

Code: Select all

require "rectangle.lua"

function love.load()
  rectangle = rectangle.create( 32, 32, 32, 32, "fill", { 255, 0, 0 } ) --makes a rectangle with the name 'rectangle'
end

function love.draw()
  rectangle:draw()
end
....that's all an entity is!??! I thought it was something really complicated! So if I had a player 'class'(a player file) and required it and used it's update and draw functions, the player is an entity? If I had a ball falling, is that an entity? I think what Inny was saying was that you would have a generic type of entity base, and you would derive from that and in another file and make a more specific type of entity. It seems kind of like inheritance in C++ or Objective C. Anyway, I think I understand it now! Thanks everyone!
No, not even close. The Entity/Component model is exactly as described above, so I won't go into it again but give another brief example. A "Player" entity or a "Bad Guy" entity is made of components. Each component gives that entity certain properties. Examples of components could be Movement, Animation, Collision, Controllable.

A VERY rough example:

Code: Select all

Entity = {}

function Entity.new(id, tag, grouptag)
	local o = {}
	o.Id = id
	o.Tag = tag
	o.GroupTag = grouptag
	o.Components = {}
	setmetatable(o, { __index = Entity }) 
  return o
end

function Entity:Add(component)
	self.Components[component.Id] = component
end

Movement = {}

function Movement.new(id, x, y, xv, yv)
  local o = {}
  o.Id = id
  o.X = x
  o.Y = y
  o.Xv = xv
  o.Yv = yv
  setmetatable(o, { __index = Movement }) 
  return o
end

function love.load()
	-- Create Player Entity
	entity = Entity.new(1, "Player", "")
        -- Add Movement Component to Player Entity
	entity:Add(Movement.new(1,100,100,5,5))
	
	
end
The idea behind this is you have a Player Entity which contains a component that gives this entity an X, Y coordinate position and an X, Y velocity(Xv, Yv)
This is just an example of the concept. You may wish to move X, Y into a position Component or just give all entities the X, Y property. It depends on the needs of the system and how complex you want to go. You would also create a 'System' or 'Manager' object(table) that will perform operations on your entity, for example a MovementSystem would take the Xv, and Yv, values and apply it to the x, y values. The 'DrawSystem' would draw the the entity based on the X, Y in the Movement/Position Component or however you want to break it down. As I said a very ROUGH Example. :)

Disclaimer: I have only been looking at Love2d and Lua for a couple of days now. If there is a better way to do things in the code I post please let me know. Thanks!
I get it now! Thanks!

Re: Entities tutorial?

Posted: Thu Jun 06, 2013 8:39 pm
by EvilSheepLord
Most welcome. :)

Re: Entities tutorial?

Posted: Thu Jun 06, 2013 10:32 pm
by Inny
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.