Live data from Hacker News

Cryengine Source Code

github.com

81–90 of 149 posts

Re: Cryengine Source Code

#81
post #75
post #45

Earlier quoted context omitted.

I don't think it's the best code I've ever seen, but a lot of these are surface-level complaints. > * goto inside 3 nested for-loops. C has no pattern for breaking out of multiple for loops at the same time. Other languages like Java and JavaScript introduced "break label;" to handle this edge case. goto is perfectly acceptable to break out of multiple loops. > * new/delete, with no RAII They use RAII, but it's not a…

> C has no pattern for breaking out of multiple for loops at the same time. Other languages like Java and JavaScript introduced "break label;" to handle this edge case. goto is perfectly acceptable to break out of multiple loops. Yeah, that's not what it does. The code looks like this: if (pgeom->Intersect(pentlist[i]->m_parts[j].pPhysGeomProxy->pGeom, gwd,gwd+1, &ip, pcontacts)) { got_unproj: if (dirUnproj.len2()==0…

Either that code is misleadingly indented and you copied one more closing brace than necessary, or you omitted the opening brace for the last if's body (which contains a single goto).

Re: Cryengine Source Code

#82
post #13

This is on the front page again. Please take some time to read this wonderful function: https://github.com/CRYTEK/CRYENGINE/blob/release/Code/CryEng... EDIT: That whole function is a minefield. Just taking a quick look: * 814 lines of code * goto inside 3 nested for-loops * macros * commented out code * new/delete, with no RAII * thread specific variables and locks (?)

I'd rather work with this than Enterprise Java. At least the logic is all there and you only need to scroll to see it, instead of jumping around between a dozen or more different files. Math-heavy code tends to look dense to those who are accustomed to more "mundane" LOB type applications.

This. The convenience of everything in a single file is underrated. You can do all the modern best practice like splitting into more functions, making functions small, and I wouldn't mind if they are all in the same file.

Re: Cryengine Source Code

#83
post #68
post #13

This is on the front page again. Please take some time to read this wonderful function: https://github.com/CRYTEK/CRYENGINE/blob/release/Code/CryEng... EDIT: That whole function is a minefield. Just taking a quick look: * 814 lines of code * goto inside 3 nested for-loops * macros * commented out code * new/delete, with no RAII * thread specific variables and locks (?)

It’s not just that function, the C file is over 2300 lines long. It’s hard to tell where one function starts and another one ends in that mess

Why not? Doesn't the indentation tell you perfectly where each functions starts and ends?

Re: Cryengine Source Code

#84
post #76
post #75

Earlier quoted context omitted.

> C has no pattern for breaking out of multiple for loops at the same time. Other languages like Java and JavaScript introduced "break label;" to handle this edge case. goto is perfectly acceptable to break out of multiple loops. Yeah, that's not what it does. The code looks like this: if (pgeom->Intersect(pentlist[i]->m_parts[j].pPhysGeomProxy->pGeom, gwd,gwd+1, &ip, pcontacts)) { got_unproj: if (dirUnproj.len2()==0…

That's in a different function, so I wasn't counting it, but sure. I mean, I would write it differently, but it's fairly readable. It's jumping to a common function epilogue once it finds something it can collide with. Seriously -- try reading through it rather than gawking at the goto.

It's funny watching people reply to you without knowing anything about your skill set and experience.

Jasper_ is the real deal, people.

Re: Cryengine Source Code

#85
post #28
post #24

Earlier quoted context omitted.

Not just in game development. If you have a function that is only called once, it shouldn't be a function yet. Make it a function when you have a second or third use for it. Then, and only then, you will know what the parameters should be.

I disagree. Splitting a function up can help with readability and testability. The parent function becomes shorter and the child function can have a descriptive name. The parameters to a function are the fields that are needed for the function to perform its function.

function calls push registers, allocate a stack frame, and push a return address. By breaking your inner loops into more functions you've now generated megabytes of pointless memory thrash... on a console. Additionally, at the time this stuff was written, compilers and toolchain weren't neccessarily standardized, or were customized to accomodate certain use cases, so they needed more hand-holding to generate performant code. This is just a fact.. I'm not saying you're wrong, but you're definitely viewing this with hindsight.

Re: Cryengine Source Code

#86
post #75

Earlier quoted context omitted.

> C has no pattern for breaking out of multiple for loops at the same time. Other languages like Java and JavaScript introduced "break label;" to handle this edge case. goto is perfectly acceptable to break out of multiple loops. Yeah, that's not what it does. The code looks like this: if (pgeom->Intersect(pentlist[i]->m_parts[j].pPhysGeomProxy->pGeom, gwd,gwd+1, &ip, pcontacts)) { got_unproj: if (dirUnproj.len2()==0…

Either that code is misleadingly indented and you copied one more closing brace than necessary, or you omitted the opening brace for the last if's body (which contains a single goto).

Good catch. I think I copied one more than necessary, and then messed up when trying to fix up the indentation for HN.

Re: Cryengine Source Code

#87
post #28
post #24

Earlier quoted context omitted.

Not just in game development. If you have a function that is only called once, it shouldn't be a function yet. Make it a function when you have a second or third use for it. Then, and only then, you will know what the parameters should be.

I disagree. Splitting a function up can help with readability and testability. The parent function becomes shorter and the child function can have a descriptive name. The parameters to a function are the fields that are needed for the function to perform its function.

Function calls have an overhead, and if the function is only used once it makes no sense to break it out.

It also makes no sense to have a rule on the maximum number of lines for a function. These rules are often created by people who don't write software that needs to have high performance.

Re: Cryengine Source Code

#88
post #42

Earlier quoted context omitted.

One of my professors used to encourage the heavy use of helper functions that just... well, like in A or B in carmacks article, break your code into chunks with clear names that can be unit tested. How common is automated testing in AAA games?

Underlying helper libraries like math utilities are often extracted and put under independent test. A physics engine often has so much state (and isn't always guaranteed to be deterministic!) that doing any sort of unit testing at the functional level is not worth it. To those that reply with "use less state", I encourage you to show how. Often times the unit tests I've seen from junior game programmers are worse tha…

Game development problems are often large global state manipulation problems. If you don't write games you will never realize this.

Almost everything taught in academia and in the enterprise about software development "best practices" are absolutely the wrong things for a game. (They're wrong for enterprise and academia, too, but I'm not willing to get into that fight on this site.)

Re: Cryengine Source Code

#89
post #72

Earlier quoted context omitted.

...which is NOT high on the list of concerns for a game title, what you want instead is massive performance gains, so you can do more with less, and in the end produce a better experience than your competitor. -- function calls/indirection/making your code 'easy' to understand, all have a RUNTIME cost, and many small costs add up to a large cost, the reasoning is really that simple.

I struggle to see how composing into functions adds a runtime cost when using modern compilers; as others have pointed out the compiler will inline it if the function is only used once. This rationalization doesn’t make sense to me, especially for game engines which I assume are not limited to a release or 2 but are used to power multiple titles. If the software artifact is going to live for a long time, it’s probabl…

This! I'm not sure why we are discussing the runtime cost of a function with modern compilers.

Could this pattern result in code so slow the game won't work in development w/o high optimization flags, thus increasing compile time?

Re: Cryengine Source Code

#90
post #60

Earlier quoted context omitted.

While this is often a good rule of thumb, occasionally it's useful to extract a function just to make the inputs clear for a complicated calculation. Particularly when it has few inputs and they are unlikely to change.

With modern C++ you could do this with a lambda

Which compiler that can compile modern C++ doesn't always inline a static single-caller function?
Post reply on HN