Live data from Hacker News

Cryengine Source Code

github.com

51–60 of 149 posts

Re: Cryengine Source Code

#51
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 (?)

inside a bunch of nested loops is where you need a goto, if the language doesn’t have labeled breaks (which is just a fancy goto)

most of your points are things people notice any time real actual big software with performance constraints gets posted. so along with questioning the wisdoms in that function, also question your own wisdom. maybe some of what you think you know is wrong.

Re: Cryengine Source Code

#52

Earlier quoted context omitted.

It falls more in the category of having a lot bugs which could've been caught if they used static code analysis, code review, etc... I understand that you might think that messy could mean it's fine tuned for performance. In this case, I highly doubt it and think it's more reasonable to think it's messy because they had deadlines. The messy part isn't about performance optimizations. It's more about things that got c…

What sorts of static code analysis tools do people here use in their game projects? I know carmack is a big fan of them

I have used the Rust compiler, which will catch all memory errors, data races, and null pointer exceptions and buffer overflows at compile time as a matter if course. then you can add cargo fuzz if you like.

Re: Cryengine Source Code

#53
post #24

Earlier quoted context omitted.

Here's a good article from John Carmack on why that can be a good approach in game development: http://number-none.com/blow/john_carmack_on_inlined_code.htm... I feel like this Cryengine example may be a bad example of that, though.

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.

There are other reasons for separating logic into functions besides just keeping it DRY. It's an opportunity to encapsulate concerns and then, in some other place, compose the story poetically and clearly.

Re: Cryengine Source Code

#54
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 (?)

The code looks bad, but not for those reasons, in my opinion. The logic in this function doesn't look composable. It combines different kinds of mathematical functions to apply inertia, whether you're jumping, etc. into one big ball of spaghetti that would be hard to extend for anyone not deeply familiar with the code. If I were to try to refactor this, I would try to decompose it into standalone "behaviour" function…

I encourage you to try! However, a lot of gameplay and getting movement controls to feel good is difficult and at odds with the goal of "modularized physics", e.g. you might want to apply different amounts of ground friction depending on whether the player is moving, how they're moving, whether they're holding the jump key, and so on.

Ultimately, we're trying to simplify a large simulation of real-world physics and hundreds of controllable muscles and motor responses trained over a lifetime, down to 5 or 6 keyboard inputs. That means you tend to have such inputs doing multiple things, and it's often hard to make separable.

Re: Cryengine Source Code

#55
post #38
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 (?)

If the code was separated out into functions that are only ever called once, I'd find it harder to read. Analysing code I'm not familiar with often consists of manually tracing through calls, producing documentation that inlines all the single use function calls. Ideally function names act as shorthand for the body of the function, but if they only have one caller they have nothing to keep them honest. In older codeb…

I agree with the gist of your post, but one positive about single use functions is that you can be explicitly clear about data visibility.

In this contrived example, you can tell that formatting a title is not affected by user preferences, but formatting the body is. (And additionally that formatting a body has no information about the other fields of an entry)

  def formatRssFeedEntries(userSettings: UserSettings, data: List[Entry]) {
    val titles = data.map(entry => formatTitle(entry.title))
    val bodies = data.map(entry => formatBody(entry.body, userSettings))
  ...
  }

Re: Cryengine Source Code

#56
post #44
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 (?)

As a hobbyist who likes to tinker with game and interactive media development, a sentiment I often come across is that in 2020 it makes no sense to implement a game engine, and that I should just use something which already exists to avoid re-inventing the wheel. Code like this is one thing which helps me to calmly ignore than sentiment. I came across the same kind of thing when I was kicking the tires on the Unreal…

I have a feeling you may have been approaching this problem in UE4 the wrong way. Adding a double jump can be done in numerous ways, but one simple way is with Blueprints. See below link where the exact functionality is implemented with a really simple blueprint.

https://m.youtube.com/watch?v=hFAr7gYV1rA

Re: Cryengine Source Code

#57
post #38

Earlier quoted context omitted.

If the code was separated out into functions that are only ever called once, I'd find it harder to read. Analysing code I'm not familiar with often consists of manually tracing through calls, producing documentation that inlines all the single use function calls. Ideally function names act as shorthand for the body of the function, but if they only have one caller they have nothing to keep them honest. In older codeb…

I agree with the gist of your post, but one positive about single use functions is that you can be explicitly clear about data visibility. In this contrived example, you can tell that formatting a title is not affected by user preferences, but formatting the body is. (And additionally that formatting a body has no information about the other fields of an entry) def formatRssFeedEntries(userSettings: UserSettings, dat…

I agree. Blocks can somewhat substitute with scoping effects, and that's what I do with my inlined docs - they're nested {} with plain text description of contents and mentions of key variables and functions, scope is useful.

Re: Cryengine Source Code

#58
post #44

Earlier quoted context omitted.

As a hobbyist who likes to tinker with game and interactive media development, a sentiment I often come across is that in 2020 it makes no sense to implement a game engine, and that I should just use something which already exists to avoid re-inventing the wheel. Code like this is one thing which helps me to calmly ignore than sentiment. I came across the same kind of thing when I was kicking the tires on the Unreal…

I have a feeling you may have been approaching this problem in UE4 the wrong way. Adding a double jump can be done in numerous ways, but one simple way is with Blueprints. See below link where the exact functionality is implemented with a really simple blueprint. https://m.youtube.com/watch?v=hFAr7gYV1rA

Oh I am certain I was not approaching the problem in the UE4 way. But the issue is that the way UE4 expects me to do things is not the way I would like to approach game development.

UE4 has a strong bias about the way things should work. If I am making something which is fairly well aligned to that bias, then it's fairly easy to make it work. But if I want to achieve something which is quite far from what the engine expects, then I have to invest significant effort undoing or circumventing what UE4 already does before adding my own functionality on top. I would greatly prefer to start from a blank slate, and only add precisely the behavior I actually want.

So basically this experience with the double jump just gave me a window into the level of complexity I would have to work around in terms of realizing my own goals.

Re: Cryengine Source Code

#59

Earlier quoted context omitted.

Interesting sentiment, I sometimes wonder if a "messy" codebase can have advantages for performance. Many very highly performance tuned applications I saw in the wild would fall into the category of "horrible codebase" when looked at through that lens.

It falls more in the category of having a lot bugs which could've been caught if they used static code analysis, code review, etc... I understand that you might think that messy could mean it's fine tuned for performance. In this case, I highly doubt it and think it's more reasonable to think it's messy because they had deadlines. The messy part isn't about performance optimizations. It's more about things that got c…

>I don't blame the programmers, it feels they had deadlines to uphold from managment.

This is my own experience. The teams that spent the most time on standards usually had the least pressure, in terms of things like deadlines. Once the focus of the team shifts to having to ship things, there is less time to worry about having 100% code coverage (to pull out an arbitrary number), and so forth. Code review can slip into flagging only things that really matter, and leaving nitpicks for another day.

Re: Cryengine Source Code

#60
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.

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
Post reply on HN