The main problem with scripting layers is that you are basically handing programming tasks over to team members who's job is not to solve programming tasks, and thus getting a lot of beginner's code quality and performance problems which are almost impossible to debug and profile (unless you have a few top-notch coders in the game- and level-design teams).
And then there will be definitely those "creative workarounds" to get something done which neither the engine nor the scripting layer was designed for, which make entertaining horror stories the programmers tell the new hires when they inevitable ask why your engine doesn't have scripting ;)
A better approach is to give the level designers simple, pre-programmed, combinable high-level building blocks (AI behaviours, actions, triggers, etc), and let them customize a level (as in game area) with this. But never build the entire game logic with such an approach! With this, stuff can still be fucked up, but at least the performance-sensitive stuff can be implemented by the programming team, and it's much easier to debug and maintain.
[edit: typos]
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++ though I'm a little skeptical it can stay robust
https://github.com/RuntimeCompiledCPlusPlus/RuntimeCompiledC...
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 looks very interesting:
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.
The next time the main thread wants to give processing time to the actor, it describes the world into the same shared object, waked up the actor's thread, and blocks.
Doing a switch like this dozens or even hundreds of times per second seems to work pretty well, especially if the main thread only gives execution to the actor thread when it needs to - inputs have changed, etc.
For my use cases, it radically simplifies my code, and I have a small number of different inputs to handle, so it has been scaling well.
An ideal scripting language:
- Allows designers to build complex gameplay elements, define complex ai behaviors, create gameflow with minimal work from the software engineers.
- Handles memory allocation/destruction behind the scenes
- Does not crash the game when an error occurs
- Handles multithreading and/or events
- Does not allow designers to shoot themselves in the foot
- Has a simple and clean syntax
- Allows software engineers to expose their APIs to it easily
- Can be reloaded on the fly
If you control the feature set of the scripting language then it becomes a crucial tool for rapid development of your game - empowering the creative team to make their game and allowing the software engineers to concentrate on all the other stuff that needs their attention.
In my opinion visual scripting and component systems can be a useful addition to an engine, but I have always seen a usefulness in having a scripting language layer.
(I have shipped multiple high profile console games with more lines of script code than of game code and design teams matching the size of the programming teams)
I disagree that it has to follow that scripting -> bad code. I think of the C <--> scripting integration that I do as a Judo secret weapon. I get to easily fling "high-performance" C around in a super-dynamic way (REPL, easy-to-use high-level abstractions)... I think the problem you're describing is real (possibility to abuse/mis-use scripting power), but dismissing the notion of scripting plus C/C++ because of possibility of abuse seems like throwing out the baby with the bathwater. Better addressed with training and culture.
It sounds like having a real software engineer do code reviews and/or rewrite the poor scripts before they get committed would be a solution to this problem. Presumably giving level designers the ability to script things is good for the game play.
> 'What starts out as a sandbox full of toys eventually grows into a desert of complexity and duplication.'
is beautiful and is a pattern I've seen multiple times before. Its not feature creep per-se, but more something a bit more insidious in software development.
Rust for instance looks very promising but you still have to go through the tedious task of redeclaring all the prototypes of the C functions before you call them, it cannot directly parse C headers (as far as I know). That makes writing hybrid code (for instance incrementally porting code from C into Rust) much more difficult and error prone than they need to be.
https://github.com/crabtw/rust-bindgen/
There are also long-term plans for adopting this into the compiler itself:
That is the only way to make people adopt them. Otherwise they become just another language to do business applications.
It is very possible to write games in high-level languages, but you will lose at least half the compute power of the machine by doing so. Note that unless you're writing a Gears of Wars, you don't really need such performance and productivity wins once again.
As much effort as they put into the IDE it would always play second fiddle to Visual Studio. When I left there was no way to remote debug unreal script on the target device (this may not be the case now).
I know that all of the guys I worked with in the studio would welcome pure C++ approach. The only real losers here are mod makers who will have a higher entrance bar.
They didn't really drop the highlevel language, they just dropped the idea of a highlevel general purpose language, favouring a strict DSL.
There's still a bit of interop, but you have to be very explicit about it. In C++ you use macro's to tell the compiler what's accessible to blueprint, and to access blueprint from C++ you have to make weird queries that are very obviously highly dynamic and ill-performant.
So cool stuff all around :)
The reason builds were sometimes a bit tricky was due to chicken and egg syndrome because the script compilation wouldn't just compile scripts, but also modify headers to support the new objects created in script.
Aside from the performance issues, the main drawback (to me) with UC was definitely how tightly coupled to native code it was.
PS: I like the BluePrint though.
Doom 3 and previous Unreal engines had scripting languages; even the first moddable FPS engine, Quake, had a 'scripting language' of sorts -- Quake C, a sort of subset of C. id software turned back to pure code with the Quake 4 engine, however, recognizing the mistake that introducing the overhead of script-vs-code, and the limitations of scripts, outweighs any gains from being "easier to edit".
Quake 1 ran a virtual machine, which QuakeC compiled down to. Quake 2 ran native code via DLLs. Quake 3 ran either VM code or native code--depending on how clever you wanted to be, you might need to break into the native code.
There wasn't some "mistake" about using scripts-vs-code, because they would actually compile down to executable bytecode. This made it much easier to load mods over the network if you needed to, and to port their tech to different architectures.
idTech 1-3 internally were a lot more like VR operating systems than scriptable game engines.
and the limitations of scripts, outweighs any gains from being "easier to edit"
Wrong, wrong, and wrong. The mod scene flourished back in the day specifically because it was so easy to bodge together mods in these friendlier environments--especially in the Unreal series.
The place where scripting falls apart is in modern AAA games where way too much stuff is expected of/exposed to designers, and then you end up with gigantic sprawling piles of poor performance. A friend worked with a licensee of the Unreal engine for a few games, and their script dispatch switch went on for...well, let's just say that many good programmers lost many good hours in those mines.
Scripting is a perfectly good tool, and one that makes sense until you start doing crazy AAA stuff with it.
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 bash scripts in unix. An imperfect mismatch with the underlying language, yes; but worth it.
http://dconf.org/talks/evans_1.html
I wonder if some of the same points would apply here. The short version of the talk is that D compiles much faster than C++, has limited C++ link compatibility (e.g. classes, but not templates), and overall has nicer syntax / language features than using C++ directly. Metaprogramming / compile-time introspection allow automatically serializing/deserializing data to allow updating data structures without restarting the engine.
This is why I follow with high interest the work clang guys are doing for the committee.
[1] http://www.w3.org/TR/WebIDL/
[2] http://jstenback.wordpress.com/2012/04/11/new-dom-bindings/
I also know of a few game development studios with R&D departments who have had an eye on Rust in the past, though I bet it will be a long time before a major studio is willing to make the risk that writing an engine in Rust would entail.
I know it's not your point, just providing some answers in case someone is wondering.
# 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: 0
Type inference ensures that this uses efficient types internally, and is compiled to something very close to the efficiency of C. Here [2] is the generated C code, minus line tracing and stack trace frame generation. (Nimrod does things like bounds checking and overflow checking; without them, the program obviously becomes faster; the AddInt() function, for example, is replaced with a simple "+=".)As for Go, it's not very well suited to this domain. Or at least no better suited than Java or C#.
Indeed. Most of the trail blazing work is being done by professional game devs in their spare time, hobbyists, indies and students who are willing to endure the pains of early adoption for the incredible gains that Rust gives them. It will only be post 1.0 however that the bigger players will be able to even consider using Rust. It's too risky to bet an entire company on – and that's coming from somebody who is willing to bet their indie project on it. ;)
- No null pointers (with an Option type that compiles down to a nullable pointer)
- Data race free concurrency
- Zero cost abstractions
- RAII and destructors
- No exceptions
- A modern, highly expressive type system
- Generics that throw type errors at the call site, not deep in a template expansion
- True immutability (not `const`)
- An excellent C FFI
- Compiles to native code
- You don't pay for what you don't use
- Safe by default, but you can circumvent the safety checks if you know what you are doing, and those places are clearly marked and easy to audit. Inline assembly is supported.
- Most safety is enforced statically, so you don't pay for it at run time.
(But maybe I'm missing something. What exactly is the role of the Unreal Editor in UE4? Is it mostly for things like graphics and sound?)
EDIT: OK, so apparently UE4 has something called Blueprints. I'm still not exactly sure what they are, but people in the thread are saying that they're superior to C# in Unity, and that they can even allow you to make a game without knowing how to program. So why is Tim Sweeney saying that C++ is replacing UnrealScript for gameplay code?
You can also mix up the blueprints and C++.
At this point Unity only really has simplicity because of the lack of features, and well if people are too scared about C++.
Blueprints are a weird entity, not really code, but definitely similar.
I think the major difference is they are heavily event based and probably have severe performance restrictions placed on them, which is the major difference. If you want a real time-slice you need to do it in C++.
It also had some clever ideas about replicating state across the network. You want to run the simulation locally to reduce latency, but you also need it to run elsewhere to have a consistent source of truth. So some state would be calculated by the local simulation, but be updated when packets of truth arrive. Member variables could be annotated according to how they were replicated, IIRC.
It's also possible to recompile UnrealScript files without recompiling the whole C++ program which took quite a while. (Unreal4 allows hot reloading C++ so this is no longer an issue.)
Ultimately it was confusing at first. Besides the official docs I had to look at their script source and old UT2 tutorials to figure it out.
I haven't seen the new engine, but I imagine simply doing a net.replicate(&player_info) would have been more straight forward than dealing with all of the unrealscript language constructs for it.
Replace "C++" with "JavaScript/client-side processing" and "script" with "server-side scripting" and I feel like this adequately describes web-development.
Attempts to hide this have thus far all been leaky abstractions, and we're still in the research phase (e.g. Meteor). I'm not convinced that it will be possible to create a coherent web environment which abstracts the server-client boundary effectively.
Note that this doesn't preclude e.g. using Javascript as a server-side language. That's not related.
At least that is how it feels for guys like myself that lack designer skills.
FTFY
On a serious note:
I've recently started using Clojure on the backend and ClojureScript on the frontend and while its not quite 100% of the way there, its close and quite pleasant to work with.
Seems an appropriate term here.
I think the more effective solution for most developers will be to keep all the engine-adjacent code in C++, but integrate a scripting engine of your choice just with your game logic.
Also, I found this comment from later in the thread really interesting about how easy it is for hackers to abuse the reversibility of managed (.NET) code. Granted, this could just be due to poor design on the developers part, but giving hackers that kind of insight into the games design cannot be helping anything.
So with that, This could be a unity issue, mono issue, or just the game developers issue. For background reasons, I am a local memory hacker, tho the reason I am here on UE is im teaching myself how to develop games not for hacking purposes. The game im going to talk about is the only game I know that is MP only and uses the unity engine. This game has one big problem when it comes to hackers, what we do is simply edit the .net dll's to manipulate the game, no hooking, no debugging, no working out functions in assembly, it also meant that we could reverse the source to pretty much 100% usable source - this resulted in the end user being able to change things like the user id to stop them being able to be banned. Un-Ban able hackers? its destroying this game. [1]
[1] - https://forums.unrealengine.com/showthread.php?2574-Why-C-fo...
[Edit] Is Unity's approach drastically different in a way that solves them?
What I would have liked to see was better support for interactive development. When I was playing with it I still had the edit/save/compile/run loop to see my changes, that's not what I want. I use Common Lisp extensively and appreciate the power of a REPL, it's available in many languages now. This brings me to the next point of providing powerful reflection support so that I can easily explore the state of the application, as well as better debugging tools.
UnrealScript was just not a very good language implementation in my opinion.
So in my opinion removing it and exposing the C++ is a good thing. But not for the same reasons that most are touting, I don't want to code in C++. But now it should be a lot easier to build a reasonable Lisp on top of Unreal Engine 4, which is what I really want.
Now, to make the gameplay programmer and level designer's job easier, you still have to build well made and documented building blocks.
It's either that or hire people who do know how to talk a statically typed language. Might be good news for the job market, I always found it weird to have people making games who were not really competent in programming. always baffled me.
I guess you can still force people who are unable to write good c++ to write c++ anyways and hire somebody else to valgrind everything. In the end using a statically typed language is more a requirement for performance, clarity and consistency than a lack of flexibility.
Setting the bar high or demanding discipline if you prefer. Computers are stupid, so you need to be precise when you work with them.
Heck it even allows live preview of how it is executing.
> It is ... more dangerous than UnrealScript, C#, and JavaScript. But that is another way of saying that it's more powerful.
is why we can't have nice things.
But maybe they are just trying to fend off Unity (open source, a more coherent experience). Usually when companies do this, it's too late. I've no idea if that's the case here.
Note how many games have come out using UE3, think about the royalties coming in.
Also, right now they have just about the best game-engine, only hobbyists and some indies would choose Unity, mostly because its easier.
UE4 will definitely get several high profile games soon from big AAA companies.
I would say that Unity is in deep trouble right now :P
I'd say they should start worrying about Unity when something like Unreal Tournament 2004 (a decade old game btw) comes out built with Unity.