Entities tutorial?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
Eamonn
Party member
Posts: 550
Joined: Sat May 04, 2013 1:29 pm
Location: Ireland

Entities tutorial?

Post 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!
"In those quiet moments, you come into my mind" - Liam Reilly
EvilSheepLord
Prole
Posts: 10
Joined: Wed Jun 05, 2013 6:05 pm

Re: Entities tutorial?

Post 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.
User avatar
Inny
Party member
Posts: 652
Joined: Fri Jan 30, 2009 3:41 am
Location: New York

Re: Entities tutorial?

Post 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.
davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

Re: Entities tutorial?

Post 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
GitHub | MLib - Math and shape intersections library | Walt - Animation library | Brady - Camera library with parallax scrolling | Vim-love-docs - Help files and syntax coloring for Vim
User avatar
Eamonn
Party member
Posts: 550
Joined: Sat May 04, 2013 1:29 pm
Location: Ireland

Re: Entities tutorial?

Post 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!
"In those quiet moments, you come into my mind" - Liam Reilly
davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

Re: Entities tutorial?

Post 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.
GitHub | MLib - Math and shape intersections library | Walt - Animation library | Brady - Camera library with parallax scrolling | Vim-love-docs - Help files and syntax coloring for Vim
EvilSheepLord
Prole
Posts: 10
Joined: Wed Jun 05, 2013 6:05 pm

Re: Entities tutorial?

Post 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!
User avatar
Eamonn
Party member
Posts: 550
Joined: Sat May 04, 2013 1:29 pm
Location: Ireland

Re: Entities tutorial?

Post 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!
"In those quiet moments, you come into my mind" - Liam Reilly
EvilSheepLord
Prole
Posts: 10
Joined: Wed Jun 05, 2013 6:05 pm

Re: Entities tutorial?

Post by EvilSheepLord »

Most welcome. :)
User avatar
Inny
Party member
Posts: 652
Joined: Fri Jan 30, 2009 3:41 am
Location: New York

Re: Entities tutorial?

Post 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.
Post Reply

Who is online

Users browsing this forum: Google [Bot], Semrush [Bot] and 2 guests