Sign in to follow this  
FrontBack

Entity/Component architecture using plugins

Recommended Posts

FrontBack    237

Hi all, I'm currently making a 2D engine using MonoGame. Since I want it extremely flexible, I'd like to implement a sort of plugin system. I mean, each entity picks its required components from various DLLs, that contain some components, all inherited from the same BaseComponent class in the engine. I also want to implement a serialization system to JSON to save the scenes, which are merely a list of all the entities.

Is it possible? If yes, how? I've already checked at Duality, but that didn't help.

 

Thanks in advance! :)

Share this post


Link to post
Share on other sites
FrontBack    237

I don't know how to design the architecture of the entities and the components (basically I don't know how should they communicate), and I don't know how to serialize and deserialize them without breaking anything, because I've read that if you're using plugins the deserialization could raise some exceptions.

Share this post


Link to post
Share on other sites
frob    44977

Exactly how you do it is up your own implementation.  The "could raise exceptions" is certainly one way of implementing things.

 

 

Objects should generally serialize themselves.  Everything above the objects should be serialized by the base system.

 

For example, lets say you build a system like I've used in a few games. Your base game provides some classes, you start with a GameObect, then it is specialized to a Portal, that is specialized again to OneLaneDoor, MultiLaneDoor, and so on. Then someone comes along using your modding system and creates their own component, we'll call it AntiZombieDoor component derived from OneLaneDoor. 

 

At startup your system goes through all registered components and finds the AntiZombieDoor component. It validates it, and we assume everything checked out. The player puts an AntiZombieDoor object in the world and everything is good.  Then the player saves. AntiZombieDoor has its serialization function called, looking something like this:

 

bool Serialize( Serializer s) {

  result = OneLaneDoor.Serialize(s);

  if(result) {

   result &= s.WriteS32( key1, this.foo ); 

   result &= s.WriteS16( key2, this.bar );

   ....

  }

 return result;

}

 

The game system will serialize whatever other information is needed like the object's position and orientation and any customizations or other information.

 

The next time the player plays, the game loads up all the components at startup. When the save file is loaded, the object's key is validated. If the library is found, it runs the same deserialization process:

 

bool Deserialize( Deserializer s) {

  result = OneLaneDoor.Deserialize(s);

  if(result) {

   result &= s.ReadS32( key1, this.foo, somedefault ); 

   result &= s.ReadS16( key2, this.bar, otherdefault );

   ....

  }

 return result;

}

 
Then if that succeeds, the game engine places it in the world and restores any values that were missed. The AntiZombieDoor will appear in the same place, in the same state, doing whatever thing it was doing before.
 
If that failed, then you need to specify a fallback system. We've always had fallback objects as things that exist in the base game. Each game object has an ID as part of the built-in data that indicates the fallback object. This is always recorded at save in case the custom content isn't installed during load. If there is an error loading the object, perhaps because the file was corrupt, but also potentially because the DLL or the custom content was not found, then the fallback object is created instead and a message is shown to the user that some content could not be loaded. In this case the fallback object might be a different OneLaneDoor. If there is a problem creating the fallback object, just punt and don't create the object, the error message shown to the player is sufficient.
 
Of course, your game is different, so you may have different responses to libraries not loading properly.

Share this post


Link to post
Share on other sites
FrontBack    237

Basically, you're telling me that each component should serialize itself, and once it's serialized it will be quite straightforward to reload them, but that implies that somehow I've created this object by hardcoding it or by using an editor. So, how could I create the "first copy"?

Share this post


Link to post
Share on other sites
phil_t    8084


but that implies that somehow I've created this object by hardcoding it or by using an editor. So, how could I create the "first copy"?

 

Yes. That's one reason you must be building a game with your engine as you design your engine. It will help you flesh out design questions like this.

 

Game code could hard code stuff (like a CreateSpaceShip function that creates a GameObject with the required set of Components, and assigns the properties of the Components as needed). Or for a little more flexibility/terse syntax you could define some way to load this info for a text file. Of course, these "prefabs" would only be used when starting a new game or spawning new entities during gameplay (not when loading a saved game).

 

Of course, if you have a world editor with your engine, then this would be the normal way someone developing a game would construct "prefabs".

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this