Sign in to follow this  
azonicrider

Once you go OO, you never go back?

Recommended Posts

azonicrider    421
I was scared to jump into object oriented programming, and avoided it for months when I first began programming. But once I began programming in an OO way, I never wanted to go back to the old days of declaring variables and functions outside of classes.

I guess my questions are:
-Is this average?
-Are there any modern games, that aren't programmed in an OO way?

Share this post


Link to post
Share on other sites
BeerNutts    4400
[quote name='azonicrider' timestamp='1355929195' post='5012448']
I was scared to jump into object oriented programming, and avoided it for months when I first began programming. But once I began programming in an OO way, I never wanted to go back to the old days of declaring variables and functions outside of classes.

I guess my questions are:
-Is this average?
-Are there any modern games, that aren't programmed in an OO way?
[/quote]

When someone "gets" OOP, it's somewhat of an eye opener and what you experience is probably typical. It's a great tool, but don't be fooled into thinking it's the ONLY tool. There will be plenty of times when the correct tool will be a non-class function and variables.

As for any "modern" games programmed in non OO? I'd guess probably not, but not too long ago, (late 90's, early 00's) many big games were done in pure C.

Share this post


Link to post
Share on other sites
Aqua Costa    3691
Actually a "new" paradigm is getting increasingly popular called Data Oriented Design: [url="http://gamesfromwithin.com/data-oriented-design"]http://gamesfromwithin.com/data-oriented-design[/url]

For example, Bitsquid engine uses it: [url="http://bitsquid.blogspot.pt/2010/05/practical-examples-in-data-oriented.html"]http://bitsquid.blogspot.pt/2010/05/practical-examples-in-data-oriented.html[/url]

I've been rewriting some parts of my engine to a more data oriented approach instead of object oriented, and once you start thinking data oriented you'll see a lot that a lot of your object-oriented code could probably run faster if it was data-oriented.

In my opinion, after starting to write OO code, most people fail to write code that takes advantage of the memory cache effectively... Edited by TiagoCosta

Share this post


Link to post
Share on other sites
In some situations, you will want to go back to non-OO for performance reasons. Usually OO is just fine and the overhead (if any) is neglegible. However, in some situations, it can cause adverse effects to processor caches (read up AoS versus SoA), and some OO constructs can sometimes cause significant overhead.

Virtual function calls are an example of a feature that usually doesn't matter at all, but can matter a lot in some situations. In the normal case, you pay a dozen cycles extra for the call in the worst case, mostly because the call cannot be inlined. In the average case, it's often rather something like 3-4 cycles. Burning 3 cycles a hundred times is exactly nothing for a modern CPU.

Now, in the worst case, you do a million calls per frame and the object type varies almost every time, and there are a few types to choose from, so you pay for a data cache miss, a branch misprediction, and an instruction cache miss. Multiplied by a million.


EDIT: Found what I was looking for, there is a good summary on the pitfalls of OO: http://research.scee.net/files/presentations/gcapaustralia09/Pitfalls_of_Object_Oriented_Programming_GCAP_09.pdf

I remember there being another one (if I could find it now... I think it was on Gamasutra or something from GDC) which was much more radical, entirely condemning OO for performance reasons. That's a bit too harsh in my opinion. OO Performance can become a problem, but not if you are a bit savy. Edited by samoth

Share this post


Link to post
Share on other sites
Drathis    141
After you understand OO, you should try functional programming too. Not all languages support it properly, but you can usually manage, even with Java. Learning functional programming will help make your code more maintainable and bug free, even if you use OO. The best part is that you can mix and match OO and FP(though some people think OO and FP are mortal enemies. IMO they are wrong)

Share this post


Link to post
Share on other sites
6677    1054
Well I started in python (without using its OOP features particular), then VB.net and C# which are of course OOP (and I do use OOP for my computer science coursework) but outside of school I've been playing with a little bit of plain C so I have sort of gone into OOP and then out of it again. C is for an embedded device btw, anything I develop for actual usage would normally be C# although I might consider C++ one day.

Share this post


Link to post
Share on other sites
darkhaven3    160
After being a C++ programmer for a little while and dabbling with Java, I have to say that in my opinion object-oriented programming is relatively worthless to me. I honestly don't see why I should ever bother worrying about whether or not a particular set of functions can "see" each other, or whether or not I can make two functions with the same name. Why would I ever want more code obfuscation like that -- two functions with identical names that can do two completely different operations? Why on earth would I ever want such a thing?

