Hacker News new | comments | ask | show | jobs | submit login
CryEngine out on GitHub (github.com)
506 points by lentil_soup on May 24, 2016 | hide | past | web | favorite | 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).


Yeah, but still there's possibility of failure there as you could paste in and forget to update the one below.

Honestly, flags should be a type. IIRC, the C# designers have admitted this was a mistake on their parts to continue C's ambiguity between flag enums and choice enums.


Crystal has a Flag attribute for enums (Flag enums):

http://crystal-lang.org/docs/syntax_and_semantics/enum.html


Nim supports sets which IMO is a much better solution: http://nim-lang.org/docs/manual.html#types-set-type


Taken from Pascal and other Wirthian languages. Nim actually looks vaguely Wirthish in some areas. Interesting.


Nim's author was originally a Turbo Pascal/Delphi programmer. A lot of Nim and its conventions (things like prefixing type names with T and members with F) come directly from Borland's Pascal dialect.


Ah, so a Set keyed with an Enum is functionally C-style "flags" then?


Pretty much. Here is an example:

    type
      EGlassRNState = enum
        EGlassRNState_Initial,
        EGlassRNState_Weakened,
        EGlassRNState_Shattering,
        EGlassRNState_Shattered,
        EGlassRNState_ActiveFrags

    proc hasGlassShattered(mState: set[EGlassRNState]): bool =
      EGlassRNState_Shattered in mState

    proc hasActiveFragments(mState: set[EGlassRNState]): bool =
      EGlassRNState_ActiveFrags in mState

    assert hasActiveFragments({EGlassRNState_Shattered, EGlassRNState_ActiveFrags})


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))


Hacks like these make unfamiliar code quite hard to understand (I'm looking at you OpenCV).


Yeah. It gets easier to understand once you use ctags/etags to have a "go to definition" key while you're hovering over a symbol.


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
    )


In python you could probably do

    def makeflag():
        flag = 1
        while True:
            yield flag
            flag = flag << 1
    flag = makeflag()
    E_GLASS_RN_STATE_INITIAL = next(flag)
    E_GLASS_RN_STATE_WEAKENED = next(flag)
    E_GLASS_RN_STATE_SHATTERING = next(flag)
    E_GLASS_RN_STATE_ACTIVE_FRAGS = next(flag) 

    flag2 = makeflag()
    UNRELATED_FLAG = next(flag2) 
    UNRELATED_FLAG = next(flag2) 
    
Also no chance of fatfingering a number.


Another option is to assume at most 128 bits then do something like:

  >>> _bitflags = [1<<i for i in range(128)]
  >>> (E_GLASS_RN_STATE_INITIAL,
  ...  E_GLASS_RN_STATE_WEAKENED,
  ...  E_GLASS_RN_STATE_SHATTERING,
  ...  E_GLASS_RN_STATE_ACTIVE_FRAGS,
  ...  *rest) = _bitflags
  >>> E_GLASS_RN_STATE_ACTIVE_FRAGS
  8


For the sake of correctness, the first const should be 0 and the second should be `1 << (iota - 1)`.


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
  )


"(iota is not used but still incremented)"

Seems bizarre. That's actually a pretty confusing idiom in that context.


Yeah this is classic shitty design from Go. One-off compiler hack that doesn't actually address any of the actual safety problems.

org/bitflags/bitflags/macro.bitflags!.html is much better.



Thanks. Phone clipboard failure on my part.


While it is a bit odd, it is documented (and I've seen it used a few times in code).


How does bit shifting prevent typos as opposed to just explicit numbering?


Spot the error:

    ...
    [DayOfMonth(28)]
    D28 = 134217728L,
    [DayOfMonth(29)]
    D29 = 268435456L,
    [DayOfMonth(30)]
    D30 = 536870902L,
    [DayOfMonth(31)]
    D31 = 1073741824L,
    [DayOfMonth(DayOfMonthAttribute.LastDayOfMonth)]
    Last = 2147483648L
Vs

    ...
    [DayOfMonth(28)]
    D28 = 1 << 28,
    [DayOfMonth(29)]
    D29 = 1 << 29,
    [DayOfMonth(30)]
    D30 = 1 << 31,
    [DayOfMonth(31)]
    D31 = 1 << 31,
    [DayOfMonth(DayOfMonthAttribute.LastDayOfMonth)]
    Last = 1 << 32
Hint: It's with D30 in both cases...


Another take on this is using hex values. Not saying it's better or worse than bit shifting, but it is fairly clear to me. My current lead prefers this for flag definitions.

FIRST_FLAG = 0x00000001

SECOND_FLAG = 0x00000002

THIRD_FLAG = 0x00000004

FOURTH_FLAG = 0x00000008

FIFTH_FLAG = 0x00000010

SIXTH_FLAG = 0x00000020

SEVENTH_FLAG = 0x00000040

EIGHTH_FLAG = 0x00000080

NINTH_FLAG = 0x00000100

...

28TH_FLAG = 0x08000000

29TH_FLAG = 0x10000000

30TH_FLAG = 0x20000000

Of course, I've never needed more than 12 bits of flags concurrently.

EDIT: Bleh, it wiped out my white space. These should be aligned.


At some point you forget a zero and it all goes to hell. Using 1 << n is far more concise.


Probably true. But assuming they are aligned, as they should be, a missing 0 would be pretty obvious. The real gotcha would be accidentally leaving a character in the wrong column during a copy-paste job.

But really, I've only used this with two or three character hex codes, so it works out much better. 0x01 through 0x80 are pretty hard to mess up, and 0x001 through 0x800 isn't bad either.

But yeah, the bit shifting honestly is probably a better solution. Cleaner, more scale-able.


Wait, so you used to compute the bit shifted value in your calculator and type it out literally (in base 10) in your code? I could understand typing out the binary literal but this is weird. Or am I misunderstanding?


It's how all MS Press books that I have read have explained it in the past; same goes for .NET focused websites back in 2001-2004 (when I got started in .NET


It's the same number in decimal and binary :)

I might be a bit weird, but I know the powers of 2 up to 2^20 in decimal. They've just snuck in there over the years, along with 2^24 and 2^31. So if I need some powers of two I might well just type them out like that. I can recognise a few common combinations too... it is all much easier in hex though.

I should really get the full set up to 2^64 memorised...


That's an impressive feat but now that you know about the bit shifting trick, I suggest you start using it because most of us mortals don't instantly recognise large powers of 2 when they're written out in decimal :) I'm still kind of amazed that you learned how to do bit arithmetic without coming across that pattern.


It may or may not. However, what's more important is the semantic significance.

You're making it clear these are flags and you're concerned with individual bits. 2, 4, 8 etc. are decimal numbers and mean something else i.e. "two", "four", "eight".

Does bitwise ORing the decimal numbers 2 and 4 really make sense? Not particularly, but combining bits at certain offset does.


Bit off-topic, but in C# at least you can mark your enums with the 'Flags' attribute to indicate it's a flags enum.


The odd thing here is that these don't seem to be flags.. can a glass be both shattered and shattering?


Maybe you read it wrong :)

