Live data from Hacker News

Why C++ for Unreal 4

forums.unrealengine.com

161–170 of 178 posts

Re: Why C++ for Unreal 4

#161
post #108
post #75

This was refreshing. I'm struggling with the same problem...I've embedded Lua in my C++ engine for high-level scripting. Unfortunately, as my scenes became more and more complex, I found myself struggling with representing the inheritance hierarchies in Lua, as well as things like object ownership/gc (resorting to passing around shared_ptrs in Lua userdatas). And for each new data type, I had to write the same old C+…

Embedded scripting languages seem to work best on what I'd call a 90/10 model. Either your game is written in the scripting language inside a thin compiled shell (to provide access to system routines and the occasional optimization), or your game is written almost entirely in the host language and just configured using scripts. So: 90% Lua, 10% C++ or vice versa, but not 50/50 or the like. In general, it seems to be…

Alternatively, write most of it in C++ and allow it to be extended with components written in script, ECS style.

Or something else.

Honestly, having too much scrip is very much a thing to try and avoid. Perf (gc, etc), long term maintainability (usually no static types in script), tooling (frequently no debuggers, profilers, or the ones that exist are low quality), etc are all reasons for this.

If you're going to have 90% lua, you probably should be writing the game in lua anyway...

Re: Why C++ for Unreal 4

#162
post #112

Earlier quoted context omitted.

No worries, it was a good question! I would highly recommend hopping on the IRC if you'd like some more information or have a chat. The community is very active and friendly. You can see the list of channels here: http://static.rust-lang.org/doc/master/index.html#external-r... Regarding exceptions: whilst they can be be very useful, unfortunately a significant number of large, performance sensitive C++ projects outla…

> due to overhead My understanding is that the old exception code called "SJLJ" (short for setjmp, longjmp, which is what it was) was slow. I think each try/catch required hooks, and yes, it was. The newer compilers generate something called "DWARF"; resources on it are unfortunately scarce, but my understanding is that you don't pay anything in speed for an exception until you throw one. (You do however pay a bit of…

Yeah, I will admit I am not an expert in exceptions, so I might have been incorrect in my response. I'm sure there would be better people to talk to on the #rust. Alternatively you could ask on the mailing list or /r/rust.

Re: Why C++ for Unreal 4

#163

It will be interesting if any major game engines pop up using Rust as the core language, or even Go. C++ has been the king of highly optimised game engines for so long, I can't help but feel it has become so entrenched in the industry that it will take something monumental to disrupt it.

I have high hopes for Nimrod [1] in that regard. Unlike Rust and Go, Nimrod is able to be almost as fast as C/C++ without sacrificing syntax; Nimrod's syntax often looks entirely like Python. For example, here's the example from the Nimrod home page: # compute average line length var count = 0 var sum = 0 for line in stdin.lines: count += 1 sum += line.len echo "Average line length: ", if count > 0: sum / count else:…

Nimrod is a great language, but it has different goals to Rust. You get better expressiveness, and cleaner code, but you don't get the huge benefits of Rust's static type system. It depends on which you value more - I think there is a place for them both though.

Re: Why C++ for Unreal 4

#164

Earlier quoted context omitted.

Honestly, I've made over 15 games in my career and safety with C++ really just isn't an issue with decent developers. The line between what's a programmer for games and what's a designer is narrowing, most designers are competent programmers. Furthermore, there's some great tools out there to help prevent things like memory leaks. Combine that with good company practice, like code reviews, and it becomes a non-issue.

It seems like it's hard to say if Rust really would have eliminated those bugs, the reports are vague and the ones that aren't, e.g. fixed framerate issues, would be an issue either way. My argument isn't solely get good developers and be done with it. It's a combination of things, and one of the most important things is getting good practices in place. I don't know if EA did this but having a good auto-test system i…

> one of the most important things is getting good practices in place

That is really important, but still, wouldn't it be better if you could encode at least some of those good practices into the language itself, rather than relying on humans to be constantly on their game? I'm certainly not perfect, so I would rather my sloppiness be caught earlier rather than having it come back to bite me in the future. See: http://thecodelesscode.com/case/116

Re: Why C++ for Unreal 4

#165

Earlier quoted context omitted.

The biggest advantage of scripting for me has been 1. Co-routines Co-routines (co-operative multi-tasking?) mean you can do stuff like while (isWalking()) { advance(); yield(); } This is effectively 'yield' from Python, C#, etc.. You can implement this in C++ by swapping stacks and calling setjmp but there's usually issues. 2. Iteration time You can usually swap script code live. This project aims to fix that for C++…

I've been using threads to do co-operative multi-tasking, for a while now. Every place that I'm tempted to write an event-driven finite state machine, or something similar, I spawn a thread instead. I get to write synchronous code, which feels much more natural to me. For instance my actor, running in a thread, calls a function like advance(). That drops data into an object, and wakes up the main thread, and blocks.…