But this is of course only my opinion. I'm not unique in the way I think, surely, but I'm also probably not at all a rare, dying species of programmer.

A recent example that I can think of is the IW engine (used in every single major Call of Duty title). It's based directly on the Quake 3 source, so I can imagine it's probably in C still.

Share this post


Link to post
Share on other sites
kunos    2254
I find OO to be a very good fit to represent most of game logic... but it is VERY easy to overdo, especially inheritance; I have seen demented usage of inheritance in my career.
I can say I had my period with OO obsession , now I am enjoying the freedom you get from C++ and understanding that lots of things live much better as loose functions... so I would say no, you actually can go back from OOP, and just use it where it's the best fit for the problem. Edited by kunos

Share this post


Link to post
Share on other sites
Bregma    9199
[quote name='kunos' timestamp='1355938622' post='5012513']
this will become tragically clear once you'll try to debug a big project where everything can talk and modify everything else
[/quote]
QFE

A lot of game code tends to be write-only, but in other programming domains maintenance turns out to be the bulk of the cost of software. Good OO design leads to well-defined interfaces and good decoupling, which in turn leads to improved testability and easier reasoning about the code, which further leads to fewer bugs, fewer staff hours for fixing problems, and less cursing and grumbling (and lower staff turnover).

OO is a very useful design tool. It can be a very useful implementation strategy. So-called Data-Oriented Design is a refinement of OO using many of the techniques pioneered for procedural programming in the 1970s by the likes of Coad and Yourdon and rediscovered recently by people who didn't pay attention in computer science class.

As for the OP, congrats on gaining the OO achievement. Keep playing, the game's not over yet.

Share this post


Link to post
Share on other sites
aclysma    180
[quote name='darkhaven3' timestamp='1355935655' post='5012486']
After being a C++ programmer for a little while and dabbling with Java, I have to say that in my opinion object-oriented programming is relatively worthless to me. I honestly don't see why I should ever bother worrying about whether or not a particular set of functions can "see" each other, or whether or not I can make two functions with the same name. Why would I ever want more code obfuscation like that -- two functions with identical names that can do two completely different operations? Why on earth would I ever want such a thing?

But this is of course only my opinion. I'm not unique in the way I think, surely, but I'm also probably not at all a rare, dying species of programmer.
[/quote]

Most of the projects I've worked on professionally did NOT do much in the way of data hiding. 99% of the member variables in a class were public. It was annoying at times.. every time you reached in to set a value you had to be careful that you wouldn't cause side effects, but ultimately those projects shipped. Unrealscript is an example of an everything-is-public OO implementation.

Data hiding is a good idea. But can you ship without doing it? Yes, definitely. It raises the requirement of others not screwing up when working with your code though. In the case of unrealscript, they made the explicit choice to not hide data for performance reasons of calling a getter/setter (in C++ it's essentially no extra cost due to inlining, but in script.. there was definitely cost.) But that decision was not without other consequence in the form of maintenance hassle. Edited by aclysma

Share this post


Link to post
Share on other sites
darkhaven3    160
[quote name='kunos' timestamp='1355938622' post='5012513']
this will become tragically clear once you'll try to debug a big project where everything can talk and modify everything else.. at that point it becomes really hard to figure out what's going on... this, again, has nothing to do with OOP but more to do with global state and basic programming theory.
Of course, from a programmer's point of view, being able to access every function and every variable feels like a good thing, but it quickly turns into a total mess... and the problem gets bigger as the software gets bigger, so you might get away with it with small code bases.
[/quote]
I think I can safely say that the above is pretty much a nonexistent issue. In C, you cannot "access every function and every variable"; a static int declared within a function remains within the scope of that function, and cannot be overwritten directly. Of course, it's quite possible to do so intentionally, in the same way that it is with any OOP language that doesn't do bounds checking on arrays, if you get where I'm going with that.

If I don't want a function to modify something, I'll pass it a pointer-to-const (i.e. const int* var; ). If I want a variable to be available locally to a function, I will initialize that variable within the function that requires it. Not much more to it than that, honestly. If it comes to a point where data is being modified that I didn't intend to be modified, I can always have a look at that nifty map file the linker generates, which is available to both C and C++ programs. Edited by darkhaven3

Share this post


Link to post
Share on other sites
DekuTree64    1168
You may get stuck in a rut of OO-obsession for a while, but you'll come out eventually as a better programmer :) For me, C++ tends to demand a bit more thorough OO style than I prefer, especially for games. C is like a blank canvas, where you can use OO techniques without having them pushed in your face, and mix and match with other styles less awkwardly. But it works best when coding alone... for group projects, C++ usually works out better in the end. You can still mix and match styles, but do expect to have a high percentage of your code end up as strict OO.

I also agree with Drathis, that OO and functional programming mix surprisingly well. Definitely another good tool to have in the box :)

