Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411423 Posts in 69363 Topics- by 58416 Members - Latest Member: JamesAGreen

April 19, 2024, 01:13:03 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)The grumpy old programmer room
Pages: 1 ... 266 267 [268] 269 270 ... 295
Print
Author Topic: The grumpy old programmer room  (Read 738208 times)
gimymblert
Level 10
*****


The archivest master, leader of all documents


View Profile
« Reply #5340 on: June 17, 2017, 12:22:14 PM »

Personally, even though I haven't completed a full complex game due to difficulty with architecture, BUT I see myself sleeping in what I call teh breadboard model, I don't know if that make sense. But basically I create unit that are very self contain with clear input and output, ie basically electronic component. Since every project need some specific coupling, I have dedicated objects to handle the coupling that is the breadboards, ie it connect the elements with very specific direct link, ie dogs don't know about cat but the breadboard does and handle any exception self contained in its definition. Breadboard can be nested. It's similar to the componenent system, as I understood it, but instead of having external system, the breadboard handle the codes, it's basically the bag of links. Not sure if best practice lol, but for now it's what works best for me and allow to separate modular part against specific/exception. In the end it's the exception that is the identity of teh objects, what makes it unique.

Isn't it the same principle of ECS what you're mentioning? I favor components over OOP first if I can. There are cases that it is better to refactor when you have 20+ components attached to an actor, performance-wise also. For example an actor in Unreal Engine 4 doesn't like too many components attached.

Well component is usually for defining "objects" with more flexibility. Breadbords is about interaction between objects, ie they define the "world".

Component allow to compose, "dog", "cat", "tiger", base on similar component without having the divergence you can have in real world situation, while class inheritance tend to favor union. Basically if you want a flying dog or a dragon you are kind of screw and need more abstract class to cover bird, magic bestiaries and quadruped.

Breadboard solve cat bite dog. At least in my perspective, nothing is really solid, I don't have enough practice.
Logged

JWki
Level 4
****


View Profile
« Reply #5341 on: June 17, 2017, 11:16:59 PM »

Personally, even though I haven't completed a full complex game due to difficulty with architecture, BUT I see myself sleeping in what I call teh breadboard model, I don't know if that make sense. But basically I create unit that are very self contain with clear input and output, ie basically electronic component. Since every project need some specific coupling, I have dedicated objects to handle the coupling that is the breadboards, ie it connect the elements with very specific direct link, ie dogs don't know about cat but the breadboard does and handle any exception self contained in its definition. Breadboard can be nested. It's similar to the componenent system, as I understood it, but instead of having external system, the breadboard handle the codes, it's basically the bag of links. Not sure if best practice lol, but for now it's what works best for me and allow to separate modular part against specific/exception. In the end it's the exception that is the identity of teh objects, what makes it unique.

Isn't it the same principle of ECS what you're mentioning? I favor components over OOP first if I can. There are cases that it is better to refactor when you have 20+ components attached to an actor, performance-wise also. For example an actor in Unreal Engine 4 doesn't like too many components attached.

OOP != inheritance and component systems don't conflict with OOP. Unreal is EXTREMELY object oriented and so is their actor component system.
Logged
Ordnas
Level 10
*****



View Profile WWW
« Reply #5342 on: June 19, 2017, 06:30:34 AM »

Well component is usually for defining "objects" with more flexibility. Breadbords is about interaction between objects, ie they define the "world".

Component allow to compose, "dog", "cat", "tiger", base on similar component without having the divergence you can have in real world situation, while class inheritance tend to favor union. Basically if you want a flying dog or a dragon you are kind of screw and need more abstract class to cover bird, magic bestiaries and quadruped.

Breadboard solve cat bite dog. At least in my perspective, nothing is really solid, I don't have enough practice.

Are there any risks that, using the Breadboard method, you could end to write a very long "function library", in case there are a lot of different classes in the project? Also this library needs to be maintained every time a class changes or removed.

You could write the "function library" using templates (in C++), but then you have to be careful to what objects can interact with (use a function to define damage when cat bites a dog, but not a chair bites a cat because it makes no sense).
Logged

Games:

Photon
Level 4
****


View Profile
« Reply #5343 on: June 21, 2017, 06:41:55 AM »

Well component is usually for defining "objects" with more flexibility. Breadbords is about interaction between objects, ie they define the "world".

Component allow to compose, "dog", "cat", "tiger", base on similar component without having the divergence you can have in real world situation, while class inheritance tend to favor union. Basically if you want a flying dog or a dragon you are kind of screw and need more abstract class to cover bird, magic bestiaries and quadruped.

