Entity system design 101: how to make a game object

a continuation of this abandoned thread:
Generally Accepted Approach to Creating Game Objects - #3 by bacon

i’ve seen:

  1. entity extends Object (inheritance)
  2. entity has an Object (as in: var sprite:Object; composition)
  3. … other ways??? factory? i dunno

is there a preference? especially taking into consideration how Heaps whole scene tree works…?

when i first started, as in the first few days, i just used the inheritance way. It was simple; it got me started quick: just override update(), add it to the scene, and you’re good to go. Then, when i sat down and made a tiny system, i used the second approach. But… now, i’m really not certain which is the way to go anymore.

With the composition way, entity can have multiple Objects (and things that extend it). Let’s say an Anim animation and some Graphics effects. But then, it kinda feels like it’s detached from the scene tree… Like you’d have to handle how all of those Objects are added to/removed from the scene tree / Layers, moved around in the scene tree, etc. I dunno, it’s a fuzzy feeling i’m trying to describe here…

Whereas with inheritance, the entity is an Object itself. And so, if you wanted multiple Objects, you can still add them to the entity, but this way, you’d always have a parent Object (super/this; inheritance parent), as, well, a parent Object (in the scene tree)… It’s more of a 1:1 association to the scene tree… and that somehow makes more sense to me.

huh, well, that’s all my brain has to say about that, for the moment… :confused:

i personally like composition, just to keep the core class clean ‘n abstracted as much as possible, with very few methods to distract me… But that’s not really a good reason, is it? lol.

I don’t even know if it’s worth abstracting Object! As of now, I just keep the Object as a public var, and manipulate it directly, as in myEntity.itsDrawableSprite.x = 123. I mean, with multiple Objects, abstraction would be a pain, no? Should entity.x = 123 change all of it’s objects?.. Or do you keep one Object as a sorta parent Object (scene tree parent, not inheritance parent), for transform purposes only, and make the rest [of the Objects] children?

God halp me. lol.

inheritance actually makes sense. You’d probably want a base Object, so that when you do manipulate it’s transform, entity.move(10, 0), all of it’s children objects are manipulated too… Otherwise, with composition, you’d have to do something like entity.mainObject.move( (unless you wrote wrappers, which i kinda attest).

hrmmmmmm…

for the record, ld40 (Jonathan the Sorcerer) uses composition, deepnight’s gamebase uses inheritance (iirc).

So, Heaps basically spares all game logic structures (like entities/game objects, how things get updated, OOP, entity-component-architecture or “data driven approaches” like ECS) and leaves this question completely open :open_mouth:. In that sense (for the moment) it is only a graphics engine that only cares about providing you with API/classes that handle visualisation.

For 2D there’s actually only h2d.Object that lives on another h2d.Object (you have these “trees” like in Godot or Java and can search in them, give these sub-objects names, which both I’ve never used so far). In the end a h2d.Object must be added to a h2d.Scene (or have a parent h2d.Object that does so). By the way IIRC h2d.Object was even named h2d.Sprite when Heaps launched/started out. But since this class can be a Bitmap, a Flow, a Layer, a Text and many more* it was “abstracted” to a general (visualisation) object.
*(see here, then also click on h2d.Drawable and all it can be while still inheriting from h2d.Object)

In that sense Heaps only provides this kind of visualisation and your game logic is (I would say) totally free from that. This visualisation is a bit advanced, because it also provides h2d.Object.getBounds() so you can check if two h2d.Objects collide, but besides that you can kind of use it or leave it, maybe even draw everything in your game by a h2d.Graphics. (Ok, when you “leave” it, then why bothering with Heaps and even pick OpenGL or Kha etc. Idk)

Game logic means, maybe for performance or abstraction reasons your game pieces (like e.g. your chess figurines :chess_pawn: or figurines on any board game) is only a table of data (who is where and has what name and how many lifepoints), like in ECS (“data driven” instead of OOP), you can still go with Heaps. Heaps only says “Ok, I got this ~sprite~ system, if you want it” and you decide how both is going to cling together.

But keeping it direct and simple: You can add any h2d.Objects to your h2d.Scene and find() an object that matches a name or something. In that sense you don’t need any thinking in terms of “entity” or abstraction at all. Or your hxd.App just saves a list of My_h2dObject_WithUpdateFunction to call their update() function (that you programmed for their class) and you spare this Heaps default search system and maintain your own haxe.ds.Vector for that, and maintain one for trees :evergreen_tree:, one for sheeps :sheep:, one for genies :genie:.

But all talking, I think you just have to see a good sample :smiley: and quick game samples is what we’re just short of… :slight_smile: but I started working on that :cowboy_hat_face:

1 Like

In short, I’m pro composition. (see short code sample below :slight_smile: )


…So in that sense (“graphics” engine) you only have to take care of adding and removing your visuals/sprites from the scene once you no longer need them. Your design pattern 1., 2., 3. have all their pros and cons. Inheritance means Dog can do what Mammal can do, but once you want to design a RobotDog it cannot use features from neither Dog nor Mammal, because its a robot. So instead you could use composition and e.g. do like this instead:

Class RobotDog {
  public var treatAsDog : Dog;
  public var treasAsRobot : Robot;
  ...
  // and for Heaps of course
  public var sprite : h2d.Object; // so we know where to find the sprite on the screen
  // to transform it, remove it later, etc. etc.
}

and you have a rather loose composition (see also comp. over inherit.).

Also with inheritance you may have the problem that when you iterate through a my_animals : List<Animal> and call one of its items, at that point you do not know whether it is a Mammal, a Lizard or even an Ant. You need to cast then (I think) or know by code to find out what kind of animal it is.

Or — instead of inheritance — maybe Animal is just an interface. Then when calling functions like “eat” or “reproduce” it really calls the code from your specific GoldenRetriever class and not only the function in the Animal class and leave it at that. (wait, no. overrides take care of that…)

So in that sense I’m anti-inheritance :sweat_smile: but every programmer is different and every project maybe needs something else. Unless you plan to make an RTS with 2000 people running around on your screen performance can be neglected and you probably can go with any Haxe code you feel the most convenient with.

edit: But when used wisely inheritance is just what you need. In that sense I think the Haxe or Heaps API is a great example (as far as I can tell).

1 Like

wow, lots of good info. thanks again!

…also provides h2d.Object.getBounds() so you can check if two h2d.Object s collide…

yeah i also found the getBounds() thing. I think it can be used to create a simple collision check or even a simple collision system(!), i mean, limited to a rectangular “hit-box”… but otherwise, it seems we have to use hxd.col for any other shape and add that to our own entity ds. For anything more detailed, like a different collision shape for every frame of an animation, which is normal for a fighting a game… well… let’s pray the Anim has something? :sob:

…maybe even draw everything in your game by a h2d.Graphics . (Ok, when you “leave” it, then why bothering with Heaps and even pick OpenGL or Kha etc. Idk)…

lol, sadly, for my first little prototype, i do use Graphics for everything, and the reason to use Heaps is because it provides a very very high-level Flash-like drawing api for it (moveTo, lineTo, drawPoint?, fill, drawShape, etc.). Kha self-claims it’s low-level (but who knows??). i’m quite fond this kind of “drawing”. I don’t really know the difference between “drawing” and “vector graphics”, but that’s really my jam. :smiling_face_with_three_hearts:

…and you spare this Heaps default search system and maintain your own…

yeah, this touches one of the confusing bits for me. The scene tree system is already there, in fact, you must use it to in order to draw anything to the scene… but then, if you create your own entity system, then, you’ve got to maintain a whole ‘nother system, either several containers as you mentioned (genie…etc.) or a few containers and re-create those functions, like find, findByType, findByClass, etc. (or, at least, I already have, in my own EntityList, a special entity container). And then, in the end you have two systems that are quite interlinked, the scene tree system, and the entity system, both full of Objects ‘n Entitites… and i still have to ponder about why it’s better to separate the two :thinking: :thinking: (todo)—in fact, that’s one major difference between inheritance and composition! Inheritance makes use of the already existing scene tree structure… Anyway, I, similar to you, don’t envision using Object’s built-in functions much either… I imagine we’d just track the Entity we’re interested in, not the Object… But maybe it’s useful in finding some lost stray untracked projectile, once in a while?? lol… (it’s nice that they exit though, just in case, especially getBounds…)

btw, i read Component · Decoupling Patterns · Game Programming Patterns, and i just felt that components are excessive for the coding-style of game-making, which Heaps has. For engines that come with a game editor (Godot, etc.), it’s perfect: you just click, add component, alter some properties, etc… but to have an individual component for every entity just feels like overkill. I’m sticking to composition. (—a side question, i wonder how people adjust ‘n fine tune their game vars? is there a tool i’m missing? Console? HIDE? Castle db? Chrome debug? *drools at HaxeFlixel’s debug mode*… maybe Flow, and then reflection on a ds that contains all of the adjustable game vars?)

i haven’t got to the second post, but will read soon! :slight_smile:

update:
yeah, i agree with the composition over inheritance thing in general,even with just a few simple varieties of enemies, things can get outta hand real quick… yet it’s for sure still useful, as a programming feature, as Object proves. The idea that Layers extends Object took me quite a bit to grasp, lol. But it makes sense now…

In the specific case of this topic though, i still think it’s a tough decision: to extend Object or not? :thinking: Beyond the base entity class though, i’d for sure choose composition. No crazy inheritance hierarchies.

that wikipedia article was for sure written by a game dev!! :grinning_face_with_smiling_eyes:

So, now that I made these game sample experiments it seems to me you can just extend any h2d.Object (keep inheritance super simple, no advanced hierarchies) and once you need it use composition like in the short code sample above and you really don’t need any Entity abstraction at all. :open_mouth: / :grinning_face_with_smiling_eyes:

An Entity class can just serve as a single base class when there is really common functionality among your “game pieces/entities/instances” and then it is of course easier to maintain a single class for that. But until that moment you actually use h2d.Object for that.

1 Like

so, as i said in the DMs, a shoot ‘em up game such as the one you just made should definitely be the first game sample anyone sees, for 2D at least, no idea about 3D… (are there even any?? 3D samples?). I think i still need to take another look at the RPG sample…

i’m also still curious as to what was so slow about your simple game… was it really the object.FindAll function?.. :confused: I mean, for it to lag on such a simple game… my god!!. I didn’t think the engine would be so sensitive!.. :woozy_face: That thing needs like a warning to tell people not to use it too much!

here at the end of my game-making session, i think i’ve finally just got into the groove of things(!!!)… I think i’ve already become accustomed to my little composition-style “entity” (—? there’s literally nothing even in the class! :open_mouth: :open_mouth:)… this way multiple Objects can be in the same place, on the same scene tree level, without ever being tied to the local coordinate system of a parent Object. … or maybe you can do that with inheritance… :thinking: i guess i often think of Object having children / not on the same scene tree level… I dunno… I’m just able to think more clearly with the whole scene tree thing just separated :stuck_out_tongue_winking_eye:, especially since i use Graphics to draw stuff using scene coordinates so often…

One big reason for that is: i’ve ditched the new Object(parent) / object.addChild stuff for scene.add(object, layerIndex). Once i discovered Scene extends Layers, i saw no reason to have a separate instance of Layers (for a simple game). Nicholas’s LD40 added an instance of Layers to Scene, and then added all of his entities to Layers, and so when i started, i copied that. But now, I just use the add function, which is inherited from Layers, to add stuff to it’s correct layer. (i still haven’t even thought about layers vs scene tree / Flash-style display list…)

Anyway, i’ve now come to think of Heaps.io as something like MonoGame with a good chunk of MonoGame.extended’s functionalities (note: MonoGame itself is hella bare, even more-so than Heaps—made for the original xbox for god’s sakes!!). What functionality should be included in an engine is a tough call, but, it would definitely be awesome if there were a suite of modular features that you could select…

i think the C# world is similar to the Haxe world, in that there are so few things out there… but even less in this world (i’ve checked the haxelibs). You know, Actuate lib for tween, echo lib for physics, etc. I don’t even know of one for just collision and separation only. But yeah, i think i’m starting to wrap my little head around this whole modular, no-dependency approach to things. It’s all starting to make sense…! lol. This way, HaxeFlixel, HaxePunk, Heaps, and every custom engine out there can work together on the components they share. :slight_smile: :heart: it’s like all one giant ECS!! :open_mouth: :open_mouth: lol

also, kinda off-topic, but: the luxe engine is now in the “preview” stage :open_mouth:. And Depot is like CastleDB, but in your VS Code? Oh baby… game-making is actually going somewhere…!

1 Like

(I placed some answers here in this new thread :wink: )