See http://csharppad.com/

    // State flags
    enum EGlassRNState
    {
        EGlassRNState_Initial     = 0,
        EGlassRNState_Weakened    = 1 << 0,
        EGlassRNState_Shattering  = 1 << 1,
        EGlassRNState_Shattered   = 1 << 2,
        EGlassRNState_ActiveFrags = 1 << 3
    };
    foreach(var val in Enum.GetValues(typeof(EGlassRNState
))) { Console.WriteLine($"{val} -> {(int)val}"); }

Output:

    EGlassRNState_Initial -> 0
    EGlassRNState_Weakened -> 1
    EGlassRNState_Shattering -> 2
    EGlassRNState_Shattered -> 4
    EGlassRNState_ActiveFrags -> 8


I think he meant that in this context does not make sense for more than one value to be true at the same time , which is the reason you define enums this way, usually.


Not necessarily. Enums main application is to restrict a variable to a range of valid values. As to whether some other object may have one or more of these vales, enum makes no statement.


But then using bit fields makes no sense.


It can be used like this, no?

    writable = 001
    readable = 010
    readwrite = 011 (writable | readable)


Yes yes, but the point was, it can't be Shattering and Shattered at the same time ;)


I throw a baseball through a window, and set the window's state to both Shattered and Shattering. It's Shattered, for the purposes of "is this an intact pane of glass?" e.g. if I throw another baseball, it's not going to shatter again, and I can jump through it without any physical resistance (in the case of strong/thick glass, if it was still intact I might risk bouncing off if I'm at low velocity or mass).

But it's also still in the process of Shattering, so when I jump through it, I'm risking cuts, it's actively producing noise for someone to hear, that laser I'm shining at it will be fragmenting wildly rather than reflecting off/passing through/deflecting like it was before the glass started Shattering.


Ok, but it still doesn't make sense to use flags here, because according to your definition, a shattering window is always shattered.

Anyway, I don't think it's worth arguing design on this codebase because it is full of dirty things.


There are three distinct values: unshattered, shattering, and shattered which appear to correspond to 00, 01, and 10 with 11 being an unused state. This will always occur in boolean with 2 bits and 3 used values (unless someone stupidly gave it an undocumented purpose).


It could serve a dual function to describe what states are valid for a given piece of glass.

e.g.

EGlassRNState allowed = EGlassRNState_Initial | EGlassRNState_Shattered;

EGlassRNState current = EGlassRNState_Initial;


Time for a pull request? ;)


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


It also enables Enum.HasFlag.



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?


> Did you mean you actually type out mask values in base 10?

I believe that's what they meant. I worked in C# for many years, and many, many places wrote out bit masts in base 10 literals as no one realized they could just left-shift. Similarly, whenever I would use the ?? (null-coalescing) operator, the reviewer would inevitably point out my "syntax error", at which point I'd have to point them at the ~10th page of the nearest C# book to convince them that, yes, that is one of the valid operators -- and it's quite useful too!

Man, do I miss those first years of my career working in .NET -- dunno why I ever switched to OSS stuff.


Hex literals work pretty well for defining masks.



Carmack has some interesting comments on this sort of coding: http://number-none.com/blow/john_carmack_on_inlined_code.htm...


> "However, if you are going to make a lot of state changes, having them all happen inline does have advantages; you should be made constantly aware of the full horror of what you are doing."

Nicely put. :) Thanks for the link.