Share this post


Link to post
Share on other sites
phil_t    8084
[quote name='darkhaven3' timestamp='1355941851' post='5012534']
[quote name='kunos' timestamp='1355938622' post='5012513']
this will become tragically clear once you'll try to debug a big project where everything can talk and modify everything else.. at that point it becomes really hard to figure out what's going on... this, again, has nothing to do with OOP but more to do with global state and basic programming theory.
Of course, from a programmer's point of view, being able to access every function and every variable feels like a good thing, but it quickly turns into a total mess... and the problem gets bigger as the software gets bigger, so you might get away with it with small code bases.
[/quote]
I think I can safely say that the above is pretty much a nonexistent issue. In C, you cannot "access every function and every variable"; a static int declared within a function remains within the scope of that function, and cannot be overwritten directly. Of course, it's quite possible to do so intentionally, in the same way that it is with any OOP language that doesn't do bounds checking on arrays, if you get where I'm going with that.

If I don't want a function to modify something, I'll pass it a pointer-to-const (i.e. const int* var; ). If I want a variable to be available locally to a function, I will initialize that variable within the function that requires it. Not much more to it than that, honestly. If it comes to a point where data is being modified that I didn't intend to be modified, I can always have a look at that nifty map file the linker generates, which is available to both C and C++ programs.
[/quote]

That's an awfully big limitation to put on your data (requiring it to be a static variable in a function).

Also (regarding the const thing), data-hiding isn't just about worrying about modification. If you have a publicly visible piece of data and you change its representation/meaning somehow, you have to worry about everyone who may access that data. Making it explicitly clear who has access to that data really is essential for building/maintaining robust code.

If you work on a large project, you will quickly realize this is not a "nonexistent issue".

Share this post


Link to post
Share on other sites
azonicrider    421
I've tried to understand how Data-Oriented Programming works, but it just doesn't snap into your mind like OOP did.

Also, are there specific languages for DOP, like there is for OOP?

Share this post


Link to post
Share on other sites
Daaark    3553
[quote name='azonicrider' timestamp='1356017511' post='5012816']
I've tried to understand how Data-Oriented Programming works, but it just doesn't snap into your mind like OOP did.

Also, are there specific languages for DOP, like there is for OOP?
[/quote] No specific languages.

There really isn't anything to get with DOP.

In OOP you think about objects and their relationships. This is fine, but the actual instructions that get generated is not optimal for the way modern machines work. The gap between processor and memory speeds has kept getting bigger. So all these abstractions are not making the best use of the current machine architecture.

DOP still thinks about objects and relationships, but puts more emphasis on the actual data, how it is stored, and how it gets read and written to. You think of things as groups instead of singular objects with their own data. When you have to update 10,000 of something, you can just store all those things in one flat list and update them in one go instead of having to hunt down all the memory locations of that variable across those 10,000 objects.

It's how to program something for machines with massive amounts of slow memory instead of small amounts of fast memory.

Share this post


Link to post
Share on other sites
Radikalizm    4807
[quote name='azonicrider' timestamp='1356017511' post='5012816']
I've tried to understand how Data-Oriented Programming works, but it just doesn't snap into your mind like OOP did.

Also, are there specific languages for DOP, like there is for OOP?
[/quote]

DOD isn't all that hard to understand, and while the term 'Data-Oriented Design' might be relatively new, the concepts behind it have been around for quite some time.
Just don't try to learn DOP by comparing it with OOP as that'll make things a lot more difficult for you.

