Page 1 of 1

RF2 Component Based Entities

Posted: Tue Dec 08, 2009 11:12 pm
by paradoxnj
After playing with the scripting system a bit, I was able to develop a component based entity system for RF2. A component based entity is an entity that is made up of many components. Think of a Windows GUI application. The application is nothing more than a WinMain() function. The components of the application are what actually do the work. Those components are Forms (Windows), controls (list box, combo box, text box, label, button, etc), logic (external libraries). So for RF2, there will be 2 types of components...hard coded and scripted. Hard coded components will be components that are specific to the RF2 C++ code and can be modified only by editing properties. Scripted components will be made using Squirrel classes and can be anything you want them to be.

So far, I have 2 hard coded components:

-- Actor - assigns a mesh to your entity
-- Animation - assigns a skeleton to your entity and applies animation

Planned components are:

-- Physics - Physics properties for an object
-- Inventory - Object can hold an inventory
-- Brain - AI related properties and scripts
-- Conversation - Object can hold a conversation
-- Debris - Object can leave a mess when it is destroyed
-- Fader - Fades out an object

I don't have any scripted components yet.

There will be a GUI in the RF2 Editor to create these objects and save them to the format they need to be saved in. The format is just a text file that is parsed using a custom parser that is derived from the Ogre Script parser interfaces. The test object is the robot mesh. To define it, I did the following:

Code: Select all

// test.rfobject
object Robot
{
	actor
	{
		mesh robot.mesh
		material Examples/Robot
	}
}
The format is simple. The word object tells us to create a new object template and call it Robot. Inside the brackets are the components and their properties. The properties have default values so if you don't want to define one, you don't have to. In this case, I am assigning an actor component and setting the mesh property to robot.mesh and the material property to Examples/Robot. Upon object instance creation, the actor component will use robot.mesh for the mesh file and Examples/Robot as the material.

Components will update every frame with the object. So the hierarchy is as follows:

-- Object instance created from object template
-- Object instance added to world
-- World updates object instances
-- Object instances update component instances
-- Component instances apply logic based on properties

The combinations you could use would be endless and you are not stuck using the same old entities again and again as you can create new components using script. I see this as a great community building tool as the more prominent scripters can create components for the community as components will work from game to game as long as all scripts are included with them.

I used the following Squirrel code to create the object to display in my test scene. You could also change the properties of an object's components to change the behavior of that object during runtime. It will only affect the instance that you are working on and not the template. If you create another object, the changes you made to the previous object will not carry over.

Code: Select all

local rob = RFObject("Robot");
rob.setPosition(Vector3(0.0, 99.0, 0.0));
rob.setScale(Vector3(0.50, 0.50, 0.50));

Re: RF2 Component Based Entities

Posted: Thu Jan 28, 2010 4:05 am
by paradoxnj
I changed things up a little. Instead of having a custom script parser, I decided to use Squirrel for object definitions. Here is an example:

Code: Select all

// Contents of robot.nut
local RobotData =
{	
	body =
	{
		skeleton = "robot.skeleton"
	},
	
	animation =
	{
		idle = 
		{
			name = "Idle",
			speed = 0.35,
			loop = true
		}
	},
	
	actor =
	{
		mesh = "robot.mesh",
		material = "Examples/Robot"
	},
}

RFGetObjectManager().registerObjectTemplate("robot", RobotData);
body, animation, and actor are components that make up robot. You can put more than one object template in a script (as many as you want). To create this object and place it in the world, you use the following Squirrel code:

Code: Select all

// Object template names are not case sensitive.  They are converted to lowercase in the engine before they are used.
local rob = RFObject("Robot");
rob.setPosition(Vector3(0.0, 99.0, 0.0));
rob.setScale(Vector3(0.25, 0.25, 0.25));

Re: RF2 Component Based Entities

Posted: Fri Jan 29, 2010 5:43 pm
by paradoxnj
People...this is the entity system that will be going into place. If you have any reservations or comments, please make them as I want to hear them.

Re: RF2 Component Based Entities

Posted: Fri Jan 29, 2010 10:21 pm
by Jay
So... basically, what you are proposing is a system where you 'plug together' the entities instead of having entities like StaticMesh, StaticEntityProxy, Pawn, etc... This could be implemented, of course, with a simple StaticMesh just having

Code: Select all