After many years of programming, I came round to favour more inlining than I used to (I probably wouldn't go as far as some of this function, however).

Needlessly increased variable scopes - and thus increased risk of harder to follow cross-dependencies - is probably the biggest downside risk. But I've found code that executes linearly easier to read and understand when it's written linearly. When everything is factored into functions - particularly impure functions - you need to click all over the place to understand the whole.

If there are higher-level primitives that can be used - filters, maps, folds, etc. - then they can reduce the verbosity overall. Some monadic styles can flatten nested code by computing a pipeline / computation rather than having lots of nested loops. But depending on the language and the problem domain, performance may suffer.


For me, this code looks like it was decompiled. It's pretty much this amount of insanity.


> When it gets to be too much to take, figure out how to factor blocks out into pure functions (and don.t let them slide back into impurity!).

This is a great piece of advice and one that has worked for me in the past when refactoring code like the one referenced.


    I was quite surprised at how often copy-paste-modify
    operations resulted in subtle bugs that weren't
    immediately obvious.

    I now strongly encourage explicit loops for everything,
    and hope the compiler unrolls it properly.
I found this particularly interesting


Seeing Carmack's thoughts on programming always reminds me that I have such a long way to go. When he was my age, he had already created DOOM and DOOM 2 (along with the wtf? r_sqrt trick).


Fun story: both ID and Epic started out making 2D games. When Tim Sweeny saw Quake for the first time, he literally gave up on gamedev because he thought he wouldn't be able to keep up with game tech. But, shortly afterwards a friend of Tim wrote a Quake-like 3D renderer as a fun project. Tim figured if that guy could do it, he could do it and went on the make Unreal.


Is this true? There's leaked Unreal alpha stuff from 1995, which was already doing almost everything Quake's bsp renderer ended up doing.


One important insight into all of this is that, while there might not have been BSP renderers until 1995, the BSP rendering algorithm was probably 10-20 years old at that point.

Another good example of this is the Phong shading model. IIRC it was invented in the mid-70s, and some software rasterizers implemented it, but it didn't really make its way into graphics cards with fixed pipeline rendering until the mid-90s.

Graphics tech in the 90s and even early 2000s involved a lot of hardware and software catching up to theory from the 70s and 80s because we were finally getting enough compute power to make it worthwhile to use "approximate" rasterization-based algorithms in order to get real-time rendering.


I had to dig up my source for this. I did misquote. It was Wolfenstein that gave Tim a shakeup and it drove him from coding to management, not out of games.

> Did you think about doing a first-person shooter after their success with Wolfenstein 3D and Doom?

> TS: It was funny how we got to that point. When I saw Wolfenstein for the first time, that was truly shocking. I'd never envisioned that you could do 3D in a computer game; I don't know why.

> The research had indicated that you could do that for at least 15 years before that, but it was this 3D game with real-time texture mapping; you know, real-time bitmaps scaled up and displayed in 3D on the screen. It never occurred to me that you could actually write code to do that. It was just another lack of foresight there.

> But seeing that for the first time, I was like, "Wow, I'm totally not worthy. I need to get out of programming now, because I'm never going to be able to compete with this." So they just basically demoralized me into becoming a manager for a few years.

> Around 1994, James Schmalz had written this 3D texture-mapping code, and I was starting to think, "Hmm, maybe that's not so hard." So I started reading up on references there and experimenting with it, and it turns out that, yeah, it's just another piece of code that you can learn how to create.

http://www.gamasutra.com/view/feature/4035/from_the_past_to_...


Yup, in hindsight it's interesting because the key innovation was realizing that real-time 3D was possible.

The algorithms themselves (like 3D texture-mapping) are college third year problem set level difficulty to actually implement, but having the curiosity, courage, and ambition to be the first to do it real-time is huge!

The algorithms used in today's 3-d game engines are definitely more complex than something I'd expect a college student to do, but the state of the art has also progressed substantially since the 90's.


That is incredible. I think that with games in particular, it is very easy to feel like you will never bridge the gap between where you are and whatever current AAA game is doing. It's easy to forget that those games we compare to are made by huge teams. The smaller games that are created by individuals and small teams are the product of a lot of effort. One simply has to stay the course and understand that a game is not made overnight. Still, it can be discouraging.


I don't believe he wrote the original fast inverse square root trick; but he is no less an inspiration for it.


https://www.beyond3d.com/content/articles/8/ for the history of it. The original author is still unclear, but that article digs back as far as Gary Tarolli at 3dfx/SGI (by way of Carmack, Abrash, and Terje Mathison)


Nitpick: Terje Mathisen [1].

The man is a legend. I remember using his little set of DOS utilities (things like stuffit.com [2]) back in the early 1990s, which I got from a friend whose dad was a colleague of his at Hydro. They were all written in assembly language, and were superb little extensions to DOS.

[1] https://www.linkedin.com/in/terje-mathisen-b740181

[2] http://files.mpoli.fi/unpacked/software/dos/utils/keyboard/s...


Heh, Terje's name is actually misspelled in the linked doc (I was like "I know I copy/pasted that")


Really interesting. I already began to inline code with a comment for each block. Didn't knew John Carmack agree with me.


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.


This code is not actually that _complex_, it is just _complicated_, and there are probably several people within the company that understand it completely. If you actually go through the code, I bet you will understand the majority of it. Step functions are annoying and complicated and need to be _fast_, less than half a frame long. And you need to do a lot in them, and all of those things are tightly coupled.



Wow.

Question regarding index access: There are tons of for loops with player[k] occurrences and similar. Personally I would create a local variable and prevent further index-retrievals.

Is this worthwhile or would a compiler optimize the array-index access away? Or maybe subsequent uses of the same index are cached by the cpu? Does someone know?


That's a micro-optimisation that's absolutely worthless. Even if you do pay the cost of indexing an array every single time, that's just a single instruction to fetch the address. The compiler is absolutely capable of caching the indexing for you, either in a register or on the stack, if it deems it worthwhile.

One reason you might want to use a separate variable would be to prevent indexing mistakes, like using i instead of k by mistake in a context where i is a nested loop's counter. But apart from this and other "to make it easier on the human" reasons, there's no point in caching that in a variable. Now, if you were writing Python on the other hand...


Holy batman. Now this is officially the worst piece of code I've ever seen in my 15 years of programming. This has to be generated... right?? I can't believe any human wrote this.

Grabs the eye bleach


It was written by a highschooler who made a 3D video game with decent physics and you're... criticizing him? Man, I'd like to see what YOU wrote in highschool.


On top of that, in a step function you really want to see what's being modified (that's kinda the point...). I suspect that monstrosity is easier to maintain than having state updates scattered around and having to jump to definitions and back to step() to understand the thing.


i think they don't use static code analysis on this part :)

generally agree on commenting, but it's also about discipline - method-level commands are rarely updated, but if there is some particular algorithm within method, I don't see a reason to describe it beforehand on a line or two.

General rule - if method is longer than my screen, it's time to refactor. very rarely this isn't a good idea.


maybe the author got a 4k monitor and set it up in portrait? :P


There are also 3 gotos in that function.


Goto should be used in the (admittedly rare) cases where it makes program flow cleaner. The original complaint was that people weren't moving to structured programming constructs as they became available. That really isn't a problem any more.


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 always think it is inappropriate to type declare like char* p1 in the first place. Yes, you want to be saying "I'm declaring an 8 bit integer pointer" but since in reality the pointer declaration is bound to the name in C, you should do it everywhere.

So I always do char \p1. Yes, for a non-C programmer its not as intuitive, but C isn't intuitive a lot of the time (cough, char p1[] what?). But you avoid making these mistakes altogether.

Note in function declarations I use char, because you cannot do statement expansion with a comma there, and because in headers the variable name is optional anyway.


You mean

    char *p;
?

I prefer to use char* p; as well as std::string& s; and etc. rather than attaching the type syntax to the name, since in essence that's part of the type. But yes, it's a mess that this inherited C logic doesn't treat it that way clearly. To avoid such mistakes, it's better not to use comma declarations altogether, you can perfectly avoid them.

It's a good feeling when working with new languages like Rust which avoid such mess.


Yes, the banes of markdown reap their ugly head again.

The point is, though, that while in a developers mental model you attach ref or ptr to the type, the language itself does not, and writing it out like it does can easily drive newer developers who do not understand the nuance to make hard to recognize mistakes as a result of it.


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


Looks like they are using some raw pointers there instead of iterators, that's why they loop like that.


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.


The fact that you are using university requirements as an exemplar is very telling. The moment I graduated and started hacking away in the real world is when I discovered that there was a lawless wild-wild-west of coding conventions out there.


A mish-mash of coding conventions is understandable, given the fact that coding standards may not exist in the first place, or can change over time, etc.

Long functions which have grown over time are also understandable, given the realities of changing requirements and such.

Thousands of lines of uncommented code, however, are not understandable... in the sympathetic sense, or literally.