Breadboard solve cat bite dog. At least in my perspective, nothing is really solid, I don't have enough practice.

Are there any risks that, using the Breadboard method, you could end to write a very long "function library", in case there are a lot of different classes in the project? Also this library needs to be maintained every time a class changes or removed.

You could write the "function library" using templates (in C++), but then you have to be careful to what objects can interact with (use a function to define damage when cat bites a dog, but not a chair bites a cat because it makes no sense).
I suppose I'd be interested in how you'd implement such a breadboard, at least in a way that's different from what's already been done.

Also, perhaps I'm just too ingrained in OOP terminology, but I'm a little confused when I hear people say they don't like using objects. As opposed to what? Global variables?
Logged
JWki
Level 4
****


View Profile
« Reply #5344 on: June 21, 2017, 08:23:36 AM »

Well component is usually for defining "objects" with more flexibility. Breadbords is about interaction between objects, ie they define the "world".

Component allow to compose, "dog", "cat", "tiger", base on similar component without having the divergence you can have in real world situation, while class inheritance tend to favor union. Basically if you want a flying dog or a dragon you are kind of screw and need more abstract class to cover bird, magic bestiaries and quadruped.

Breadboard solve cat bite dog. At least in my perspective, nothing is really solid, I don't have enough practice.

Are there any risks that, using the Breadboard method, you could end to write a very long "function library", in case there are a lot of different classes in the project? Also this library needs to be maintained every time a class changes or removed.

You could write the "function library" using templates (in C++), but then you have to be careful to what objects can interact with (use a function to define damage when cat bites a dog, but not a chair bites a cat because it makes no sense).
I suppose I'd be interested in how you'd implement such a breadboard, at least in a way that's different from what's already been done.

Also, perhaps I'm just too ingrained in OOP terminology, but I'm a little confused when I hear people say they don't like using objects. As opposed to what? Global variables?

No not global variables.
Not using objects, or more fitting, not using OOP means not using methods, not using inheritance, not using data hiding (private and protected fields) and most importantly not designing your code around a network of objects that work together.
Instead you write code in a purely procedural, or functional fashion - depending on what programming paradigm you prefer.

The primary characteristic of non-OOP code is that there's definitions of data structures, and algorithms and functions that act on these data structures, and they are not tied together.
Data and logic is clearly separated.
Logged
Photon
Level 4
****


View Profile
« Reply #5345 on: June 21, 2017, 08:59:59 AM »

No not global variables.
I mean, I kinda figured not. I was more expressing my inability to come up with more fitting alternatives.

Quote
Not using objects, or more fitting, not using OOP means not using methods, not using inheritance, not using data hiding (private and protected fields) and most importantly not designing your code around a network of objects that work together.
Instead you write code in a purely procedural, or functional fashion - depending on what programming paradigm you prefer.

The primary characteristic of non-OOP code is that there's definitions of data structures, and algorithms and functions that act on these data structures, and they are not tied together.
Data and logic is clearly separated.
This still sounds suspiciously similar to bread-and-butter ECS.
Logged
Ordnas
Level 10
*****



View Profile WWW
« Reply #5346 on: June 21, 2017, 11:54:45 AM »

No not global variables.
I mean, I kinda figured not. I was more expressing my inability to come up with more fitting alternatives.

Quote
Not using objects, or more fitting, not using OOP means not using methods, not using inheritance, not using data hiding (private and protected fields) and most importantly not designing your code around a network of objects that work together.
Instead you write code in a purely procedural, or functional fashion - depending on what programming paradigm you prefer.

The primary characteristic of non-OOP code is that there's definitions of data structures, and algorithms and functions that act on these data structures, and they are not tied together.
Data and logic is clearly separated.
This still sounds suspiciously similar to bread-and-butter ECS.

Are there any advantages to not using methods, inheritance, data hidings etc.?

In case I need to define a Car, how would I implement that using the breadboard style?

In an OOP style (just as an example, could not be very correct), I could make a Car Chassis parent, that has as a child the cockpit. The cockpit can have a child Engine, and the Engine has 4 suspensions childs, and each suspension childs has a wheel.
Advantages: If the Car parent moves, then all the car childs moves. If a suspension breaks, the wheel also breaks because is a child of the suspension. If we need to disable the physics of the car, we can disable the Car parent, and all the subsystem is disabled.

