back
257 comments
This might be fun to look through; first thing I saw that I never thought of before was how to define flag enums.

From https://github.com/CRYTEK-CRYENGINE/CRYENGINE/blob/release/C...:

    // State flags
    enum EGlassRNState
    {
    	EGlassRNState_Initial     = 0,
    	EGlassRNState_Weakened    = 1 << 0,
    	EGlassRNState_Shattering  = 1 << 1,
    	EGlassRNState_Shattered   = 1 << 2,
    	EGlassRNState_ActiveFrags = 1 << 3
    };
Als a C# dev, I write Enum flags from time to time, but I always just write out the values; never thought of using bit-shifting to prevent typos :)
This is pretty standard practice, in C# too. However, it's still somewhat prone to typos.

If you don't care about backward compatibility (i.e. the flags are used internally and never written anywhere), then a better method is actually to grab the value one line above and bit shift it by one. That way you can insert values in the middle and you won't have to change every single line (just two).

The Linux kernel takes it a step farther:

#define BIT(nr) (1UL << (nr))

#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))

#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)

#define BITS_TO_TYPE(nr, t) (((nr)+(t)-1)/(t))

In the Go language, there is something called iota which is like a iterator that counts up from 0:

    type EGlassRNState int

    const (
        EGlassRNState_Initial EGlassRNState = 1 << iota
        EGlassRNState_Weakened
        EGlassRNState_Shattering
        EGlassRNState_Shattered
        EGlassRNState_ActiveFrags
    )
Just don't fall into old habits without thinking and end up writing...

    enum MyEnum
    {
    	MyEnum_Foo   = 1 << 0,
    	MyEnum_Bar   = 1 << 1,
    	MyEnum_Baz   = 1 << 2,
    	MyEnum_Quux  = 1 << 4,
    	MyEnum_Xyzzy = 1 << 8
    };
:)
Go has a great idiom for this, with the 'iota' keyword, which increments by one for each line in a block of declarations.

From the language spec:

  const ( // iota is reset to 0
  	a = 1 << iota  // a == 1
  	b = 1 << iota  // b == 2
  	c = 3          // c == 3  (iota is not used but still incremented)
  	d = 1 << iota  // d == 8
  )
How does bit shifting prevent typos as opposed to just explicit numbering?
It's usually done to combine multiple flags using bitwise or, but I don't think it's the case here(unless glass can be shattered and not shattered at the same time). Or are you saying that you usually write 0, 1, 2, 4 and so on?
C# even has a (deprecated?) [Flags] attribute that will auto-number in this way.

Edit: I was mistaken, it still requires manually setting the numbers, it just adds neater ToString support: https://msdn.microsoft.com/en-us/library/system.flagsattribu...

C++14 supports binary literals, which makes it way more readable.
Shifting is used to define masks. Did you mean you actually type out mask values in base 10?
Carmack has some interesting comments on this sort of coding: http://number-none.com/blow/john_carmack_on_inlined_code.htm...
14 levels of indentation across 811 lines. Wow indeed.

I refactor as soon as my code gets past 3 levels, I don't know how one is supposed to readily understand this block of code.

The lack of comments isn't what troubles me. Comments get old and, when they do, they get completely misleading and downright dangerous. As soon as you feel the need to add a comment, it's often because that particular chunk of code should be extracted into its own function/method/whatever and given an intelligent name. Comments should be reserved for really important stuff, like when the code does something totally non-obvious.

Yeah, this sort of declaration[1] (inherited from C) is horrendous and prone to nasty errors.

Consder this:

    char* p1, p2;
You could erroneously think that char* is a type, and p1 and p2 are variables of that type. That's not correct however, since p1 is indeed char*, but p2 is char. Such declarations therefore should be strongly avoided for clarity.

[1]: https://github.com/CRYTEK-CRYENGINE/CRYENGINE/blob/release/C...

I actually kind of find this sort of entity data oriented code easier to grok than when everything is nicely organized into object hierarchies, like they teach you to do in school ;)
The perfect example of everything I try to avoid. I'm really surprised to see this type of coding in a triple A grade engine.

What can be the rationale behind writing this [1] ?

[1] https://github.com/CRYTEK-CRYENGINE/CRYENGINE/blob/release/C...

Wow, that is a hardcore function... Have no idea what is going on there... Probably some/a lot refactoring needs to be done there.
There are some parts of video games, where if the thing works, nobody would dare to call your code bad :)
My God. I would've been panned for that in university. Break it up with meaningful comments, rip some of it out into functions where possible, if you're leaving code in source which is commented out - at least leave a comment on why it's commented out.

I suppose this is the result of deadlines and lax code reviews.