I like to make the comparison between DOD and relational databases since they have a lot of things in common.
When you read papers on DOD you'll always come across a piece of advice which goes something like "Store your data as a struct of arrays, not as an array of structs", and a 'struct of arrays' is nothing more than a regular old table where column data is stored contiguously.
Just like with tables in relational databases this allows you to easily do operations on entire columns in an efficient manner, which is exactly where the strength of DOP lies.
This type of data layout is also very friendly for multithreaded applications, as you can just split up the data set and let multiple threads handle their own chunk of the data at once (this is completely safe since the same operation is done on each data entry anyway).
When a table needs info on a relation stored in another table you can again use an RDB approach by adopting the concept of foreign keys to some extent to allow for proper data encapsulation. This way you can create complex 'objects' (to put it in OO terms) with a DO approach.

I'd advise anyone who wants to learn how to work with Data-Oriented designs to learn about the basic principles of relational databases, maybe learn how to work with SQL at a basic level, and play around with building properly designed databases.
Not all the concepts found in RDBs will be applicable to DOP though, but it could become a possible eye-opener for anyone struggling with wrapping their heads around it.

Share this post


Link to post
Share on other sites
popsoftheyear    2194
Again, keep in mind DOD and OOP are not mutually exclusive.

Using the SoA example, say you have a 3d model resource that stores its vertices. You may store them as a vector of Vec3, or you may store them as 3 separate float vectors. Either way your 3d model resource is hopefully very simple in purpose (SRP) as a container of the necessary data. The way you organize that data is up to you. Now, even in this example, it's not as easy as SoA versus AoS. The 3 vectors of floats might be nice for SIMD usage, but those vectors could be in very different parts of memory. If you are bound by memory transfer rates then the vector of Vec3 (or Vec4) might [i]actually[/i] be a more optimized organization of your data. And SIMD doens't have to be out of the question here because more and more I am seeing horizontal instructions.

DOD is not about doing it this way or that, it is about programming around the best way to organize your data. You have to figure out what "best way" means though, given your situation. [edit] And it doesn't get you off the hook from figuring out how to best organize your code [img]http://public.gamedev.net//public/style_emoticons/default/wink.png[/img]

As another example, think about how you might store a binary tree in a single array...


[quote name='Radikalizm' timestamp='1356020109' post='5012828'][a lot of thoughtful insight]
[/quote]
This sounds to me like a mix of [b]Data Driven Programming[/b] and [b]Data Oriented Design[/b]. Just wanted to make note that they are 2 very different concepts. Edited by achild

Share this post


Link to post
Share on other sites
Radikalizm    4807
[quote name='achild' timestamp='1356021379' post='5012833']
This sounds to me like a mix of Data Driven Programming and Data Oriented Design. Just wanted to make note that they are 2 very different concepts.
[/quote]

I am very well aware that data-driven programming and data-oriented programming are completely different concepts, don't worry about that, I was just trying to create a link between DO concepts and other well-known concepts so it might become easier to understand.
On the matter of data-driven designs, I always hate to compare it with paradigms like OO and DO as these comparisons just don't make sense. It's completely possible to do data-driven programming within the confines of a paradigm like OOP as they're completely orthogonal concepts.

And it's also true that OO and DO are not mutually exclusive, but programmers who think of software purely as interactions between objects (as with OOP) will have a very rough time trying to adapt to DOP as they'll always try to translate the concepts to OOP. Trying to make sense of a data-oriented design with an object-oriented mindset will force you to make a bunch of confusing 'mental jumps', which is something you'll want to avoid when trying to learn something properly.

Share this post


Link to post
Share on other sites
BlueSalamander    966
[quote name='darkhaven3' timestamp='1355935655' post='5012486']I have to say that in my opinion object-oriented programming is relatively worthless to me.[/quote]
I used to think like that but there are some examples where OOP is clearly beneficial. For example look at the scroll bar. With procedural programming, a scroll bar can be implemented with a function plus one or two global or static variables. If you need several scroll bars, you can copy and paste the code and create more global variables. You get more code and you can't change the style of all scroll bars easily.
With OOP, you can implement the scroll bar with a class. If you need several scroll bars, you just declare several instances of the class. You don't need more code or more variables. You can change the style of all scroll bars by modifying the class, and you can create new scroll bar styles easily by using class inheritance.
OOP also helps breaking long functions into small pieces by creating more places where you can logically put the code in.
That being said, I think most roguelike games are made with C and they're not small projects. The advantage of procedural programming is that you can focus on getting tasks done quickly without having to worry about how to package functions and data inside classes.

Share this post


Link to post
Share on other sites

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