Sign in to follow this  

Object Oriented Game Programming

This topic is 4861 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

So working on my game engine, I've been finding myself using a whole lot of object oriented concepts. I've got plenty of inherited classes, some interfaces, and just a lot of other things to take advantage of C++. Then the other day I was browsing threw LaMothe's book Tricks of the Win Game Programming Gurus, and he said to limit your useage of it, to not go "class crazy." Personally, I love how organized my code is. I realize that sacrafices a little speed here and there, but I'm not working on Half Life 2 here, so it not that big of a deal is it? And to tell you the truth, I can't imagine the guys at Valve would be writing in straight C anyway. I respect LaMothe's opinions greatly, but this comment of his seems counter-intuitive to me. But since I don't have much expeirence my intuitions much be misguided. So for all of you who have been game programming for years now, what do you think about using a lot of object oriented techniques in your code?

Share this post


Link to post
Share on other sites
i haven't been OO game programming for years.
but i feel that you shouldn't use every OO technique there is.
whether it's for speed or for plain readability.

some people on this boards (and there's very few) tend to use techniques just because they can and the techniques has no real impact on their game.

singletons, polymorphism, 3 level inheritance, virtual functions every which way... is alot of that necessary? even in a 3D game (Q1 level game)?

oh well, just my opinion.

Share this post


Link to post
Share on other sites
I've found that interface based design usually is more flexible and easier to understand and refactor than implementation inheritance or deep inheritance hierarchies.

I e, I wouldn't have "Thing" from which "MovableThing" and "StaticThing" derive, from which "MovableLivingThing" and "MovableVehicleThing" derive, ... "Actor" ... "Player". Because, suddenly I'd realize that "Horse" is a "MovableLivingThing" but can be ridden, just like "Car" that's (indirectly) a "MovableVehicleThing".

Instead, there would be "Thing", and then you query for specific optional interfaces, such as "Ridable" and "Movable".

Anyway -- this is still object oriented design, just applied differently. "OO" is a very broad and loose concept, and applied appropriately, it helps organize most code bases. I think LaMothe is saying "apply it appropriately".

Share this post


Link to post
Share on other sites
Lamothe is a good guy for sure and I own alot of his books. However, lately I've come to believe he isn't as great as alot of people think (myself included, once upon a time.) After all, if he were such a great programmer he'd probably be programming new and exciting things rather than re-hashing the same old books over and over.

Anyhow, I don't think his oppinion deserves as much wieght as people want to give it sometimes. OOP has its place, it sounds as though you're using it right to me. There is such a thing as "class crazy" though, where everything and every variation becomes its own class, thats what you want to avoid.

The classic example is weapon classes, you don't need a seperate class for every single weapon, it usually suffices to have an umbrella class which has properties describing how each sub-unit is different. IE- a dagger does 5 damage while a broad sword does 50. Damage is a property of a weapon and doesn't need a whole new class just for that.

OOP is a tool, just like anything else, but as the old adage goes: When all you've got is a hammer, everything starts to look like a nail. Realize that there are alot of tools and techniques at your disposal.

Share this post


Link to post
Share on other sites
Quote:
Original post by hplus0603
I've found that interface based design usually is more flexible and easier to understand and refactor than implementation inheritance or deep inheritance hierarchies.

I e, I wouldn't have "Thing" from which "MovableThing" and "StaticThing" derive, from which "MovableLivingThing" and "MovableVehicleThing" derive, ... "Actor" ... "Player". Because, suddenly I'd realize that "Horse" is a "MovableLivingThing" but can be ridden, just like "Car" that's (indirectly) a "MovableVehicleThing".

Instead, there would be "Thing", and then you query for specific optional interfaces, such as "Ridable" and "Movable".

Anyway -- this is still object oriented design, just applied differently. "OO" is a very broad and loose concept, and applied appropriately, it helps organize most code bases. I think LaMothe is saying "apply it appropriately".


The phenomenon you are describing here seems a huge lot like interfaces. Instead of having:


Thing
MovableThing
RidableThing

[oops] Car

you have:


Thing,
IMovable,
IRidable

Car : IMovable, IRidable

I prefer to use the last one which is very comfortable and easy to implement, so, I second hplus.

/edit:
Forgot to add that a certain base class is usefull for ingame objects, so the default behaviour doesn't have to be rewritten everytime

Share this post


Link to post
Share on other sites
Quote:
Lamothe is a good guy for sure and I own alot of his books. However, lately I've come to believe he isn't as great as alot of people think (myself included, once upon a time.) After all, if he were such a great programmer he'd probably be programming new and exciting things rather than re-hashing the same old books over and over.


I have to disagree with you there. I'm sure people give Lamothe more credit than necessary but he's still a helpful person, and a lot of his books are helpful especially to beginners.

I do disagree with his use of straight C though. Alpha_ProgDes
if you feel you've organized your code efficiently, and haven't done a lot of advanced OOP features to waste, then that's good for you.

Lamothe may code in straight C, but it's pretty easy to convert the concepts he gives you and how to implement them, so you can use them in your own C++ code.

Quote:
Anyhow, I don't think his oppinion deserves as much wieght as people want to give it sometimes. OOP has its place, it sounds as though you're using it right to me. There is such a thing as "class crazy" though, where everything and every variation becomes its own class, thats what you want to avoid.


Another thing you have to take into consideration Alpha_ProgDes. A lot of things out there don't need to be classes or use all the versatility that C++ offers. Certain thigns can be static arrays, or plain old structures. Keep that in mind, develop your own style that works for you and is cool and you'll be all good.

Share this post


Link to post
Share on other sites
Quote:
Original post by hplus0603
I've found that interface based design usually is more flexible and easier to understand and refactor than implementation inheritance or deep inheritance hierarchies.

I e, I wouldn't have "Thing" from which "MovableThing" and "StaticThing" derive, from which "MovableLivingThing" and "MovableVehicleThing" derive, ... "Actor" ... "Player". Because, suddenly I'd realize that "Horse" is a "MovableLivingThing" but can be ridden, just like "Car" that's (indirectly) a "MovableVehicleThing".

Instead, there would be "Thing", and then you query for specific optional interfaces, such as "Ridable" and "Movable".


can you please explain this more... right now in my game im doing what you describe... i have Thing from which MovableThing and StaticThing derive, etc.....

"Instead, there would be "Thing", and then you query for specific optional interfaces, such as "Ridable" and "Movable"."

what do you mean by this? exmaples and stuff would help. thanks a lot!

also, you write:

"I've found that interface based design usually is more flexible and easier to understand and refactor than implementation inheritance or deep inheritance hierarchies."

could you explain what the interface based design and implementation inheritense / deep inheritense is? thanks a lot!

Share this post


Link to post
Share on other sites
There are two kinds of inheritance, basically: inheritance of interface (the kind you get in Java when you use keyword 'implements', or in C++ when you inherit a completely pure-virtual class), and inheritance of implementation (the kind you get in Java when you use keyword 'extends', or in C++ when you inherit in general).

"Interface-based design" basically means that you are making more use of the former. You might also inherit implementation here, and use multiple inheritance of implementation (in C++), but you are then thinking of the inherited classes more as "mix-ins". Personally, I prefer to handle these by object composition and delegation. "delegation" and "polymorphism" are basically the key (and orthogonal) concepts here; "inheritance" and "composition" are both ways of obtaining "delegation" and "polymorphism". (By doing object composition, you can acheive more flexibility in your polymorphism without shattering your brain or using weird things like virtual inheritance; but at the cost, generally, of having to do delegation manually.)

"Deep inheritance" is not a technical term, it just means that your tree of inherited classes is rather tall. I.e. you have A which inherits from B which inherits from C which ... etc. so that there are several layers. (LOL, I remember when I was first learning to program in BASIC, and my teacher asked me if I wanted to see a "long program", and I thought that was a technical term for some reason! It wasn't even that long, a couple thousand lines maybe, but back then when you could still find Commodore 64s in use, it seemed pretty substantial.)

Share this post


Link to post
Share on other sites
There's a tendency for people to get wrapped up in the object oriented design paradigm as if it were a religious practice. I think the best advice anyone can give you is that you shouldn't stress over it. There's a thing called analysis paralysis, and I see too many people fall into it. It's very easy to do when you sit down to architect the perfect design using the latest and greatest OO concepts.

Using OO design concepts can go a long way in improving the maintainability and extensibility of your code base. The Unreal Engine is an excellent example. But they designed it that way from the beginning because they wanted an engine that they could port to several platforms, use again and again for several years, yet still be able to easily upgrade. The architecture they came up with would likely have been less flexible had they taken a different approach.

I'm sure that the design goals of most people around here do not fall in line with Epic's goals for the Unreal Engine. In most cases people are just wanting to make a game and learn something in the process. In that case, I say do what feels right. Get it done. Good software design, whether you use OO concepts or not, comes from experience with software design. Using OO techinques can still lead to a pile of spaghetti very easily (look up the terms tight coupling and loose coupling). Spending all of your time designing an engine, then throwing it out and doing it again because you over engineered yourself into a corner, is less time pumping out a game.

If you remember that Object Oriented design does not mean using classes (you can easily apply OO techinques to C, you just don't get built in support to make the implementation easier), and if you keep in mind that the best design is the one that allows you to meet the goals of your project (whether that be the Unreal Engine or a Tetris clone), then there's nothing to be concerned about. Eventually, you start to see the benefits of certain design concepts and, more importantly, learn to recognize where to apply them.

Quote:

So working on my game engine, I've been finding myself using a whole lot of object oriented concepts. I've got plenty of inherited classes, some interfaces, and just a lot of other things to take advantage of C++.


Two things stand out about these two sentences that I think are the wrong attitude.

The first is the fact that you are making a game engine. Too many people sit down to make a game and think the first thing they need to focus on is a 'game engine'. I say, you need to focus on the game. There are many legitimate reasons to make a 'game engine' (to license to others, to support multiple future titles, for the learning experience). But for most people on these boards who are still learning, I think the best thing to do is to forget even the concept of 'engines' and just make the game. Make as many games as you can. This will lay the foundation you need, not just on the implementation details (like graphics algos), but more importantly for design. Building a game engine that you aren't likely to use again, or even complete, is a waste of time. Coming at it with insignts gleaned from slapping together four or five games will improve not only the chances of completing it, but also of having something that can be easily reused and extended.

The second thing is this bit:

Quote:

I've got plenty of inherited classes, some interfaces, and just a lot of other things to take advantage of C++.


Never implement features just to take advantage of the language. Instead, use the language features to the advantage of your project. Inheritance and interfaces are quite useful - in specific cases. For example, there are some cases when composition is a better solution to a problem than inheritance. You need to choose the language features that meet your design needs, not shoehorn your design to make room for the features. It's very easy to bloat your code with things you don't need. Every design decision should be given careful consideration. This is the sort of thing which comes with experience, of course. All of the threory in the world is useless until you've actually applied it and seen the results firsthand.

Quote:

what do you think about using a lot of object oriented techniques in your code?


It's not about using 'a lot of object oriented techinques'. It's about applying design solutions to design problems. Some people go to such extremes to follow 'good OO design' (I have yet to figure out exactly what they're on about) that they do the silliest things. I could rant on and on about the silly things people do to achieve OO nirvana. Let me tell you - it doesn't exist. Layout the requirements for your project, spend some time to determine how you are going to meet those requirements, implement, profile, debug, refactor, move on to the next project. Let others squabble about the finer details of public vs. private member variables.

Share this post


Link to post
Share on other sites
I think things are a matter of style. I wouldn't really take to heart when people say "don't use OOP for this" and "use it for that."

It's not like people couldn't do things in the older days with straight procedural languages. There were work arounds/methods to do the things that were needed. Some things are more convenient now, some things haven't changed a whole lot, etc. I rather think it really just comes down to style.

Maybe LaMothe was just saying that, speaking to beginners, so you don't overwhelm yourself. To not make things more difficult than they need to be!

Personally, I use C++ for it's organization and principles, it clicks in my mind a little easier. Everything I do in classes, I could do just as easily without. I do avoid using a lot of inheritence and what not, because I really don't warrent it as necessary most of the time. I try to remain more "bottom up" in my approach, in that I don't try to think of ways stuff should be inherited, rather, I think of what I need to do, what works well, and then just do it (which usually means keeping things separate, but still organized).

At times, it is useful to use inheritence and other bells and whistles, and at those times, it will be there for me. I think that's the point (and basically refers back to your style). But I try to stay as simple and grounded as possible, to not.. maybe, paint myself in a corner? ;)

Share this post


Link to post
Share on other sites
Okay, Aldacron really drove the point I was going to make home (Somehow I missed that huge post).

One thing I'd like to emphasize in his post, specifically:

Quote:

...the best thing to do is to forget even the concept of 'engines' and just make the game. Make as many games as you can.


I've noticed a similar trend. I see lots of questions being asked about game engine design... I even hear people talk about between my geek friends. It always kind of iffed me, but I could never really say why.

I think people should write games first, and after they have written a few games, worry about code reuse (they are going to reuse code anyway!) to make projects faster an easier.

Honestly, most code reuse isn't about writing it so it's the primo-perfect type-safe and generic engine. Since games all tend to require special parameters/features/design, I'd worry about the concepts of the game, and not the generic engine; since you might have to do some heavy customization anyway.

Good post Aldacron. Definately worthy of a rate up!

Share this post


Link to post
Share on other sites
The right tool for the job, i say.

Quote:
Some people go to such extremes to follow 'good OO design' (I have yet to figure out exactly what they're on about) that they do the silliest things. I could rant on and on about the silly things people do to achieve OO nirvana


That's a good point. There are some serious "paradigm zealots" out there. For instance, some people will rip your arms out of their sockets for for using a Singleton because it "breaks encapsulation" or for using a global variable because it "pollutes the the global namespace". These are mostly theoretical arguments. They don't make your program better or worse. Now some design patterns have some serious merits, but often everything is a tradeoff. OOP is no exception. OOP is theoretically slower than just throwing everything in the global namespace, but that would of course be horribly unmaintainable. That's the tradeoff.

So when you sit down to program a componant, you need to think "What design pattern will make this work the way i want?" and not "How can i solve this using inheritance?"

And of course, the more you know, the more tools you have. Some people are advocates of XYZ technique because all they know is XYZ technique and it works for them. I'm guilty of that too. But if you also know ABC and 123 technique, you can choose the right tool for the job.

Share this post


Link to post
Share on other sites
Quote:
Original post by catch
Personally, I use C++ for it's organization and principles, it clicks in my mind a little easier. Everything I do in classes, I could do just as easily without. I do avoid using a lot of inheritence and what not, because I really don't warrent it as necessary most of the time. I try to remain more "bottom up" in my approach, in that I don't try to think of ways stuff should be inherited, rather, I think of what I need to do, what works well, and then just do it (which usually means keeping things separate, but still organized).


Well, yeah, when I say I've been taking advantage of C++ features, I'm not just doing it for the sake of using them. I've been programming in C++ for about 6 years now, and Java for 3, so all of the object oriented constructs in the language are pretty natural and intuitive to me.

I don't turn everything into a class, just before I start developing a new aspect to my engine I'll usually think of an aspect as an object. Also, if some inheritance seems blatently obvious, I'll use that too. Yet if something's simple and turning it into a object or inheriting it from something doesn't occur to me immediately, there's no way I'd go out of my way just to take advantage of OOP.

Anyway, I agree with what you've all said, just after hearing that remark for LaMothe, I was wondering if the game development community frowned upon it, since all of his examples seem to shy away from them. But I suppose you're right catch, I'm not reading the book as a beginner to C++, so I'm not thinking that LaMothe probably discourages it as to not overwhelm his readers.

Quote:
Original post by catch
I think people should write games first, and after they have written a few games, worry about code reuse (they are going to reuse code anyway!) to make projects faster an easier.


Yeah, by "engine" I'm not talking about an extremely robust framework, just some basic things like sprites, animation, fonts, textures, just some simple things. As an experiences programmer, I tend to like the idea of building a basic framework to make implementing the many ideas I have without much hassle. Sure I'm going to have to make a lot of modifications as I run into problems in my game, but persoanlly I'd rather do that then make an sort of composite engine based entirely off of "lessons learned." Still that's just a personal preference of mine - but I would recommend it to an experienced programmer since you'd be more able to anticipate the features you'll need and be able to implement modular code without starting on projects first.

Share this post


Link to post
Share on other sites

This topic is 4861 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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