Seems as you've picked up on the same thing -

"I've worked in the Games industry with age old engines, I currently work in embedded development with a code base over 10 years old - I'm fully aware of what "real life" code is like. There is no excuse for not writing well commented code - or even code with well named variables and functions that reduce the need for as much commenting. If you suffer from code like this in your workplace, perhaps actively comment it as you reach an understanding of what it does."

Relatively experienced 6 year C++ dev - I mainly mentioned university because things where much stricter - but having an environment with decent code reviews and maintaining a little self discipline goes a long way with the sanity of your co-workers.


You're a C++ dev, not a gamedev. They use different coding conventions. You'll find a lack of refcounted pointers, for example, whereas university teaches you to use them.

6 years is significant, but it's not a long time. There's much to learn, particularly about the cultural aspects of various segments of the industry.

This is excellent code that was produced on a tight timeline.


I was a game dev for 3 of my 6 years. I just got sick of the layoffs after project ends - and my university tuition was in fact games development specific.

*Edit - Yes though - by no means do I think I'm some big shot know it all. But I do have strong feelings about readability after having had to deal with code which is awful to grok.


Fair enough. It's a valid point of view. Sorry you had to deal with layoffs. It's one of the darker aspects of the industry.

To clarify, my objection was that we're criticizing this code for superfluous reasons when it's currently a delicate political climate in most game companies to even release code like this in the first place. It's probably best not to imply their reputation should be harmed by their lack of comments, since this can discourage other game companies from releasing their code in a similar manner. I've seen the argument "it might harm our reputation" be used to block endeavors like this.


I'd argue that a company should be able to take a little criticism - style based ones like mine will likely be ignored, as you mentioned before it's down to the culture of the company - for every function like the one outlined in the OP I'm sure there's countless examples of good style in the code base, engines are huge.

I really hope that companies don't view criticism as a negative thing, it's cause for discussion and change which are most certainly positive - I hope some bugs are found and they start to feel the benefit of the community a little.


What's wrong with managed pointers? Rust uses them just fine. C++11 has them natively.

Using raw pointers in C++ is rarely really needed.


In gamedev, using raw pointers is necessary. As a rule, game engines do not use refcounted pointers. This is because whenever you decrement a refcount, you're accessing the cache line in which the refcount resides. This results in thrashing the L1 cache, which translates into at least a 10% drop in performance. This is an unacceptable margin for game engines that fight to stay ahead of the competition.

More info on performance loss due to cache thrashing:

https://lmax-exchange.github.io/disruptor/

https://lmax-exchange.github.io/disruptor/files/Disruptor-1....

http://martinfowler.com/articles/lmax.html

http://mechanical-sympathy.blogspot.com/2011/08/disruptor-20...

And http://mechanical-sympathy.blogspot.com/ is great in general.

The reason that raw pointer management works in gamedev is because gamedev is closer to crafting than traditional programming. No one will die if a game crashes, and the iteration loop is a tight feedback cycle of code-compile-run code-compile-run.

Due to the nature of the entertainment industry, the codebase also loses much of its value within a year of releasing the game, as opposed to traditional software that typically gains value with time, meaning it's more important to get code out the door than to get it right. History is littered with the skeletons of game companies that disregarded this unfortunate truth.


> The reason that raw pointer management works in gamedev is because gamedev is closer to crafting than traditional programming. > No one will die if a game crashes, and the iteration loop is a tight feedback cycle of code-compile-run code-compile-run.

The more time I've spent understanding and building game engines, the more I see it as an organised network of state-machines managing and working with collections of data.

More often than not, shared state has clear ownership and lifecycle management built into the relevant state-machines. By isolating creation and destruction of resources in the transitional states (load and start a level, open a menu, change to Game Over screen), most of the code can safely reference data from other subsystems without reference counting, under the assumption that references are only valid until a global, shared transition in state.

Imagine a player entity that stores a reference to a model, texture, sound effect, input state, etc... If that data is loaded at the start of the level, and destroyed when the level ends, is there really a need to inc/dec a reference count if an enemy entity shares a sound effect reference?


Well, shared_ptr has its costs. What about unique_ptr though? It's not a raw pointer, but it's for transferring ownership, so it shouldn't have problems of the reference counting.


Ownership typically isn't transferred in a game engine, but sure.


Cases when different threads work on some objects passing them around aren't common?


They are, but in that case you'd use raw pointers.

The reason this works is because of discipline. Generally, there is a FooManager class which owns Foos. The FooManager is responsible for both allocating and deallocating Foos, regardless of where they're used. And in a game, "When should something be deallocated?" usually has a clear answer: When the level loads, for example, or when you move from one part of the continuous world to another part.

Then there are Subsystems (singletons) for each division of the engine: GraphicsSubsystem, InputSubsystem, etc.

Between those two patterns, there aren't a lot of ways to lose track of a pointer.


Great post, related to my thoughts above: https://news.ycombinator.com/item?id=11783491

I think another important factor is the pseudo-realtime update loop that synchronization is tied to.

Unless there is some garbage collection between game state changes (unloading unused resources during a level, etc...), its rare that references are invalidated unexpectedly, or accessed in parallel to the cleanup step between game state changes.

eg. a global state change from RUN to CLEANUP tells the subsystems to stop using a resource, so during the CLEANUP state the subsystems can safely delete any resources they have ownership of.


Idea of levels or areas isn't always applicable, and in vast open space games like Star Citizen or Witcher 3 with tons of random events you might need to load / free something pretty regularly I suppose, and it should happen seamlessly (i.e. if some event is triggered or passed).

So limiting lifetime of the object by some scope should work pretty well for it, and if you can pass raw pointers to transfer ownership, you can as well pass managed ones. At least it's safer.

Anyway, by using something like Rust a lot of such problems are solved by the language itself.


The idea of levels or areas is always applicable. A vast open game like Star Citizen is partitioned into area spaces, usually in a cubic array. When you move out of range of one of the cubes, past the point where you can see it, then all resources in that cube can be safely freed.

I don't know where Rust came from, since the discussion was about C++. But feel free to write an engine in Rust. It seems like a promising approach.


I hope it will happen eventually, especially with projects like this: https://github.com/tomaka/vulkano


To be clear, Rust does support refcounted pointers, but they're used very sparingly, and also have the advantage of allowing regular old pointers to their interior while remaining safe, which reduces refcount twiddling.


