Design Object Inheritance/Structure Design

samspade

Member
Let's say you're making a basic 2D metrovania style game and you have the following things which damage the player:
  • Spikes (doesn't move, can't be killed)
  • Pillars of Fire (move up then down, can't be killed)
  • Arrows (move left to right, can't be killed)
  • Falling Spikes (move down, can't be killed)
  • Stationary Enemy (doesn't move, can be killed)
  • Walking Enemy (moves back and forth, can be killed)
  • Flying Enemy (flies back and forth, can be killed)
  • Jumping Enemy (moves up then down, can be killed)
Damage is dealt during a collision and the player has iframes.

How would you structure the objects, inheritance and code wise? What would you consider objectively good or bad structure?

The one thing all the above share is the ability to damage the player through contact. I see a couple unshared elements - movement (state change) and hp (ability to die) - which can also be generalized as requiring an update.

I see a couple primary options for division.

Option 1 - Inheritance
Structure is done through inheritance. You would have a primary parent contain the code for damaging, immediate children for those that don't need hp, a sub parent for enemies with hp with children to contain their own movement. Movement code could be scripts if they were identical.

Example (tabs mean children):

enemy_parent (contains the damage player code)
Spikes
Pillars of Fire (movement code)
Arrows (movement code)
Falling Spikes (movement code)
enemy_with_hp_parent (contains hp code)
Stationary Enemy (movement code)
Walking Enemy (movement code)
Flying Enemy (movement code)
Jumping Enemy (movement code)​

Option 2 - Components
Structure is done through components. Where the damage masks and hp are separate objects created and connected to any object in the create event. Here you wouldn't need inheritance at all for hp or damage freeing up inheritance for use in other ways (e.g. similar movement code, or more complicated state changes with enemies, etc.).

Example:
damage mask (contains the damage player code)
hp obj (contains code to track hp and destroy connected obj)

Spikes (gets a damage mask attached)
Pillars of Fire (gets a damage mask attached)
Arrows (gets a damage mask attached)
Falling Spikes (gets a damage mask attached)
Stationary Enemy (gets a damage mask and hp obj attached)
Walking Enemy (gets a damage mask and hp obj attached)
Flying Enemy (gets a damage mask and hp obj attached)
Jumping Enemy (gets a damage mask and hp obj attached)

Preferences on the above or other choices entirely?
 

Mert

Member
Although I don't know how the internal codes of objects goes, I can surely say that you must avoid objects as much as possible!

Each object comes with a heavy burden, including almost 50 variables. In most of the time, you don't even need almost all of them. That's why professional coders here implement their own "entity system" where we imitate Game Maker objects in lighter way. (Also notice that Yoyogames is bringing lightweight objects to Game Maker in the following months)

You can create everything that an object can have via code on runtime(OR sometimes on compile via YYC commands)

In my current 3D Moba project, I only have three objects and I can have millions of entities within my room.
 

samspade

Member
Although I don't know how the internal codes of objects goes, I can surely say that you must avoid objects as much as possible!

Each object comes with a heavy burden, including almost 50 variables. In most of the time, you don't even need almost all of them. That's why professional coders here implement their own "entity system" where we imitate Game Maker objects in lighter way. (Also notice that Yoyogames is bringing lightweight objects to Game Maker in the following months)

You can create everything that an object can have via code on runtime(OR sometimes on compile via YYC commands)

In my current 3D Moba project, I only have three objects and I can have millions of entities within my room.
I understand the basics of using a single GM object to handle multiple 'game objects' but wouldn't you still want to come up with some way of structuring the above in that system?
 

Yal

šŸ§ *penguin noises*
GMC Elder
I usually have "parent_damage" (damages player on contact) which parents hitboxes, spike traps etc, and then "parent_enemy" (can be killed and drop loot). GM's structure doesn't lend itself too well to aspect-oriented programming, but you could always have generic behavioral scripts that doesn't assume anything about the object they're being used by (perhaps with a companion setup script that sets up its required variables), and put an arbitrary number of them in the object's step event.
 
Top