Entity Component System

Monkey Forums/Monkey Code/Entity Component System

Belimoth(Posted 2013) [#1]
Fun little experiment I did in another thread.
In order to write a new Component you have to define an accompanying ComponentGetter<>, which in this example I've prefixed with an underscore.

Strict
#REFLECTION_FILTER="*"
Import reflection

Class Entity
	Field components := New StringMap<Component>
	
	Method AddComponent:Void(component:Component)
		Local key:String = GetClass(component).Name
		components.Set(key, component)
		component.owner = Self
	End
End

Class Component
	Field owner:Entity
End

Class ComponentGetter<T>
	Global name:String
	
	Function GetFrom:T(entity:Entity)
		If name = "" Then name = GetClass( New T() ).Name	'be aware of this New
		Return T( entity.components.Get(name) )
	End
End



Class _PositionComponent Extends ComponentGetter<PositionComponent> End

Class PositionComponent Extends Component

Public
	Method X:Int() Property Return _x End
	Method X:Void(x:Int) Property _x = x End
	Method Y:Int() Property Return _y End
	Method Y:Void(y:Int) Property _y = y End
	
	Method New(x:Int, y:Int)
		Self._x = x
		Self._y = y
	End
Private
	Field _x:Int, _y:Int
End

Function Main:Int()
	Local myEntity := New Entity()
	myEntity.AddComponent( New PositionComponent(16, 24) )
	Local position := _PositionComponent.GetFrom(myEntity)
	Print "X: " + position.X + " Y: " + position.Y
	Return 0
End



Belimoth(Posted 2013) [#2]
Here's a version that doesn't involve reflection.




Belimoth(Posted 2013) [#3]
All this to avoid one cast


Belimoth(Posted 2013) [#4]
Version 3, I never miss an opportunity to over-engineer something.



Supports having more than one component of the same type, and adds a "property" thing. I am probably done with this.


c.k.(Posted 2013) [#5]
I wish I understood all this. :-/

Maybe someday.


Halfdan(Posted 2013) [#6]
cool I started looking into this Entity Component thing, here is an article about it (article link)

your system looks a bit different but I'll use it as starting point


Belimoth(Posted 2013) [#7]
Yeah it's all a bit fuzzy to me, it might be closer to aspect-oriented than component-oriented.
In hindsight...
Class Get<T>
	Function From:T(entity:Entity)
		...
	End
End
...
Get<PositionComponent>.From(myEntity)
...is much cleaner than my first attempt up there. Oh well.


Sammy(Posted 2014) [#8]
Having just read up on component systems I was wondering if this was possible in Monkey. You example has show me it most definitely is, many thanks! :)


Goodlookinguy(Posted 2014) [#9]
Entity component systems are overrated. It was a fad that's already expired. They're more work than they're worth. Just go the classic route unless you have a team of 10+ people and millions of lines of code. Because building games with ECS is like building a city out of Legos.