I didn't just mean refcounting, but simply managed ones (i.e. "smart" pointers), in contrast to raw pointers which require manual management.

Shared pointers (as in ref counting) is just an example of that, so I understood the above comment as implying that game development somehow encourages manual pointers management. May be I just understood the intention wrong, and it didn't mean to exclude other types.


Colleges normally stress perfect code against some theoretical metric.

Real-world work stresses getting stuff done. And in this case parts of the code can also take a life of their own.

Ideally both ideologies meet somewhere in between and you get code that works and is maintainable. But sometimes you can get bad code that is shipped... or an unhealthy obsession with polished code that never ships. One is infuriating, the other makes businesses slowly unfeasible.


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

This is usually the result of years of changing/updating the code. Any living code base tends to grow and accumulates cruft over time. Just because it doesn't fit the ideal you learned in university doesn't mean it is bad code, this is real life code.


I've worked in the Games industry with age old engines, I currently work in embedded development with a code base over 10 years old - I'm fully aware of what "real life" code is like.

There is no excuse for not writing well commented code - or even code with well named variables and functions that reduce the need for as much commenting.

If you suffer from code like this in your workplace, perhaps actively comment it as you reach an understanding of what it does.


This reminded me of my last place of employment. We didn't use any form of version control system. Instead, every time we changed a piece of code, we commented out the existing code and left it there, next to our revised code, along with a START and END comment including the coder's initials, date, and the ticket or project the change related to.

Frequently changed parts of the code were a hideous mess of 90% comments to 10% code. And then occasionally we'd just rename an entire file by prepending 'old' to it and starting fresh with a new file.

That place was such a learning experience on the concept of technical debt. But at least I got a fun talking point for my resume. "x++, is that a typo?" "No, sir..."


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 :)


1) What's the business goal of CryEngine putting this stuff out here. 2) (Possibly related) can you give an "I am not a lawyer, and don't speak for my employer, but here's a layman's take on it" interpretation of the CryEngine licence?


The license is basically you can use the engine for free with no royalties. Our model is Pay What You Want: https://www.cryengine.com/get-cryengine

Basically you pay whatever you want, if you want, and have a choice of how much of that goes to the developers and how much goes to an Indie Fund that we use to fund indie projects that use the engine.

We also offer "Insider Memberships" (https://www.cryengine.com/get-cryengine/service-packages) for studios that want some closer support from us, trainings, etc.


Wow. I really hope that works out for you... (and that this decision wasn't born out of desperation)

Because I really like this pricing model (and your engine) and I hope it will become standard over time ... but at the moment unfortunately it isn't and still too many people and companys won't pay anything if they don't have to. So good luck to you.


with unreal, unity and other things having zero cost (up front anyways); the playing field has changed.


>The license is basically you can use the engine for free with no royalties.

When you review the license, it is really not like this. Only games made explicitly for "entertainment purposes" can use the engine -- even "Serious Games", which I guess means games that may straddle any actual utility, are not allowed. Most likely Kerbal Space Program would be considered excessively "scientific" and not allowed to use CryEngine.

There's also a very scary clause that essentially says "if we don't like your game we can classify it as objectionable and withdraw your license".

This is a cool release from an academic standpoint, but should probably not be used by real people for real projects with the license as-is. There are many excellent truly open-source game engine options.


> There are many excellent truly open-source game engine options.

i'm not sure what you mean by "truly open-source"; what "game engine options" are you referring to?


>i'm not sure what you mean by "truly open-source"

Software distributed under a license approved by the OSI. These licenses, as far as I know, place no limitations on the type of speech that can be produced with licensed software. To use CryEngine, the people who work at CryTek must not find any of your project's content "objectionable".

>what "game engine options" are you referring to?

http://irrlicht.sourceforge.net/

http://www.ogre3d.org/

http://www.garagegames.com/products/torque-3d

https://github.com/id-Software

and many others; I'm sure there are big lists floating around. All of the engines listed here can be used even if the authors of the engine disagree with what you want to say, and I believe they've all been used in real, honest-to-goodness commercial games.


Unfortunately nothing in your list even comparable to UE and CryEngine. Ogre is just graphics engine (not game engine). idTech have great code, but it's even released dated and it's lack of tools.

Irrlicht and Torque is good options for small indie games (actually there many more great engines for small games), but they still can't be compared with "big" commercial engines.


This is nice, but can you please disclose the political views of your lawyers and C-suite? It seems that if a user happens to have a subjective political disagreement with someone at CryTek, the license to use CryEngine can be revoked per section 2.4, which states:

"use the CryEngine for the development of any Games which are harmful, abusive, racially or ethnically offensive, vulgar, sexually explicit, defamatory, infringing, invasive of personal privacy or publicity rights, or in a reasonable person's view, objectionable;"


Just checking but you do realize Creative Commons Licenses have this same clause. They call it "moral rights". When I asked about it I was told it's a right many countries require them to respect so it's in the license.

Note: I'm just as horrified as you about that clause but it's in every CC license AFAICT


> if a user happens to have a subjective political disagreement

given that politics tends to be much more qualitative than quantitative, it's unclear that any "political disagreement" can be anything other than "subjective".


Yes, I agree. I added "subjective" not because it uniquely qualifies the type of political disagreement, but because it emphasizes that your game's life is dependent on never having a simple disagreement with any present or future employee of CryTek. If the license to the engine is pulled, it would probably mean you have to start your project over from scratch.


There's also "enterprise licensing" which is probably where CryTek hopes the big money will come from. It's essentially moving the company towards more of a consulting business kind of model. That's the way I read it at least.


Sounds a lot like Red Hat's business model to me.


i didn't know what cryengine was. I mean, you probably don't need to tell people what it is, but the github repo, documentation introduction, homepage, and first page of the getting started material don't have the words:

"CryEngine is a game engine designed by the German game developer Crytek. It has been used in all of their titles with the initial version being used in Far Cry, and continues to be updated to support new consoles and hardware for their games."

which I found on wikipedia after clicking through 3-4 pages. General consensus seems to be that it is pretty awesome though, so keep up the good work.


Did you lose the source code at some point? Because it looks like the output of a decompiler.


Haha, definitely not. Which part looks like that?


Not sure if this would be a compliment or otherwise.


Are there plans to fix the art pipeline to not require expensive autodesk products?

In other words, fully and officially support blender :)


With version 5 we have an FBX importer that we are working a lot on. It should allow you to import from Blender or any other modelling packages


The beauty of open source is that people who want new features can submit pull requests. ;-)