Don't you still need to carefully use locks everywhere? For me the one reason to use coroutines instead of regular threads is that coroutines are cooperative multitasking, rather than preemptive. Which is what I want for when I have a bunch of concurrent but not parallel processes working on shared data.

Re: Why C++ for Unreal 4

#166

Earlier quoted context omitted.

The slightly obscure music programming language SuperCollider [1] added co-routines about 10 years ago and they became one of my beloved techniques. Was very glad to see them come to python and soon to mainstream javascript. Boost has a c++ implementation but it looks quite different: http://www.boost.org/doc/libs/1_55_0/libs/coroutine/doc/html... [1] http://supercollider.github.io edit: pythons new asyncio stuff loo…

> Was very glad to see them come to python and soon to mainstream javascript. I really need to get around to writing a blog post to explain this in detail since this misapprehension is endemic. Python and JavaScript do not have coroutines, they have generators. Lua has actual coroutines. The latter is dramatically more expressive than what you can do with what Python, JavaScript, and C# offer. This mistake drives me…

Yield and generators (i.e. save stack; return value to caller; receive value from caller) are really a language feature for writing a runtime for a different language with coroutines. Or if you're willing to write your program in a way that looks like it was generated by a source-to-source transformation tool, you can write your coroutines on top of them. The most basic construct is something like this:

  CurrentCoroutine = None


  def run(main, arg):
    global CurrentCoroutine
    CurrentCoroutine = main
    while CurrentCoroutine is not None
      CurrentCoroutine, arg = CurrentCoroutine.send(arg)


  def corodecorator(coro):
    @functools.wraps(coro):
    def init():
      c = coro()
      c.next()
      return c
    return init

And this is pretty much it. A simple example for two coroutines that pass control to each other would be:

  @corodecorator
  def coro1():
    # yield nothing on first call to receive args
    arg = yield None
    friend = arg[0]
    while True:
      print('coro1')
      arg = yield friend, (CurrentCoroutine,)
      friend = arg[0]


  @corodecorator
  def coro2():
    arg = yield None
    friend = arg[0]
    while True:
      print('coro2')
      arg = yield friend, (CurrentCoroutine,)
      friend = arg[0]


  run(coro1(), (coro2(),))

You can do the same with javascript and events, but it requires a much higher degree of masochism.

Re: Why C++ for Unreal 4

#167
post #67
post #59

It's important to note that what is being talked about in this post is not, "why we wrote the Unreal engine in C++", because it already was in C++. Many games, older Unreals included, had a separation between "code" and "scripting", where stuff like animations, weapon firing, etc. was written in scripts, in the belief that this would be easier to update as required vs. C or C++ code. Doom 3 and previous Unreal engine…

I would guess the idea was to enable non-coders (esp. artists, level designers etc) to handle many of their needs themselves - for faster iteration. But maybe the UnrealScript wasn't simple enough in practice to do that? Or perhaps, giving people a template function, and a few functions, is just as easy/hard as a separate scripting language. Generally, scripting languages are a really great idea: consider all the bas…

It sounds like the problem was that UnrealScript was initially too simple for the applications it was pushed to, which led to more and more of the underlying system being exposed through the interop API.

Re: Why C++ for Unreal 4

#168

Earlier quoted context omitted.

Extraordinary claim- please elaborate. I'm working on 100's of thousands of lines of C++ code with a medium-sized team; memory issues are almost non-existent because of disciplines described above.

I've described this many times in the past, but here are a few things that modern C++ does nothing to protect against: * Iterator invalidation: if you destroy the contents of a container that you're iterating over, undefined behavior. This has resulted in actual security bugs in Firefox. std::vector v; v.push_back(MyObject); for (auto x : v) { v.clear(); x->whatever(); // UB } * "this" pointer invalidation: if you ca…

[deleted]

Re: Why C++ for Unreal 4

#169

Earlier quoted context omitted.

Extraordinary claim- please elaborate. I'm working on 100's of thousands of lines of C++ code with a medium-sized team; memory issues are almost non-existent because of disciplines described above.

I've described this many times in the past, but here are a few things that modern C++ does nothing to protect against: * Iterator invalidation: if you destroy the contents of a container that you're iterating over, undefined behavior. This has resulted in actual security bugs in Firefox. std::vector v; v.push_back(MyObject); for (auto x : v) { v.clear(); x->whatever(); // UB } * "this" pointer invalidation: if you ca…

Use after move by itself is not undefined behaviour.

Re: Why C++ for Unreal 4

#170
post #153

Earlier quoted context omitted.

Right; stl sucks. So its work, but you can make ref-safe containers, even thread-safe ones. We do that; we do audio rendering with audio-chain editing on the fly, with no memory issues. It takes care, more care than other languages. But its far from unsolvable.

Of course it's possible to write correct C++ code, just like it's possible to write correct assembly code. The point is the extra care required: every piece of code needs to be very carefully authored to ensure it's correct, to avoid the myriad pitfalls.

Or you can just trust the language. And if its not right, or not the way you plan to use it, what then? You're stuck unless the language also permits you to roll your own.
Post reply on HN