We could also implement the Car in an ECS way, instead of childs the Car parts are components, so we have a generic Car definition, with many properties like physics properties, engine properties etc. Attached to the Car, we can have a chassis component, the suspension components, wheels components etc. Also the Driver could be a component.

I think that a procedural way of organize something like a Car, in a more complex game, could not be entirely possible, for many reasons (safety, readability, cache-friendly code, reusable, data-driver and working in a team of 20+ people to say a few).
Logged

Games:

gimymblert
Level 10
*****


The archivest master, leader of all documents


View Profile
« Reply #5347 on: June 21, 2017, 01:54:33 PM »

It's not that you avoid objects, it's that you avoid relying on them too much for interaction between objects. You can still have some OOP if you want, where it make sense. Breadboard address the interaction part. So your car would still be there, but it would not need to know about other thing than itself, the INTERACTION would be handled by the breadboard if you try to run other a zombie for example. Because while engine is part of car, zombie (or higher class it belongs) are not. And deep inheritance make code hard to read with too many indirection.

Also there is the data oriented design that's better than OOP for cache, parallelism and other (which also met a lot of resistance), object tend to create a lot of memory indirection.
Logged

GuiltyGreens
Level 0
*


View Profile
« Reply #5348 on: June 21, 2017, 02:01:55 PM »

How does the car relate to the game? How does a car and its parts interact? The car example is kinda useless unless we know what its.. use is. Is the car going to be simulated or is it just a visual aesthetic only to be viewed? In the latter case, you don't need any specific car classes. You just need meshes and shaders. The former case requires more info. Is it an arcade game, where the car physics isn't necessarily realistic? Maybe you don't need to define what a wheel is at all. You just need a friction value. Or maybe, it's an educational car simulation for engineering students and so we have to simulate as much as possible?

Logged
JWki
Level 4
****


View Profile
« Reply #5349 on: June 21, 2017, 02:33:53 PM »

No not global variables.
I mean, I kinda figured not. I was more expressing my inability to come up with more fitting alternatives.

Quote
Not using objects, or more fitting, not using OOP means not using methods, not using inheritance, not using data hiding (private and protected fields) and most importantly not designing your code around a network of objects that work together.
Instead you write code in a purely procedural, or functional fashion - depending on what programming paradigm you prefer.

The primary characteristic of non-OOP code is that there's definitions of data structures, and algorithms and functions that act on these data structures, and they are not tied together.
Data and logic is clearly separated.
This still sounds suspiciously similar to bread-and-butter ECS.

ECS is about aggregation over inheritance and dynamic composition of objects so to speak. They're not something that you can use for everything because it doesn't make sense for every type to be dynamically composed of other types. You can implement an ECS both in an OOP style as well as in non-OOP style.

Writing non-OOP code means NOT thinking in objects on the language level, regardless of what part of the program or what kind of program even.
Take any language that doesn't have classes and look at an example program if you want to see non-OOP code. Like a C program.



Are there any advantages to not using methods, inheritance, data hidings etc.?

In case I need to define a Car, how would I implement that using the breadboard style?

In an OOP style (just as an example, could not be very correct), I could make a Car Chassis parent, that has as a child the cockpit. The cockpit can have a child Engine, and the Engine has 4 suspensions childs, and each suspension childs has a wheel.
Advantages: If the Car parent moves, then all the car childs moves. If a suspension breaks, the wheel also breaks because is a child of the suspension. If we need to disable the physics of the car, we can disable the Car parent, and all the subsystem is disabled.

We could also implement the Car in an ECS way, instead of childs the Car parts are components, so we have a generic Car definition, with many properties like physics properties, engine properties etc. Attached to the Car, we can have a chassis component, the suspension components, wheels components etc. Also the Driver could be a component.

I think that a procedural way of organize something like a Car, in a more complex game, could not be entirely possible, for many reasons (safety, readability, cache-friendly code, reusable, data-driver and working in a team of 20+ people to say a few).

Again, "not using OOP" has NOTHING to do with ECS.
And whether or not there's advantages to not using OOP, discussing that would tangent off way too much and is also kinda subjective.

I personally found that I prefer reading and writing procedural code because I found myself tangled up in object hierarchies and overly complex, scattered control flow caused by the decomposition of the program into separated objects.
Not that I think separation of concerns and clean code architecture is a bad thing, but I personally don't think OOP is the ultimate way to achieve that.

Also your example has nothing to do with OOP or non OOP really.
Logged
Ordnas
Level 10
*****