SampleStaticMesh
{
   actor =
   {
      mesh = "example.mesh",
      material = "Examples/example"
   },
}
(Is the comma at the end needed? It looks strange, since nothing is coming after it)

I have a few questions regarding this system... would it be possible to change the components in the script, like you change the actor for example? Can object types inherit from other object types? Could one add a new component to the object at runtime? Can functions be defined for those types?

I am asking this because... for example when you can inherit from other types, it would be easy to make some default entities like StaticMesh (has actor), StaticEntityProxy (has actor, animation), Pawn (has actor, animation, brain, inventory) etc. from which you would inherit to make your own entities and just add the stuff you need.
If there is inheritance, how many levels are permitted?

Attributes will be stored in Inventory, i suppose?
And, is it really neccessary to make a new component type 'Fader' just to be able to fade out an object?

Re: RF2 Component Based Entities

Posted: Fri Jan 29, 2010 10:50 pm
by paradoxnj
The comma is not needed. Just a habit. :)
So... basically, what you are proposing is a system where you 'plug together' the entities instead of having entities like StaticMesh, StaticEntityProxy, Pawn, etc...
Yes. That definition is perfect for a non-animated mesh.
would it be possible to change the components in the script, like you change the actor for example?
Yes. I've exposed a function called setComponentProperty() to script. To use it, you would do the following:

Code: Select all

local rob = RFObject("Robot");
rob.setPosition(vecTmp);
rob.setScale(Vector3(0.5, 0.5, 0.5));
rob.setComponentProperty("animation", "current_animation", "Idle");
// Component Name, Property Name, Property Value
Can object types inherit from other object types?
Not at the moment, but it is a good idea. I will see if it is technically possible using the current code.
Could one add a new component to the object at runtime?
Not at the moment, but it is planned.
Can functions be defined for those types?
Not sure what you mean. Can you elaborate a bit?
I am asking this because... for example when you can inherit from other types, it would be easy to make some default entities like StaticMesh (has actor), StaticEntityProxy (has actor, animation), Pawn (has actor, animation, brain, inventory) etc. from which you would inherit to make your own entities and just add the stuff you need.
If there is inheritance, how many levels are permitted?
Yes. This is the way Dungeon Siege works. The inheritance style in Squirrel represents Java. class BlueRobot extends Robot. Key is that I would have to use classes instead of tables for this.
Attributes will be stored in Inventory, i suppose?
And, is it really neccessary to make a new component type 'Fader' just to be able to fade out an object?
Inventory give the object the ability to store other objects. For example, stuff in a backpack, list of guns, etc... I agree...Fader is more of an event than a component. I will remove it from the list. Fader was more to fade and object in and out over time (like a ghost for example).

Re: RF2 Component Based Entities

Posted: Sat Jan 30, 2010 12:14 am
by Jay
paradoxnj wrote:
Can functions be defined for those types?
Not sure what you mean. Can you elaborate a bit?
It was more of a Squirrel question. I was asking if Squirrel can have functions for the classes. I found the Sqirrel 2.0 Reference in the internet and it answered the question. Seems like Squirrel can indeed have functions and you can also override them in inherited classes. Scanning through it, i also found out that you can kind of override operators. Nice feature for a scripting language, though i don't think we will use it that much for game development. Still, nice to have.

What was the version number of Squirrel we use again?

Re: RF2 Component Based Entities

Posted: Sat Jan 30, 2010 3:18 am
by paradoxnj
Squirrel v2.2.4. Latest stable code.

Overloaded operators will be used for the math classes to make things easier. RF2 is an event driven shell. All objects will respond to events. Current events for objects are object_create, object_destroy, and object_collide. Scripts will have functions to respond to those events. In addition, you will be able to create your own events and event listener in script. Functions will be exported to do real AI as well. I'm going to start with A* as that is the easiest.

Re: RF2 Component Based Entities

Posted: Sun Jan 31, 2010 1:05 pm
by tgrech
Where can i learn this code? ive been googleing everything but nout comes up.

Re: RF2 Component Based Entities

Posted: Mon Feb 01, 2010 3:23 am
by paradoxnj
What code?

Re: RF2 Component Based Entities

Posted: Mon Feb 01, 2010 3:22 pm
by Jay
I think he means Squirrel.

Re: RF2 Component Based Entities

Posted: Mon Feb 01, 2010 5:20 pm
by paradoxnj
Oh...in that case. http://www.squirrel-lang.org