That could totally fit on my screen
What a wall of code without comments. Not acceptable.
I'm one of the developers of CryEngine, so if there's any questions, we are watching :)
What caught my eye immediately is their licence agreement that prohibits using the engine to develop, quoting "Serious games". That's a rather vague and broad statement, what's a serious game?
I really wish Epic and/or CryTek would release their engines under a strong copyleft license such as AGPL, with the option to purchase a proprietary license for developers who do not want to release their games as free software. This would allow developers of free (as in freedom) games to use the engine while also allowing the company behind the engine to make money.
Doesn't have issue tracker so can't ask them directly. Hoping they will see it here.

I think that instead of just linking to the license, they should include a copy of it in the root of the repository and refer to that. It is the proper way to do it.

Ah man, I was curious to take a look at the early development history of this, but seems like they didn't push the full history of the engine :(
It's been about a year since I tried cryengine last, but I have experienced nothing but pain with it, functionality wise, not to mention the lack of dev response to the users and the other drama surrounding the company behind it, I am going to continue to steer clear of it, especially with such restrictive terms.

To me, this is a halfhearted attempt to catch up with Epic and Unreal Engine 4, which has really shown the market how to do things right. I actually look forward to engine updates with UE4, not to mention the increasingly better marketplace content. Also, I am hoping to eventually move over to devving completely on linux...

unity and CryEngine are feeling the hurt, ans struggling to respond.

Unreal makes you 'attach' your account to their repo so they know who has had access to the source code. I'm surprised CryEngine just releases it in its entirety without any such 'protections'.

The coding style is very Microsoft-like, which is I suppose not a big surprise given it's DirectX roots. 8-space tabs seems to be the convention (ugh). They use XML for their readable format (which explains a little their slow load times).

The code itself is not very well documented but relatively clear to understand. Overall not a bad engine to learn a few things from but if you're new to Game Engines a lot of stuff will probably seem very complex (check out BreakableManager.cpp).

It's no Quake 3 in elegance but it's got a lot of advanced functionality (especially in the editor). Overall, it's pretty awesome that they released this. Its a huge gift to everyone that is curious what a world class game engine that has shipped a ton of AAA games looks like.

What do the !XT, !B, !U etc. mean in the commit messages?
So .. why would anybody care about Amazon's Lumberyard now that this exists?
2.4. Restrictions on Use: Crytek reserves all rights not expressively granted in this Agreement. Without limitation, Licensee shall not:

distribute, sublicense or exploit in any other form: the CryEngine (except for the Redistributables), e.g. as a stand-alone development engine; the CryEngine Documentation; the CryEngine Tools; use the CryEngine for the development of any product other than Games, including without limitation: military projects gambling; simulation (technical, scientific, other); science; architecture; pornography; Serious Games.

Serious Games? did lawyers actually even read this?

What I like and what I'd like to understand better from a price economics view is their "Pay what you want" model; on the following link you see the page where the user can decide which amount he likes to pay (€0, €10, €25, ...):

https://www.cryengine.com/get-cryengine

I am just wondering how the distribution is, so how many pay 0, how many 10 etc.?

Could imagine that this pricing could lead to higher total revenues than the classical three-prices-page.

It would be nice if the README mentioned what CryEngine is.

(By visiting https://www.cryengine.com/, I found out that it's a game development platform.)

Hasn't that been there for quite a while?
It would be great if the great hobbyist talent out there can also push to further optimize the CryEngine. From what I've experienced, the engine performs well, you just need to put a lot of hardware behind it.
Wow, that's quite the restrictive license they got out there. Just about the only thing that's allowed is looking at the source code. You can't modify or redistribute, definitely not sell, and there are tons of restrictions on how to use it:

https://www.cryengine.com/ce-terms

My 2c, but its too little too late. Unreal and Unity are the big boys fighting for game developers, especially indie game developers.
It's like the release of the source code of Doom and Duke Nukem 3D. We're getting old.
Does anyone how the complexity of setting up a multiplayer session stacks up against unity?
This is the kind of thing you git clone just in case it winds up being an accident.
Is it purely header files and this is commonplace at game studios that use C++?

Edit: What I mean is that the implementation of C++ classes seems to be in header files and I'm wondering if this is a common way to do things at game studios.

Found cpp files, but it's interesting that so much of the class implementations are directly in the headers.

This is very hearsay-ish, but I have a friend of a friend who had to work with the CryEngine (I think it was for one of those Sonic games) and it was described as so incredibly buggy and you have to debug it constantly.

Maybe this is their attempt to have the community fix it for them =)

Nice. I hope Vulkan support will arrive soon too.
I wish the README said what CryEngine is. What is CryEngine?