View Profile WWW
« Reply #5350 on: June 22, 2017, 04:42:35 AM »

Also there is the data oriented design that's better than OOP for cache, parallelism and other (which also met a lot of resistance), object tend to create a lot of memory indirection.

Yes, definitely true. For example, data oriented design was the only way to code on the PS3 efficiently (due to the nature of the SPUs). But your code will be more difficult to read and to debug.
Logged

Games:

InfiniteStateMachine
Level 10
*****



View Profile
« Reply #5351 on: June 22, 2017, 05:44:07 PM »

I agree with JWki. I find procedural code easier to read (I'm specifically thinking of C when I say this). I think it has to do with the fact that there's a lot of different ways you can structure your code with object definitions that are totally valid but are a reflection of the mind of the designer. I could have a totally different idea of how to lay out a program as someone else. With C, the way people program tends to be pretty standard and therefore I find it easier to get up to speed with a procedural codebase than a object oriented design.

One thing that is really great about OOP though is that it is very compatible with intellisense. You can have an object instance then press the period key and see all the functions that apply to this specific instance of data. This is why I'm a fan of the C with namespaces methodology. It's sort of a nice middle road that allows me to categorize functions in a way that intellisense can exploit to some degree.

It would be cool to see a new type of intellisense where I could select a struct and get a list of all functions that take that struct as a parameter. That doesn't happen to already exist does it? I'm not talking about grepping. I mean like a visual studio C# intellisense level of quality.

In regards to performance : I don't agree with any assertions that say OOP code will definitely cause data locality issues. That's entirely dependent on how you choose to use those features. At best I would say that modern education on OOP encourages homogenous collections and that's where things get nasty. No reason you have to do that though.
Logged

Ordnas
Level 10
*****



View Profile WWW
« Reply #5352 on: June 23, 2017, 04:15:04 AM »

I agree with JWki. I find procedural code easier to read (I'm specifically thinking of C when I say this). I think it has to do with the fact that there's a lot of different ways you can structure your code with object definitions that are totally valid but are a reflection of the mind of the designer. I could have a totally different idea of how to lay out a program as someone else. With C, the way people program tends to be pretty standard and therefore I find it easier to get up to speed with a procedural codebase than a object oriented design.

One thing that is really great about OOP though is that it is very compatible with intellisense. You can have an object instance then press the period key and see all the functions that apply to this specific instance of data. This is why I'm a fan of the C with namespaces methodology. It's sort of a nice middle road that allows me to categorize functions in a way that intellisense can exploit to some degree.

It would be cool to see a new type of intellisense where I could select a struct and get a list of all functions that take that struct as a parameter. That doesn't happen to already exist does it? I'm not talking about grepping. I mean like a visual studio C# intellisense level of quality.

In regards to performance : I don't agree with any assertions that say OOP code will definitely cause data locality issues. That's entirely dependent on how you choose to use those features. At best I would say that modern education on OOP encourages homogenous collections and that's where things get nasty. No reason you have to do that though.

Yes, maybe I was wrong. I was talking with others about it, and I changed my mind. Procedural can be easier to read and maybe can potentially removes nasty bugs introduced by hierarchy, data hidings etc. I think that it is not a valid option for a AAA project, because it will be too difficult to track all the changes in the code.

Could the locality issues in OOP being caused by how the virtual tables are implemented?
Logged

Games:

InfiniteStateMachine
Level 10
*****



View Profile
« Reply #5353 on: June 23, 2017, 04:34:34 AM »

Dont get me wrong you could make an unreadable procedural program too :D

The vtable stuff is an issue but I was thinking about trying to store an array of objects of different sizes homogenously. At that point you would have to store pointers to those objects and then you don't really have a cache friendly solution because you have a contiguous collection of pointers that point to the actual data in some arbitrary place on the heap.

Logged

gimymblert
Level 10
*****


The archivest master, leader of all documents


View Profile
« Reply #5354 on: June 23, 2017, 10:32:31 AM »

Quote
I think that it is not a valid option for a AAA project, because it will be too difficult to track all the changes in the code.

I don't know because I haven't made anything on teh scale of AAA.

But the idea of" breadboard" is not that much  coding paradigm as it is a way to organize your code, the same way a design document remain readable, the ame way you organize your code readability around key concept. Game tend to be organize around interaction, having related interaction in the same place make them more readable.

People have been coding oop like in non oop language by keeping data structure and method that modify them in the same file or block, mimicking the organisation of OOP, ie what's make it readable.

It's like the jump from goto to loop and from some loop to function, they are organizing principle BAKED into the language, but the principle itself is language agnostic. In the end it's all translated in machine code who have no idea of these concept altogether.
Logged

Garthy
Level 9
****


Quack, verily


View Profile WWW
« Reply #5355 on: June 23, 2017, 03:23:42 PM »


I just wanted to mention that worrying about cache issues at such an early point that it is defining your overall methodology and architecture is IMHO right up there with the most premature of premature optimisation. Cache issues are the sort of thing you look into in the 0.001% of your codebase that you have measured and determined is chewing up 10% of the overall execution time. You then come up with a very domain-specific solution to that particular problem. IMHO cache issues should definitely *not* be used to promote the general superiority or inferiority of any particular methodology because overall performance is going to be based on the actual execution path and data access ordering in that application. Unless you are doing a rewrite of a rewrite of a rewrite, you will never successfully predict this ahead of time.

Please don't say or suggest "do X because cache" unless X is something like "When I'm hand-optimising a frequently-called codepath for a specific set of processors I do Z" and you replace "because cache" with at least a paragraph explaining how the particular access patterns that result are optimal. These generalisations confuse people new to the craft because they don't yet understand caching issues and are prone to just believing those who appear to be demonstrating superior knowledge of the subject matter,

With respect. Gentleman
Logged
InfiniteStateMachine
Level 10
*****



View Profile
« Reply #5356 on: June 23, 2017, 05:09:44 PM »


I just wanted to mention that worrying about cache issues at such an early point that it is defining your overall methodology and architecture is IMHO right up there with the most premature of premature optimisation. Cache issues are the sort of thing you look into in the 0.001% of your codebase that you have measured and determined is chewing up 10% of the overall execution time. You then come up with a very domain-specific solution to that particular problem. IMHO cache issues should definitely *not* be used to promote the general superiority or inferiority of any particular methodology because overall performance is going to be based on the actual execution path and data access ordering in that application. Unless you are doing a rewrite of a rewrite of a rewrite, you will never successfully predict this ahead of time.

Please don't say or suggest "do X because cache" unless X is something like "When I'm hand-optimising a frequently-called codepath for a specific set of processors I do Z" and you replace "because cache" with at least a paragraph explaining how the particular access patterns that result are optimal. These generalisations confuse people new to the craft because they don't yet understand caching issues and are prone to just believing those who appear to be demonstrating superior knowledge of the subject matter,

With respect. Gentleman


100% agree Coffee. Cache coherency is something I rarely ever think about when I'm programming.
Logged

gimymblert
Level 10
*****


The archivest master, leader of all documents


View Profile
« Reply #5357 on: June 23, 2017, 05:20:20 PM »

Wait till you make planet generation with fast moving ship
Logged

JWki
Level 4
****


View Profile
« Reply #5358 on: June 24, 2017, 05:30:03 AM »


I just wanted to mention that worrying about cache issues at such an early point that it is defining your overall methodology and architecture is IMHO right up there with the most premature of premature optimisation. Cache issues are the sort of thing you look into in the 0.001% of your codebase that you have measured and determined is chewing up 10% of the overall execution time. You then come up with a very domain-specific solution to that particular problem. IMHO cache issues should definitely *not* be used to promote the general superiority or inferiority of any particular methodology because overall performance is going to be based on the actual execution path and data access ordering in that application. Unless you are doing a rewrite of a rewrite of a rewrite, you will never successfully predict this ahead of time.

Please don't say or suggest "do X because cache" unless X is something like "When I'm hand-optimising a frequently-called codepath for a specific set of processors I do Z" and you replace "because cache" with at least a paragraph explaining how the particular access patterns that result are optimal. These generalisations confuse people new to the craft because they don't yet understand caching issues and are prone to just believing those who appear to be demonstrating superior knowledge of the subject matter,

With respect. Gentleman


While I generally agree with this it should be mentioned that there's methodologies that make your code hard to optimise later - and writing code that easy to optimise isn't premature optimization, it's smart.
Logged
Whiteclaws
Level 10
*****


#include <funny.h>


View Profile
« Reply #5359 on: June 24, 2017, 10:03:37 AM »


When you finally hit the compile button Hand Any Key
Thankfully 30 of those went away when I included the OpenGL header
Logged
Pages: 1 ... 266 267 [268] 269 270 ... 295
Print
Jump to:  

Theme orange-lt created by panic