From what i have seen there have already been attempts at this. The problem is there art pipeline is so archaic that nothing ever works properly.

In other words fixing the art pipeline needs to be an offical, fully supported endeavor. Which is why I asked.


I heartily agree. It would be nice if CryEngine had official support for Blender and would make CryEngine look better as well by supporting Autodesk alternatives.


Where is the actual UI code for the Editor? Is it included?

Oh and thanks for all your hard work, I've learned a lot from you guys over the years!


The Editor code is not included, we might include it later on


What does this function do? Was the person who wrote it atleast given an Oscar?

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


I haven't look through the repo yet, but I know there was some shake-up a while back with the Star Citizen developers injecting capital into CryEngine. I don't care about the politics, but I am curious how the branch published here relates to branches used by developers on those projects, i.e., will things like their 64-bit fork be merged at some point?


Is CryEngine Cinema is built into the engine? or that's a separate product?


I guess you are talking about Film Engine (used to be Cinebox). That's a separate product: http://filmengine.com/


What is it?


Not sure why I was downvoted... I didn't find any explanation of what this project actually is in the README, and someone associated with the project said to ask him questions, so I asked. Still don't know what this is. I guess it only caters to a specific "already-in-the-know" audience? I'll see my way out :)


Upvoted because of course you're absolutely right.



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?


1.10. “Serious Games”, i.e. ‘games’ which are not developed for the sole purpose of entertainment but for purposes training, simulation, science, architecture etc.


How is 'purpose' a legal term? What is the purpose of a game? To milk money from fans? To obey to some company's internal schedule? To entertain..... review sites? To entertain me? To showcase technology? To insert subliminal messages and DRM? All of the above? None?

What was the purpose of tamagotchis?

We may never know.


From what I've seen, courts are frequently asked to answer questions just like this one. They do not seem to be as troubled by slippery slopes because it's their job to decide where the line is.

If you're a student using CryEngine you're probably not worth suing for copyright infringement (at worst a C&D maybe). If you're a corporate entity who is distributing a game which licenses CryEngine, you certainly may be worth suing for infringement.


Which subsection restricts a corporate entity from distributing a game built on CryEngine?

There are restrictions on Serious Games, but amusingly a Serious Game isn't a game.


I disagree, re: serious game. It's why we have the term gamification. Taking something mundane and making it, for my lack of a better term, gamey.

I'm thinking of things like Starfighters.


There is a section[0] of the licence[1] which allows students to develop a Serious Game, but not for profit.

[0] 2.2. If you are a student or a member of an academic institution you are in addition entitled to develop Serious Games using CryEngine and to render such Serious Games in object code form (including the CryEngine Assets and the CryEngine Redistributables) pursuant to the CryEngine documentation. However, you are in no case entitled to commercially exploit such Serious Games without Crytek’s explicit prior written approval.

[1] https://www.cryengine.com/ce-terms


It is probably an arse covering measure. If someone uses the engine for serious work and it somehow fails, there isn't a route to ask them to cover financial/other damages because they told you not to use it that way (and you agreed not to use it that way via this license).


Game engine companies actually tend to have separate licenses for Serious Games, with different terms and costs. This is because a Serious Game is often unlikely to be mass-market - at the extreme end of the scale, it might be developed for only one client to ever use.


>What was the purpose of tamagotchis? We may never know.

But we can breath a sigh of relief that whatever it was, we beat them in the end.


At that point are they even games anymore?


Kerbal Space Program?


Games without physics, not Turing complete and no building. Bye Minecraft, for one. Garry's Mod too.


If you read the Visual Studio EULA, which I did when the first Visual Studio .Net version came out, it described in a long and complicated text a certain type of software which you aren't allowed to compile with it. I don't know if this changed in the meantime because I have only read one EULA and that was it, but the software described neatly formulated the conditions of copyleft licensing. So in essence Visual Studio .Net forbade one from building things like GPL software. I'm sure the Visual Studio .Net EULA is available somewhere to dig this up.

What I'm getting at is that this isn't the worst license from a commercial-first software distributor.


Would this be the thing you're referring to?

  https://wiki.wireshark.org/Development/MSVC7
About a paragraph down that page, it mentions the concept of Visual Studio 2003 not being allowed to compiled GPL code, stating that's a misconception.

The original EULA doesn't seem to be online any more though, so it's hard to tell.


I don't know because I can't find the EULA I saw in the installer dialog on Windows myself, so it's pointless for me to speculate, but it's funny because it's the first and last time I read a EULA, while I was waiting for the installer to finish. Since it's written in legal language, and I was much younger and inexperienced/uneducated, I might have fallen for the same incorrect interpretation. Seeing how wireshark has a separate section and I was able to find a Slashdot post, it seems I wasn't the only one who found something curious.


My Google-fu produced the following Microsoft ISVLA from 2009 (not VS-related, but this language appears in several of their EULAs from the 2000s):

http://www.microsoftvolumelicensing.com/userights/Downloader...

> Potentially Viral Software. Your license rights under Agreement and/or Academic Agreement are conditioned upon your compliance with the following terms: You must not: (a) Integrate or otherwise incorporate Potentially Viral Software into, or combine Potentially Viral Software with, any Licensed Product, Software Documentation, or derivative work thereof; (b) distribute Potentially Viral Software in conjunction with any Licensed Product, Software Documentation, or derivative work thereof; or (c) use Potentially Viral Software in the development of any derivative work of any Licensed Product or Software Documentation. “Potentially Viral Software” means software which is licensed pursuant to terms that directly or indirectly (i) create, or purport to create, obligations for Microsoft or our suppliers with respect to the Licensed Products; or (ii) grant, or purport to grant, to any third party any rights or immunities under Microsoft’s or our suppliers’ intellectual property or proprietary rights in the Licensed Products. Potentially Viral Software includes, without limitation, any software that requires as a condition of use, modification and/or distribution of such software that other software incorporated into, derived from, or distributed with such software be: (a) disclosed or distributed in source code form; (b) licensed for the purpose of making derivative works; or (c) redistributable at no charge.

I'm not a lawyer, but this term sounds scarier than I think it is. "Potentially Viral Software" is defined to be software under a license that places obligations on Microsoft (which would be every license offered by Microsoft, and no license not offered by Microsoft, so as its only effect is to prevent you from using Microsoft software, it seems an unintelligible term). It goes on to say this "includes... software that requires... [being] distributed in source code form" but that has nothing to do with "Potentially Viral Software" as defined just before.

