• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GML objects inherit vs components

xDGameStudios

GameMaker Staff
GameMaker Dev.
Right now GMS uses a object inherit concept instead of a components concept... this has it's advantages and disadvantages... for example:

right now as everything object is of it's kind and not a combination of components... this enables us to do:

with(object) and run through all the objects of that type... and all it's children ;)

although imagine a structure like this

Code:
Obj_Entity:
       Obj_Moveable
           Obj_Destroyable
       Obj_Static
           Obj_Destroyable
this can not be done with objects Obj_Destroyable can't have to different parents... but sometimes games need this... this is why components are a great deal:

for example:
We have various components: movable, updatable, destroyable... and each one add that property to the object

how would you go on doing something like this?!
the ideia would be to easily and rapidly reference the objects I need, not to implement a full
Entity Component System... more like an hybrid between the two.

well I could create variables:

obj_entity CREATE EVENT:
Code:
destroyable = false;
updatable = false;
moveable = false;
then set it to true when needed:

but if I wanted
updatable objects I would have to use

Code:
with(obj_entity)
{
   if (updatable) {
      // do stuff
   }
}
this would run though all the entities and I would be slower.

Any ideias on the matter?! Thank you in advance ;)
 
J

JFitch

Guest
You could have it update once every few steps instead of once every step.
 
Z

zendraw

Guest
first you must be clear on what the problem is, right now it seems your problem is that 'you wuld be slower'. well what options do you have to be faster? work on those options and who knows, you might get a new and original game mechanic. things arent bad just becouse they dont suit your logic of dealing with stuff.
 

FrostyCat

Redemption Seeker
There's nothing genuinely wrong with the with-if approach --- it's correct and only marginally slower (depending on the distribution of instances with that property set). But if you want to optimize it, you can cache the appropriate instances in a list and iterate though that.
 

dphsw

Member
I haven't thought this through in any great detail, but suppose you make your various Components (inheriting from an obj_Component class if you like, though I can't think offhand what advantages that would give) like obj_movable, obj_upgradable etc., and make them with their various update events, but all their events have their code in a 'with(entity)' block. And then with you initiate an entity that you want to have some of these components, you can do something like:
Code:
myComponents[0] = instance_create(0,0,obj_movable);
myComponents[0].entity = self;
myComponents[1] = instance_create(0,0,obj_upgradable);
myComponents[1].entity = self;
Then all those interchangable components will apply their update methods to the object which instantiated them. It's only the beginnings of a component system (in this simple form it would immediately break if the object that created the components was destroyed, then 'entity' would refer to a non-existent object) but it's certainly possible. Whether it's worth it would depend on the situation.
 

xDGameStudios

GameMaker Staff
GameMaker Dev.
I haven't thought this through in any great detail, but suppose you make your various Components (inheriting from an obj_Component class if you like, though I can't think offhand what advantages that would give) like obj_movable, obj_upgradable etc., and make them with their various update events, but all their events have their code in a 'with(entity)' block. And then with you initiate an entity that you want to have some of these components, you can do something like:
Code:
myComponents[0] = instance_create(0,0,obj_movable);
myComponents[0].entity = self;
myComponents[1] = instance_create(0,0,obj_upgradable);
myComponents[1].entity = self;
Then all those interchangable components will apply their update methods to the object which instantiated them. It's only the beginnings of a component system (in this simple form it would immediately break if the object that created the components was destroyed, then 'entity' would refer to a non-existent object) but it's certainly possible. Whether it's worth it would depend on the situation.

What you are suggesting is that instead of objects having components, components would have objects (putting it simple). That is something I never thought of before!
 

bml

Member
One approach that was described on gamdev.net a few years back used an array of component bitmasks. Each element was a bitmask of all the components for that entity. So your Updateable System world iterate over the array and check the mask to see if the COMPONENT_UPDATEABLE bit was set. If it was, it would apply the update logic to that entity's data. There were also arrays for each component type which would store a reference to the entity if it had that component - this made it fast and easy to reference the entity data. This was in C++ so the goal was to keep the arrays in CPU cache and avoid needless cache misses - I'm not sure it any of this applies to GMS.

With this approach you end up with lots and lots of arrays, but it conceptually make sense because those arrays directly map to your data. It's a giant spreadsheet that defines each type of entity. Now if you want to make entities burnable you add a column to your CSV file that corresponds to COMPONENT_BURNABLE and make the value the burn duration. Paper is 1 second, barrel 10 minutes, a torch 1 hour, campfire 8 hours, etc... Then create a system that checks the burnable components every second. If it's burning add some visual effect, check surroundings because they might be burnable as well and once the duration expires it's destroyed. Also your light system knows that burning things give off light.

I'm thinking each entity is an empty object initially. Each component adds the data fields needed for that component and sets a flag - maybe one instance map. There's no logic in any entity. So a room is mainly system objects and entity objects. There is no obj_enemy. Instead an enemy is something along the lines of any entity that has LIVING and AI components.

I don't know GML/GMS well enough to know what a good approach is. It also feels like ECS might be fighting the system to some degree.
 
Top