Your views on my game object setup

Started by
14 comments, last by extropy45 13 years, 3 months ago
I want't to make a ridiculously dynamic data driven game :) Is this a resonable way to go?

template <typename T>class GameObjectMessage{public:	enum messageAction { CREATE, DESTROY, SET, GET };	unsigned int targetID; //if targetID = 0 you acess the handler andcan create and destroy objects	unsigned int senderID; //if you create a object you get the new ID sent back, or if you request a variable	unsigned short int componentID; //the component you need to access in the target object	unsigned short int action;	int parameter1;	T parameter2;};class GameObject{public:	void setHandler(ObjectHandler *handler) { this->handler = handler; } //set pointer to the handler object, so the components can send messages	void setID(unsigned int ID) { this->ID = ID; }	unsigned int getID() { return ID; }	void setParentID(unsigned int ID) { this->parentID = ID; }	unsigned int getParentID() { return parentID; }	void addComponent(BaseComponent component); //so the GameObjectHandler can add components when creating the object	void processMessage(GameObjectMessage<int> message); //set or get variable in the correct component	void processMessage(GameObjectMessage<float> message);	void processMessage(GameObjectMessage<string> message);	void processMessage(GameObjectMessage<bool> message);	void update(unsigned int time); //calls update() in all objects, used by object handlerprivate:	ObjectHandler *handler;	unsigned int ID;	unsigned int parentID;	BaseComponent components[1]; //uses array instead of vector so i can serialize the object};class ObjectHandler{public:	unsigned int createObject(unsigned int prototypeID); //if no ID is specified in the prototype object, a random is assigned and returned	unsigned int destroyObject(unsigned int objectID);	void loadObjectPrototypes(string directory); //load all object prototypes from the directory, serialized objects in separate files	void saveObjectPrototype(string filename, GameObject object); //save single object prototype (i will use the same classes in the object editor)	void processMessage(GameObjectMessage<int> message); //handles create/destroy message or sends it to object	void processMessage(GameObjectMessage<float> message);	void processMessage(GameObjectMessage<string> message);	void processMessage(GameObjectMessage<bool> message);	void update(unsigned int time); //calls update() in all objectsprivate:	vector<BaseComponent> objectPrototypes;	vector<GameObject> gameObjects; //i want to be able to serialize och save and load all game objects in a file like a savegame, can't use vector};class BaseComponent{public:	void setObject(GameObject *object) { this->object = object; } //set pointer to parent object, so the components can send messages to handler	virtual unsigned int getComponentID(); //return a unique id of the derived component	virtual void update(unsigned int time);private:	GameObject *object;};
Advertisement
Then you just combine the components as you please. like:
door, animation, lockable, breakable, geometry, collidable, sound

and set up parameters in the component objects, so they know where to send and request data. like door what animation and sound it should request when opened.

you could also make a separate object that is a keypad and tell it to "talk" with lockable for example, as long as you have named objects.
Using a component-based system is certainly a good start, but if you really want it to be 'ridiculously dynamic', your best bet would probably be to make the engine scriptable (e.g. using Lua), and move the bulk of the game logic to the scripting side.
Hmm yeah that seems like a good idea! At least a component for object logic with scripting and dynamic variables. But that should be easy to add later when i have done some testing :)
Quote:Original post by jyk
Using a component-based system is certainly a good start, but if you really want it to be 'ridiculously dynamic', your best bet would probably be to make the engine scriptable (e.g. using Lua), and move the bulk of the game logic to the scripting side.


I recently began doing this and I couldn't agree more. A dynamic language (like Lua) makes it so much easier to write the game object code. I would also recommend it for the user interface as well.

As a matter of fact I have essentially all of my logic in Lua. The script creates the window/renderer and manipulates the scene based on the game objects. All of the heavy weight stuff (rendering, scene interpolation, physics, quaternion/vector/matrix math) is done in C++, but instantiated through Lua. The Lua code is only called 20 times a second and the scene is interpolated between logic timesteps. So even though Lua has complete control, it is not running every frame. So far I love the decision but I am expecting to run into issues (like performance).

In other words. Using a dynamic language to script game logic is a great idea.
I read about UML and decided to try it out before doing any more coding!

http://imgur.com/JWZBY.png

The component function getComponent() goes trough Scene.getEntity() and Entity.getComponent() to get a pointer to another component, then it can acess the variables in that component.
A component can also change scene state to exit to a menu, change level, or exit the game.

This is how it should work:
I create a SceneManager in my program.
Register all types of components. (used by entity creation with componentID)
Creates and add a scene.
Use the loadScene(xml file) that then add entities and use loadEntity(xml file) on each of them.
Then call SceneManager.update() and SceneManager.draw() in the game loop.
The game loop checks the sceneState to break the loop or change scene.

The scene xml will hold objectID and a path to another xml file that specifies the objects components and the components variables. Is this a resonable way to load objects? Could become many files fast!
Seems like a pretty complex system, but looks like it would be fun to implement as a technical exercise. That said you'll probably find it difficult to actually finish a game out of it. Not sure if that's your intention or not though (actually making a game or just taking on the programming challenge).

One thing I'd throw in there based on your last post - using XML to store everything is going to lead to some pretty long load times as XML parsing can take a while. Your best bet would be to use XML as an intermediate format and convert them to something a bit more compact and laid out like the system would expect it. Whether that's easily possible with this kind of setup though, I'm not sure - you'd need to have a good think about it. But hey, that could be a fun challenge too :)

just thought I'd throw some random XML hate out there ;)

good luck!

edit: one more thing I just noticed in the code - "uses array instead of vector so i can serialize the object" - elements in a vector are stored contiguously just like a normal array, so you may want to use a vector for the convenience functions it provides (or alternatively your own array class, better suited to your game with regard to memory allocations etc)
[size="1"]
Perhaps it's a little complex :) but it feels more logical for me than other approaches i have seen. Also when this is done and tested, i can just hide the code and start focusing on the components! My goal is to learn something for fun and then see where it leads!

I have thrown away the old code, i decided to skip the messaging system and go for direct communication with pointers between the components.

Perhaps i'll skip the xml approach and just code something own.
A object could be defined by strings that you easily can tokenize and use to create objects:
component;;int;1
component;;int;2
component;;int;3
component;;int;4
variable;1;string;qwerty
variable;2;int;7
variable;3;double;5.7
variable;4;bool;false

And for the scene definition:
objectId;;0 (would create a object with random ID, other would create a "named" object)
objectType;;47 (would load a definition of type 47, like that above)
variable;1;int;10 (if you need to override variables)
and then onto the next object...

I have also been thinking about creating a manager that loads all the data and creates protoypes of each type of object. Should be effective when you reuse the object definitions for many objects.
Actually I'd advocate the use of a message parsing/event based system. I have it set up so entities really only expose a HandleEvent function, and can respond to events as they please. It's not that difficult to get going.

The good thing I'd say about XML, is that it is easy to understand. But if you want the fastest performance you'd want a format the requires minimal parsing (or a binary format). There's nothing stopping you from converting XML into another format, though.

That said, that's probably the least of your worries for now.
[size="1"]
Ok, how does your messages look? I have been thinking a bit about it, something like a struct with:

int targetEntityID (0 for acessing the scene)
int targetComponentID
int senderEntityID (for eventual replies and other stuff)
int senderComponentID
int action (1 = set, 2 = get, 3 = add, 4 = remove)
int variableID
int dataType = (1 = int, 2 = double, 3 = string, 4 = bool)
string value

Then i could set, get add and remove variables from components, create and destoy objects with the scene object, change scene state. add and remove components in a object. Something more i need to be able to do?

also i forgot to mention that i intend to have a Entity (nr 1) with all the basic components like render, sound, control, physics and so on... the rest is just actual game entities.


This topic is closed to new replies.

Advertisement