My gut says Microsoft wrote this term in a manner calculated to confuse drive-by software engineers into believing that VS can't be used to compile GPLed software, that the GPL creates obligations on third parties, or both.


Perhaps the idea is to prevent the linking of binary blobs and/or other code in eg: standard libc, c++ libraries, win32 api that Microsoft provides, with GPL software and then distributing that binary - and so implying that the standard libc and other bits are also under the GPL?


Thanks for digging that up. It reads vaguely familiar. The point of a EULA is for the End User to sign it. If the end user cannot understand it, does this mean they have to ask a lawyer before clicking Next in the installer?


I don't understand your question. "The point" of an EULA is subjective, and depends on your legal strategy, and the exact text of the document. It is generally a good idea to ask a lawyer before agreeing to anything you don't understand. I am not aware of any law requiring one to consult a lawyer before clicking next in an installer.


The whole concept of EULAs that cannot be understood by non-lawyers goes against the aim of having them read and accepted by end users before running an application. The problem is that there's no standard text where it'd say you agree to ISO-XYZ and everyone knows it's a respected and well understood agreement that's in use for all kinds applications already.


There certainly are "respected and well-understood" "standard" texts, for example, the Apache or GPL licenses are widely understood and are used for "all kinds of applications already." The legal analyses of these texts runs into the millions of pages; we know quite a lot about them at this point.

What I believe you misunderstand is that "the aim" or "the whole concept" of an EULA is not to explain things clearly to end users. On the contrary, "the aim" of an EULA is to offer terms that are favorable to the licensor (and thus unfavorable to the end user), and this aim is best accomplished when the user does not especially comprehend the document. In other words, "the aim" of an EULA is to be obfuscatory.

Anyone who wanted to use a standard document has many options to choose from that are probably familiar to you. ISVs who have passed over the ten-or-so standard texts that you are familiar with will not be convinced by an eleventh.


Well, then EULAs as they are done today should be forbidden.

I've read Apache2 and GPL2 licenses and I can't say I comprehend them fully. Read the liability clauses in GPL and Apache licenses and compare them to MIT or BSD.


Saying that licenses should be readable to software developers is like saying sourcecode should be readable to lawyers. It's a nice idea, but in the real world, even problems as simple and universal as loading an image over HTTPS is totally impenetrable to anyone outside the software development profession.

It is the same for the law. Even the basic "email-grade" legal problems are actually very complicated, and it is no good trying to simplify them down to a lay level. I'll defer to Lawrence Rosen on this, from his book Open Source Licensing: Software Freedom and Intellectual Property Law:

> The same programmers who cringe when a lawyer attempts to write high-quality software feel no qualms about writing their own open source licenses. Their goal, it appears, is to craft something that sounds like a license, to define a form of software freedom with reasonable terms and conditions, and then wait for the community to adopt the license and distribute software under it. This technique sometimes works. Some members of the open source community are more concerned with mak- ing a philosophical statement, getting free software distributed to the world, and letting license enforcement take care of itself somehow in the future. That can be a commendable goal, but from a lawyer’s perspective, it is amateurish and risky.

The reason that BSD/MIT seem readable to you is actually that they lack a lot of clarity on important points. For example, they say nothing at all about patents, which is the primary type of software litigation today. So an Oracle-type could offer you software under an MIT license, and then turn around and sue you under patent law for using the software they offered you. Whether they would win is an interesting question, but we will not find out because you will settle.

Meanwhile, Apache2 or GPL3 or other post-1970s licenses have actual clauses to deal with this. So now your lawyer can print out the license, highlight a sentence, scribble "SEE?" below it, add "Respectfully submitted, John Smith Esq." at the bottom and that is the end of your lawsuit.


If you bought the software and can't understand the EULA, aren't you entitled to legal counsel by the makers? I imagine you could stir up quite a shitstorm if they refuse, i.e. "company X tries to bind you to terms they DENY TO EXPLAIN".


I never heard of such a thing as VS prohibiting the compilation of GPL code.


It didn't say GPL. There was a long section describing code of certain kind, which was a long-winded description for the rules of copyleft, and then a reference to that type (call it X) which may not be fed into MSVC. Like I said this was the EULA for Visual Studio .Net (the first version) and probably more than a decade ago. And as I said also, I don't have the newer EULAs so cannot look for the same section in those. I wish I had saved a copy back then but I wasn't as professional, sorry.


> So in essence Visual Studio .Net forbade one from building things like GPL software. I'm sure the Visual Studio .Net EULA is available somewhere to dig this up.

Maybe I miss something, but you literally said that they didn't allow one to build GPL software.


I wrote "things like GPL" and said it described the copyleft licensing without naming the prominent license.

But I cannot find a version of the first (2001 or 2002) EULA, so it's possible my memory isn't exact.

Edit: All I could find https://yro.slashdot.org/story/02/08/04/132221/more-ms-eula-...


Anyway, given the Microsoft of today, it's doubtful they would try something like that, so this isn't relevant anymore, but it demonstrates that EULAs are written in the language of laws and unrealistic for users to read and grasp correctly. MIT and ISC licenses are simple to understand, whereas GPL and Apache are long and some sections are hard to follow without a law degree. Same issue with EULAs.


You missed the word 'like'. As he is no lawyer he avoided to give a concrete example, but he tried to describe the lawyer speak with a more understandable example. What is your interpretation of the EULA text?



I think it's mainly related to Mass Virtual (ex. RealTime Immersive Inc) business that mainly worked on military simulators. At least in past it's was Crytek's company.

http://massvirtual.com/portfolio/video/



How about anything by TruSim [0] :-)

http://seriousgames.com/


Uh, First thing I saw was .exe on git.

You can still use the src to investigate bugs in source code and walk-around them in your product.


> 1.10. “Serious Games”, i.e. ‘games’ which are not developed for the sole purpose of entertainment but for purposes training, simulation, science, architecture etc.


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.


That would be great, but both Epic and Crytek have no reason to do that. Releasing under copyleft would mean there will be forks with changes they can't use for their proprietary branch.

They of course have no reason to use permissive licensing too since that would mean someone else can make money off it.


The x264 library is GPL (i.e. not LGPL). To use it in a closed-source product you can pay for an interesting kind of commercial license, the terms of which are you /must/ submit your changes upstream (privately). The upstream can choose to accept anything that's possibly useful, and will reject anything that was application-specific.


I have no idea if this business model work for x264, but I sure it's work for Qt and few other open projects.

