# Tag Info

66

Favour composition over inheritance in your entity and inventory/item systems. This advice tends to apply to game logic structures, when the way in which you can assemble complex things (at runtime) can lead to a lot of different combinations; that's when we prefer composition. Favour inheritance over composition in your application-level logic, everything ...

18

You got a few nice answers already, but the huge elephant in the room in your question is this one: heard from someone that using inheritance must be avoided, and we should use interfaces instead As a rule of thumb, when somebody gives you a rule of thumb, then ignore it. This not only goes for "somebody telling you something", but also for reading stuff ...

17

As long as you keep your system relatively simple, this should work. But when you add things like temporary skill modifiers, you will soon see a lot of duplicate code. You will also run into problems with different weapons using different proficiencies. Because each skill is a different variable, you will have to write different code for each skill-type ...

16

I can't imagine designing a game without using object oriented programming, because my entire understanding of how to design a game-program is based on OOP. Then it will probably be good for you to try writing some programs in non-OO style. Even if you discover that this is not pragmatic for you, you'll probably learn a lot along the way that will help you ...

13

Your IDs should be a mixture of index and version. This will allow you to reuse IDs efficiently, use the ID to quickly find components, and makes your "option 2" much easier to implement (though option 3 can be made much more palatable with some work). struct entity { uint16 version; /* and other crap that doesn't belong in components */ }; std::...

13

The idea that inheritance must be avoided is simply wrong. There exists a coding principle called Composition over Inheritance. It says that you can achieve the same things with composition, and it's preferable, because you can reuse some of the code. See Why should I prefer composition over inheritance? I have to say I like your weapon classes and would ...

12

Any object-oriented program can be refactored to a procedural program by replacing all classes with structures and converting all member-functions into stand-alone function which take the object which would be this as an argument. So missile.setVelocity(100); becomes setMissileVelocity(missile, 100); or when that function is trivial, you just do ...

10

Short answer: Entity Component System (ECS) is not a part of OOP. The discussion that most influenced my understanding of Entity Component Systems is on T-Machine and an example framework inspired by this discussion useful for reference is Artemis. One of the fundamental concepts of OOP is encapsulation - application design breaks the domain into objects ...

8

Your approach is fine, and was used widely by game developers of the past. You see with inheritance hierarchy you often find yourself in a situation there you want inherit from a multiple classes, but they don't usually mix well (including The diamond problem). Because of that, a component based architecture is being widely adopted. One variation of this ...

8

It is perfectly possible to mix both styles. The same GameObject can have some of its functionality implemented with the new ECS system and other functionality in classic MonoBehaviour events. What Unity recommends in their ECS tutorial is in fact to start with a project which uses the old style and then look for features which you think would benefit from ...

7

You're correct that the problem (well, nuisance) is the if statements. Sadly, no matter what language your working in or what programming fanciness you employ you are going to have to check some component data / entity types / other flags on the colliding entity that will tell the present entity how to react to a collision. Good Practices (my experience) ...

6

I do it as follows: All OOP classes/methods have access to this. In order to utilise this in a non-OO approach, simply pass in whichever instance (see next point) this should be, as the first parameter. Now, as for instances, you can pass structs into your functions as this, but I find the best way to achieve good cache performance for objects which are ...

6

As you've noticed, there are pros and cons to each architecture scheme. Each pattern has its own implications for how objects will interact, and when. First, I'd recommend a quick refresher on SOLID design. Now, what we strive to accomplish with good architecture is enough abstraction that we aren't hampered by the system when we want to add a feature. If ...

6

Inherit from sf::RenderWindow SFML actually encourages you to inherit from its classes. class GameWindow: public sf::RenderWindow{}; From here, you create member draw functions for drawing entities. class GameWindow: public sf::RenderWindow{ public: void draw(const Entity& entity); }; Now you can do this: GameWindow window; Entity entity; window....

6

A rule of thumb is that you use different classes when objects require different code and instances of the same class when the objects only require different values. So when ShortBow, HuntingBow, CompositeBow, ElvenBow etc. all behave identical except for having different stats, then they would all be instances of the same class. When bows have different ...

6

Taking the example of the guitar: (...) a player you can, for example, not only play on guitar as a Musical Instrument, but use it as a Weapon or, what is perhaps more unobvious, throw it right to the furnace to get some heat in a cold winter night. First off, move away from using object inheritance to model this. Although, I want to note that using OOP is ...

6

The problem is that inheritance leads to coupling--your objects need to know more about each other. That's why the rule is "Always favor composition over inheritance". This doesn't mean NEVER use inheritance, it means use it where it's completely appropriate, but if you are ever sitting there thinking "I could do this both ways and they both kind of make ...

5

Four points to make, including an answer to your question: 1) There is nothing non-OOP about entity systems. Data-oriented programming is incompatible with bad over-use of poorly designed interfaces common to most mediocre OOP programming styles, but otherwise good data-oriented component systems (including entity systems) are quite naturally fit into an ...

5

In object-oriented programming, you expose private data with getter-methods. When your player-class wants to know the terrain-type of a tile, it would call level.getTerrain(int x, int y). That public function of class Level would access the private terrain array and returns the value of the terrain tile. When you don't want the player-class to depend on ...

5

AI being costly, performance is often the driving factor in architecture. To ease your concerns around data access models, let's consider a few different AI examples both in- and outside of the games industry, working from that which is furthest from human navigation to that which is most familiar to us. (Each example assumes a single, global logic update.)...

5

A singleton works. A global works. I'll stand by that statement. I don't think they're the best solution for this particular case, though. Yes, you can put all your GameObject instances into a World of some kind. The World then likely needs to be managed by an object if you plan to have more than one of them, e.g. some kind of WorldManager. This manager ...

5

No. Grass, Sand and Water aren't different TYPES of tiles, they are different tiles. i.e. class Tile { private: Sprite sprite; bool collidable; bool flamable; bool walkable; public: Tile(Sprite s, bool col, bool flam, bool walk) { this.sprite = s; this.collidable = col; this.flamable = flam; this.walkable = walk; } bool ...

5

obsessed with OOP What you've described isn't OOP. It's an abuse of inheritance, which is frequently attributed to OOP, but isn't an inherent part of the paradigm. :) My question is, what is the cost of using polymorphism in this way? Virtual function calls are slower than regular calls, and much slower than directly accessing data members, but are not ...

4

When designing an item system, or in reality any system requiring collections of whatever, you should begin by considering what type of functionality is shared by all objects in these collections. For instance, all items may need to be rendered to the screen, all items have a quantity, all items require collision detection, etc. So starting with this, begin ...

4

Why not use associated arrays?, this gives the benefit of being easily extended (using PHP for example) $Stats["Strength"] = "8";$Stats["Dexterity"] = "8"; for things such as weapons, you would probably want to create some base classes Weapon -> MeleeWeapon, RangedWeapon and then create your weapons from there. The end result I would aim for is a class ...

4

"My goal was to teach them the fundamentals of C++ using OOP", following this, I think you're making the right choice. I find the OpenGL API doesn't lend itself to OOP( in the programming sense, anyway ) very well. I'm surprised you're even exposing 12th grades to C++ and OpenGL. Most university courses I've seen avoid both of these like the plague. So, yes,...

4

Take the following relations into account A team has players Team Red is a team A player is associated with a team So, the following approach should give you a good hint. Team Red and Team Blue are instances of a team, with the same attributes but they just differ in values. Unless you need to implement different behaviors (member functions) for each team,...

4

Generally speaking, you will need a separate draw call for each set of objects that have a different material (by material I mean a different shader, texture or other shading parameters). So the obvious approach is to group objects that have the same material, so that they can be rendered together, avoiding the expensive state changes. This is normally done ...

Only top voted, non community-wiki answers of a minimum length are eligible