Unfortunately companies that developing game engines not going to benefit from copyleft licensing since there is no demand for GPL from real game developers. After all there is very few open source games around and only bunch of them aren't clone of something else. Probably none of these projects ever going to need anything as complex as CryEngine: there is enough of good open source engines for indie games.

So if they release engine as GPL they simply won't get any more developers in community. At best there will be few incompatible forks made by developers who only want to release changes under GPL.

PS: So just keep in mind that in case of CryEngine "source available" offer appear because it's only way to compete with other commercial engines and make money. They intentionaly keep it proprietary instead of going open source since it's better for their business.


Yeah, GPL or AGPL would be way less ridiculous than their current license. I'm not sure why are they so concerned if you make an offensive game.


I agree. There are a lot of things that I'd want to do with this engine that involves security research that I just can't do.

Does this also mean that flight simulators cannot be written on this engine? I used to play a lot of those for fun, but that could fall under "serious software".



Looks like they've included the entire python stdlib, which that file is part of.


But it also looks like they forgot to include the license, which is required:

https://wiki.python.org/moin/PythonSoftwareFoundationLicense...

(I Am Not A Lawyer, and all that.)


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.


Just sent this comment to the right people, thanks! :)


Thank you too :)


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.


> To me, this is a halfhearted attempt to catch up with Epic and Unreal Engine 4

I do rather think it's a last desperate attempt to get it out before crytek is going bankrupt.


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.


> The coding style is very Microsoft-like, which is I suppose not a big surprise given it's DirectX roots.

Just in case first CryEngine and early versions of CryEngine 2 had OpenGL renderers, but code style was pretty much the same.


What do the !XT, !B, !U etc. mean in the commit messages?


Internal codes to know what the check in is about: bug, feature, update, etc.


So .. why would anybody care about Amazon's Lumberyard now that this exists?


No serious game developer should care about Amazon Lumberyard in the first place, other than informationally.

Lumberyard is an immense lock in to the amazon stack with a lot of small print, a huge risk if you believe your game to be worth anything.


Apparently developers of serious games shouldn't care about cryengine eighter. ;)


What are you talking about?

CryEngine has (had?) fairly bad licensing terms overall but they're working on them (this OSS strategy is likely part of that) and they are nothing like the Lumberyard terms which essentially buy out your soul.

> 57.4 Operating Restrictions. Without our prior written consent, (a) the Lumberyard Materials (including any permitted modifications and derivatives) may only be run on computer equipment owned and operated by you or your End Users, or on AWS Services, and may not be run on any Alternate Web Service and (b) your Lumberyard Project may not read data from or write data to any Alternate Web Service.


I am talking about "serious games", because you aren't allow to develop them professionally with cryengine without written consent. It was a word play to your "serious game developer".


Haha woops, completely missed that.


yes... aws provides an engine and they ask that, should you use run any infrastructure in "the cloud" that it be their cloud. it's not that strange.


I'm not saying it's strange, I'm saying a game dev worth its salt would not even consider it.


plenty of games use aws, so i'm not sure why you say that.


It doesn't matter what tech you use now. Locking yourself into that tech from essentially the root of your game is a terrible idea.


this seems like a bit of a red herring. "locking yourself" is a bit under-specified - picking unity, unreal, cryengine, phyreengine, or whatever is also doing just this. choosing physx or havok is a fork in the road. etc. presumably one is making these choices after carefully evaluating options.


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?


A cursory Wikipedia search would yield an explanation:

"A serious game or applied game is a game designed for a primary purpose other than pure entertainment. The 'serious' adjective is generally prepended to refer to products used by industries like defense, education, scientific exploration, health care, emergency management, city planning, engineering, and politics."


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?


For the past couple of months you could get it from the website as a .zip file, but now it's source controlled properly in GitHub and connected internally to Perforce.


I see, thanks for the clarification.


I think you could get the source somehow, but maybe it wasn't on github?

Only has 90 stars ATM which seems odd if it has been up here for a while.


Are you thinking of Unreal Engine? The source for CryEngine as only been available since March or April.


Nah, I meant CE. I guess I should have specified "a while", heh.


The first commit seems to be from april, so it can't have been on github for much more than a month or so.

Before it was under perforce, apparently.


Most likely they'll continue to use perforce internally. GitHub is just for pull requests and game developers.


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


Modify you can:

2.1. Grant: Subject to strict and continuous compliance with the restrictions of this Agreement Crytek grants to Licensee a non-exclusive, non-transferable, non-assignable, non-sublicensable, limited license (the “License”) only:

[...]

2.1.2. to develop, maintain, extend and/or enhance CryEngine pursuant to the CryEngine Documentation;


Yeah, that's a big restriction on modification. You can only modify it in the ways that they document that you can modify it?


Hm, you are right, I didn't read that right the first time round. Really depends on what that documentation looks like I guess.


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.


It's the full source code, so headers and code


Could you comment on why there are lots of (non-templated) function definitions in the headers? Looking at it, it doesn't actually look like there is that much, from the two random files I opened. In the first random file I opened[0] I didn't really understand why some of the functions (see link) were defined in the header.

In another file[1] it seemed to make more sense (getters and setters, along with a smallish class where I guess you didn't want to bother making a new file).

[EDIT] Could I also ask why you have defined some very large classes entirely in the cpp files[2]

Also, thanks for this, very interesting to read the source for other large projects.

[0] https://github.com/CRYTEK-CRYENGINE/CRYENGINE/blob/63418e7c9...

[1] https://github.com/CRYTEK-CRYENGINE/CRYENGINE/blob/63418e7c9...

[2] https://github.com/CRYTEK-CRYENGINE/CRYENGINE/blob/63418e7c9...


There are a few reasons you would do this in CPP, though I'm not sure whether they apply to this case.

You might put function definitions in headers to (1) avoid linking a library (2) explicitly declare a function as inline, maybe (3) it's simple enough that you don't lose readability by inlining it.

The one about putting large classes entirely in CPP files: I wouldn't do it this way for readability reasons, but putting it in the CPP file directly does restrict anybody else from using what is supposed to be a one-off helper class. I think that's the intent here.


The only reason I have seen it done (and done it myself) is to avoid having to link to a library, so you put the implementation in the header of that library. No idea if that's the case here though.


Most logical reason: in past they shipped binary engine SDK with headers only and probably even sell licenses without full source code. This is reason quite few things defined in headers so it's easier to understand how code works without access to full source.


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 =)

More

Applications are open for YC Summer 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: