godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
90.74k stars 21.12k forks source link

C# as scripting language #5081

Closed ghost closed 7 years ago

ghost commented 8 years ago

I could not find any other issue mentioning this, so I suppose most discussion about it happened over IRC.

In #5049 we discussed some things about scripting, and some said the Godot team is considering C#.

C# is a great language with many features, but I personally think that considering Java 8 is a much better language than Java 6, has a better runtime across many platforms and a better JIT and GC than the CLR (unless things changed in the last year), Java could possibly be a better candidate.

Unity might use C#, however Godot never set out to be a Unity ripoff. Java is much more popular than C#, according to this site and job postings, and there are many game developers (especially on Android) who use Java.

Additionally, many of the features that C# offers compared to Java are not much important if the purpose is scripting, as most scripting in games is imperative and (at worst) object-oriented (and many of the advantages C# offers are related to functional programming, which Java 8 supports decently anyway). Just take a look at your average Unity script, even a more complex one like this: there's not much there that can't be done in Java straight away!

The JVM also offers a good amount of other languages - Kotlin, for examples, which has many features like nullable types, pattern matching and operator overloading. There's also Ceylon, which is in many ways a better C# (and compiles directly to JavaScript). Supporting those would not require any more work than adding a JAR dependency. Java also has a larger amount of libraries.

And if performance is the main concern and a runtime like the CLR and JVM is too heavy, those can be done away with and C++ could be used directly via LLVM, so that a JIT can be used, avoiding expensive recompilations. This solution is best kept along with GDScript, so that novices (or people who don't need extra performance) can use that instead (and avoid segfaults). The latest standard of C++ has very clean syntax, so I don't think verbosity should be a problem.

C++ is the solution I would like the best, because it would bring the fastest performance (zero overhead, can't be said for any other language), it would not need any extensive changes (as Godot can already be used from C++, and is written in C++ itself), it would have the more consistent support across platforms and it would make it possible to use Godot for very large projects (such as AAA games - there's a reason most studios use Unreal and not Unity). Additionally, keeping GDScript would let those people who don't need extra performance an easier way to write scripts than Java or C# (both very verbose languages) would be.

tl;dr: I think C++ (or worse, Java 8) makes a better choice than C# for scripting in Godot.

Any opinions?

Edit: I see the "feature proposal" tag (which is correct) but I want to make it clear that I'm not proposing C# support in Godot, I'm merely reporting and commenting on some of the things I've heard around.

hubbyist commented 8 years ago

Adding more features to GDscript would be better way to approach scripting in my opinion

For me, main reason to choose Godot over other game engines is simplified scripting scheme. Godot is not offering to learn a new programing language. It is offering to learn Godot and its scripting language as a combined tool for game development. This is a less intimidating approach than offering new comers to learn C++ or any other programing language for scripting.

Warlaan commented 8 years ago

Thanks for opening this issue, I think this is a topic where there's a big difference between the rationally best choice and what the majority will ask for.

The most important reason why more than one engine exists is because besides one-dimensional factors like performance in general purpose tasks or accessibility of the interfaces there are multi-dimensional factors like performance for specific situations (there is no obvious winner if you compare an engine optimized for 3d games and one optimized for 2d games) or usability for specific groups of users (an interface that is beginner friendly usually has to hide advanced functions). So in order to find a place among other engines an engine has to pick a "philosophy".

Now a scripting language is an integral part of an engine, so the philosophy of the language should fit the philosophy of the engine, or at least it shouldn't contradict it.

So what is Godot's philosophy? Let's look at some facts:

Godot on the other hand promotes object oriented thinking as for example every single object in your game can be built as a scene of its own. Those scenes can be started by themselves, allowing you to test them, alter them by themselves etc. That in turn requires you to build those scenes in a way that does not require accessing the environment. For example if an enemy wants to interact with the player it's much more feasible to use signals to tell the underlying scene that an interaction is requested or to simply require the scene to give the enemy a reference to the player. You still can search the game scene for the player, but if you do that the enemy scene will not be able to run on its own, so that design simply doesn't fit the tools as well.

So how does this make a difference regarding the choice of scripting languages? C# is to languages what Unity is to engines. C#'s philosophy has always been that if some feature would be nice to have it's added into the language. Just look at the list of features that were added with each version: https://en.wikipedia.org/wiki/C_Sharp_(programming_language)#Features_added_in_versions Now you may argue that having a feature isn't something bad, right? You don't have to use it, just leave it if you don't like it. Unfortunately that's not true for a language. With the importance of the internet today languages aren't tools anymore, they are cultures. Sooner or later you will have to google for help, you will use modules or objects built by others, you will use new features built by the community into the engine, and sooner or later that will require you to use language features that you never intended to use. Also if you are working in a team you will learn to appreciate using a language that promotes a common coding style and doesn't offer you dozens of ways to write the same code.

Now you may wonder if I mean to say that a language with less features is always better than one with more features. Of course that's not the case. Let's compare how Java solved the problem. C# allows you to write unmanaged code. Just use the appropriate keyword and you can use it right in the same file. It also allows you to write functional code using LINQ, which reads like SQL code and behaves like functional code. In order to completely understand what one file does you may need to know quite a lot about programming paradigms. If you are writing Java you can use functional programming as well, you just have to write it to a separate file, use a different compiler and call it "programming Clojure". If you prefer to combine object-oriented and funcitonal programming you can call it "programming Scala". The important part is that you are still writing code for the JVM that can easily interact with code from other JVM languages. The .NET-languages have the same capability, it's just not used in the C#-philosophy. They could just as well have decided to stick to one or two programming paradigms in C# and create a new language to add new paradigms, but instead they went with "one language to conquer them all" - which is totally fine, it's great to have a language like that. You should just be aware of that philosophy and the choices you have as a programmer.

Long story short: of all the languages we have I think C# is just the worst fit for Godot. It's a natural fit for Unity, but if you have all those options then why choose a language that promotes mixing-and-matching of paradigms in an engine that promotes clean OO-principles and KISS-programming in every other one of its parts?

So if you think that C# would be a nice addition to Godot then I am NOT disagreeing with you - I am merely saying that alternatives exist that are even better, that should be evaluated first and that would be immediately forgotten once C# is implemented.

ghost commented 8 years ago

@hubbyist

Adding more features to GDscript would be better way to approach scripting in my opinion

That can happen for sure, I don't think it's incompatible with the other proposals.

For me, main reason to choose Godot over other game engines is simplified scripting scheme. Godot is not offering to learn a new programing language. It is offering to learn Godot and its scripting language as a combined tool for game development. This is a less intimidating approach than offering new comers to learn C++ or any other programing language for scripting.

But Godot can already be used from C++, so nothing would really change (provided GDScript is kept) except coding in C++ would be made easier for those who want to do so (currently writing modules requires compiling all of Godot, and it is not integrated into the workflow).

@Warlaan nice analysis. If you read my post, I too disagreed with C# being a good pick for Godot, that's why I proposed expanding the already existing C++ capabilities to make it possible to use it as a scripting language, with GDScript remaining the default language for most users.

Users should be able to write pretty much in GDScript, however it's unreasonable to think that a large game would be written in GDScript. In my opinion, there's nothing that prevents Godot from being suitable for large games except GDScript performance, because the engine is very well designed and has already pretty good performance (and Vulkan will probably make it even better).

In my opinion, performance does not appeal to most Godot users, but it could bring more professionals to Godot, which means more contributions which means a better Godot for everybody.

Warlaan commented 8 years ago

@paper-pauper I understood that we are on the same side. When I wrote "if you think that C# would be a nice addition" I was adressing "you, the anonymous reader", not you personally. ;-) And yes, any new scripting language will drain attention from GDScript. I doubt that the community will take care of more than one language, sooner or later some features will be unavailable or broken from either of them maybe even up to the point that one of the languages is dropped.

I also agree that the only real issues here are C++'s compile times and GDScript's performance. The argument that people already knew C# is just plain wrong imho. I have been working professionally with C# for about 4 years now (mainly working with C++ and SQL) and the one thing that I have learned in that time is that I will most likely never be able to say that I really know that language. After all with C# 6 and the propositions for 7 the number of features is still growing. So when we are talking about "knowing C#" all we can actually be referring to is knowing the most basic syntax which even the worst beginner should be able to re-learn in a few days. I recently held a lecture on different game engines to a class of game designers that were exclusively using Unity before and none of them commented badly on the syntax of GDScript while in fact several who had given up on programming are now motivated again.

So yeah, a solution that speeds up GDScript and makes C++ less cumbersome to compile and use would be my favorite as well.

ghost commented 8 years ago

A lot of people who "know" C# don't use many of its features which make it different from Java. Just take a look at the myriad of Unity scripts which don't go much far than subclasses.

For this reason alone, I'm highly skeptical about the practical advantages C# would give. They are nice in many contexts, just not game development. Besides, C++1x already offers many of those things (including type inference, iterators and some basic functional tools) without any overhead.

Also, it's possible that the overhead brought by the CLR (or even the JVM) could make Godot perform worse, although I see some advantages in using the JVM's garbage collector (does anybody know more about Godot's memory management)?

I read on forums about people who don't use Godot because of GDScript. I think that's close-minded, because there is nothing wrong about it except the fact that it has a poor selection of libraries, which I tried to address in another ticket, #3943, by suggesting a solution which has zero overhead and cross-platform support.

Without having to implement a C++ JIT via LLVM, there is a solution which runs on native code and does not require any fiddling with Godot's sources: dynamic linking.

The first would allow native code without having to recompile Godot from scratch: you just compile it as a .so file and then add it to your load path, then use it from GDScript with no overhead (since it's all function calls).

This should be very easy to do (via libdl?) but as far as I understood it's not done because of cross-platform concerns.

Also, there's the idea of compiling GDScript to C++, much like ENIGMA does with its language. This is not easy, but obviously offers best performance.

vnen commented 8 years ago

does anybody know more about Godot's memory management?

From the docs:

If a class inherits from Reference, then instances will be freed when no longer in use. No garbage collector exists, just simple reference counting. By default, all classes that don’t define inheritance extend Reference. If this is not desired, then a class must inherit Object manually and must call instance.free(). To avoid reference cycles that can’t be freed, a weakref function is provided for creating weak references.

Ace-Dragon commented 8 years ago

Just to note...

A major advantage of GDscript is that it's a language that is completely under the control of Reduz and the other developers, how it works for Godot developers is not dependent on an external team and as such it can be developed in a way that's specific to the engine's design and have what users are requesting.

Another thing is that while GDscript isn't a real high performance language right now, there are likely a lot of areas where performance can be greatly improved while preserving its simplicity and dynamic typing nature.

Then there's the fact that GDscript does not require any compiling knowledge whatsoever and that you don't need anything outside of Godot's built-in editor (which makes the workflow nice and tidy, not to mention easy and fast).

RebelliousX commented 8 years ago

Just a question, how does GDscript interpreter work internally? Parse each line at runtime like old Basic language or does it convert the whole script into a bytecode tables then run the bytecode?

ghost commented 8 years ago

@RebelliousX

https://github.com/godotengine/godot/blob/master/modules/gdscript/gd_compiler.cpp https://github.com/godotengine/godot/blob/master/modules/gdscript/gd_parser.cpp

I don't think there are any serious languages that work like BASIC anymore! :)

alabd14313 commented 8 years ago

Hi! Here is the history of GDScript: ////////////////////////// History Initially, Godot was designed to support multiple scripting languages (this ability still exists today). However, only GDScript is in use right now. There is a little history behind this.

In the early days, the engine used the Lua scripting language. Lua is fast, but creating bindings to an object oriented system (by using fallbacks) was complex and slow and took an enormous amount of code. After some experiments with Python, it also proved difficult to embed.

The last third party scripting language that was used for shipped games was Squirrel, but it was also dropped too. At that point, it became evident that Godot would work more optimally by using a built-in scripting language, as the following barriers were met:

Finally, GDScript was written as a custom solution. The language and interpreter for it ended up being smaller than the binding code itself for Lua and Squirrel, and equally as functional. With time, having a built-in language has proven to be a huge advantage ////////////////////////

In my opinion, c++ can be best. There is some solutions like: https://github.com/RuntimeCompiledCPlusPlus/RuntimeCompiledCPlusPlus Even Angel script typically can be like a runtime compiled. In scripting, I love python because I always love solutions that mix game and scientific simulations (python has many scientific libraries). So I complain! in another issue why godot has it's own physics library: https://github.com/godotengine/godot/issues/4217 There is some issues about languages like C#: https://github.com/godotengine/godot/issues/2790

ghost commented 8 years ago

Nice find, @alabd14313 - that would solve pretty much most issues, while leaving GDScript alone.

About RCCPP, it is a very good idea. I think that if Godot supported it in editor mode and then disabled it in builds, there would be maximum performance and iteration times would be pretty fast. I've heard other engines like Unreal Engine do something similar with C++, and I think it would be pretty neat if Godot allowed seamless scripting-like C++ coding.

It seems the authors know their stuff, because in this page they listed most alternatives to their approach (including the one I mentioned, the LLVM JIT).

I think this approach makes the most sense, because Godot is written in C++ (and I don't think that's ever going to change, considering that C++ will be even better in a few years), it already has a working C++ API and C++ has pretty much the maximum desirable performance with zero overhead and there would be no additional runtimes or memory managers. I hope the devs will take a look at it.

Warlaan commented 8 years ago

I am a bit surprised to find that this thread which afaik was started as a reaction to the proposal to add C# as a scripting language doesn't yet contain a single argument FOR C#, even after six people have expressed their opinion. Maybe the decision to add C# isn't as premeditated as I assumed from the rumors I heard.

volzhs commented 8 years ago

@Warlaan what will happen if post this URL to facebook group? :)

alabd14313 commented 8 years ago

Please change title to something like "C++ as scripting language". C++17 have more features: [http://blog.mattnewport.com/why-c17-is-the-new-programming-language-for-games-i-want/](Why C++17 is the new programming language for games I want) I admire godot developers and thanks them for their works. but I resist on Box2D/LiquidFun/Bullet libraries. In this way developers can focus on pipeline, not on components like physics. With C++ they can focus on performance, not maintaining and updating gdscript. Theoretically RCCPP can implement some new features like tool mode in a better way. May be...

alabd14313 commented 8 years ago

@reduz mentioned some months ago that he want to implement visual scripting, something like unreal blueprints. With RCCPP the workflow between C++ (for programmers) and Visualscripting (for level designers and artists) can be implemented like: Introduction to C++ Programming in UE4 C++ and Blueprints So in a group, programmers can develop new blueprint classes for artists and artists use these instead of directly coding.

ghost commented 8 years ago

@Warlaan IMHO it's because a lot of the C# talk was fuelled by people who want Godot to be a Unity ripoff, but fortunately many here realize that Godot is its own thing and already ahead of Unity in many regards and it wouldn't be fair to let it become affected by the same issues.

@alabd14313 I would change the title but perhaps it's better to create a separate issue and keep this for the sake of posterity so that it can be linked when someone proposes C# (as is often the case).

I am hesitant on the visual scripting, to be honest, but if it can be implemented as a module then why not? Of course, I think having visual scripting (designers and newbies), GDScript (people who can program or are willing to learn) and C++ (programmers) would make Godot a pretty balanced program suitable for all levels of skill, but making C++ coding less cumbersome and allowing easier interfacing with third-party libraries should have a higher priority, IMHO, because it can bring in a lot of professional users (and consequently, contributors).

Warlaan commented 8 years ago

Imho visual scripting is nowhere near refined enough to make sense. It's great for marketing and talking beginners into programming, but from my experience the learning phase during which beginners prefer flowgraphs is very short. For anything but the most basic sequences of calls the systems I know (Unreal, Cryengine, Fungus, Stingray) are simply not helpful. I mean this screenshot for example is from the official advertising video of the Stingray engine. Now that's what I call spaghetti code. And the official examples in the Cry engine don't look any better, even though you can tell by the amount of comment elements that a lot of effort went into making the graph readable, or rather trying to. If you think that's not so bad let me remind you that if you saw that code in a text based language every connecting line that starts offscreen would be a variable with a (hopefully) meaningful name.

Flow graphs are somewhat helpful when it comes to shaders / materials, since intermediate results can be displayed, but even there the system suffers greatly from the fact that a short equation like float x = (a-b)*(a+b)/(1-(a+b)) easily fills a whole screen when it's done as a graph, since every multiplication, sum or difference is a node with two inputs and an output. That's at least 10 nodes for the formula above, and if you don't want to cause a chaos of connections you'll have to duplicate the a- and b-nodes.

The flow graph systems we have today (at least the ones I know) take away the option to give values meaningful names, because instead of putting a result into an intermediate named variable you simply connect it to the next node. That makes self-documenting code almost impossible and requires you to put a lot more effort into documentation. What those systems add is the option to place nodes wherever you want, which in my experience results in less readable code more often than not rather than one that is easier to read.

And please don't talk about flow graphs as if they weren't coding. They are just as much coding as any other programming language. They aren't typing, that's all.

reduz commented 8 years ago

Visual scripting is for designers and artists to make changes without having to learn how to code. Some artists also are able to make simple interactive games with it. It has it's target where it's definitely usefu, it's just not for programmers.

ghost commented 8 years ago

@Warlaan Well, it depends on how you define "programming". Certainly visual scripting is akin to defining algorithms, so it's not far from programming, but programming is also about other things.

There are some good implementations of visual programming, though. PureData is one and also there's GDevelop, a pretty good FLOSS game making program (a shame it isn't more popular). In short, even although I don't personally like it (for some of the reasons you mentioned), it's also true that we both can program, so to us visual programming is a slow and cumbersome to achieve comparably poor results.

Still, I agree with @reduz that some people see an appeal in it. They are not the people who would be hanging around threads like these, but they make games too. I think they could bring something to Godot.

Ace-Dragon commented 8 years ago

The reason why flowgraphs work well for shader editing is that it's very visual (you have nodes that allow you to load images, select colors, ect... without typing out the filepaths and values manually). You also have absolutely no fear of making sure the syntax is correct and that functions are spelled correctly. There is also no need to figure out such complex tasks such as how to work with a matrix (it's all calculated for you).

Godot's methodology for shader editing winds up being a good approach because it cleanly separates the vertex, fragment, and light components and also gives clear guidance as to what type of data you're working with (whether it's normal information or camera information).


Now with the visual scripting, I do think it could be useful even for moderately complex things if the nodes are at a high-enough level in terms of game mechanics (they do more complex things and have several inputs) and if there are nodes that allow you to run a script or create an expression/equation (which in turn can be used to manipulate values in complex ways). The problems I've seen with other visual node systems of this type is that they try to be as close to literal programming as possible (ie. having a bunch of low-level functions as nodes as opposed to being more like a nodal version of Blender's logic bricks or GameMaker's drag & drop).

Sure, it still won't allow something as fine-grained and as advanced as what you can do with pure scripting, but it would still have a use for things such a simple object types within a game (that do not need very complex logic) or if you need to just quickly bang something out.

Warlaan commented 8 years ago

I agree that some people see an appeal in it, and I also agree that it's not for programmers (it's just our definitions of "programmer" that differ ;-) ), so I suggest we leave the discussion at that since it's somewhat offtopic.

alabd14313 commented 8 years ago

Another useful feature of C++ is it's statically type. "auto" and "decltype" facilities can detect the type of an object. Editor and code completion can be easier. Instead of focusing on internal code editor, we can use another external IDE. For now I think codelite and qtcreator have a better status in code completion. Codeblocks have some troubles with c++11 kewords. Also eclipse-cdt have a good code completion. A plugin for qtcreator is a good idea (like unreal-visual studio and Unity-Monodevelop). External IDE can identified with a system path in godot settings (like /use/bin/qtcreator), no need to be compiled and packed with godot (Unlike Unity package has builtin monodevelop). There are another tools like cppcheck and valgrind that have plugins in qtcreator. If you want to have a preview of what is RCCPP: demo

RebelliousX commented 8 years ago

I would love to see a C++ based scripting language for Godot, but implementing all C++ features would be cumbersome such as template programming. There must be some limitations to this kind of script language (STL) and templates shouldn't be use. Also RTTI could cause performance issues.

I love GDscript, my only complaint about it is the pollution of variables namespace, when dealing with large scripts, variable definitions before ready() can become very messy, and prone to bugs in code due to sharing variables between functions of the same script file.

avril-gh commented 8 years ago

My 3 cents. (uh... it ended up 20, but let it be...)

Like @alabd14313 mentioned earlier "it is at the point where it is" because of evolution over years which leaded godot into form it is today. No matter if nature do this or we humans, correcting things at the time of creation apears to be the best way of developing, and i must admit, thanks to this, i enjoy Godot very much as it is and where evelution brought it.

It have all the needed pieces.

Nodes which can be combined into more complex object, saved as scene, then reused again as a "simple" object in another scene which is awesome and mega flexible feature, really, limited only by user own imagination and creativity borders.

Simple to use and learn GDScript, powerful enought to control all the nodes in the way we coders are just used to do - by typing lines of code. In addition doing it in a fast and easy way (code completion / buildin documentation / useful tooltips here and there) without need of compiling, just type, try out, adjust, and again, polishing it to perfection.

Deploying to multiple platforms with REALLY one click (not mention these deploying to android over wifi/adb, life editing, debugging, ect is just a masterpiece of art, no... Its more, its a magic!)

Additionally all these familiarities with commonly used tools like blender ect. (import stuff and it works out of the box, everything is where and how it should be)

And finally, I admit that sometime even ultra creativity might be not enought when it comes to do something milion times in a loop and fits in 1 frame. Thats where C stuff comes in. If you know C, need it, nothing stops you from creating plugin, own custom node ect, which do exacly what desired.

It have almost everything, and in time, i believe will have it all. (Meant, the things that today are "not implemented yet" and one have to do it 'somehow' or 'bare hands' (read: use external tool for it) eg. adjust 3D rigged something in a easy way (gota use blender)

Godot is amazing and a magic thing, perfectly perfect on its road where it go. Needs adjustements and adding stuff here and there but thats it. - its in constant development.

Visual scripting ? uh. It could force us coders to change way of thinking "a little" in a unusual way, plus i dont believe it can be as flexible and readable as normal code. Imagine you coding and have simple one line like this ( abc / def ) * ghi then the fast way, as usual (?) to save typing, you mark part of something, paste here, cut there, paste again and in 5 seconds and fiew keypresses, end up with "simple" (because you know what it do) one liner like ((((abc/def+((abc/def)_ghi^4))ghi)+(abc/def(100))_ghi)+abc) Its common, perhaps many of us do it this way in a super fast way. Now imagine doing it Visual way... It could take whole screen, a lot of mouse work, and it wouldnt look that readable as should. (ofcourse, such one liners also not looks easy after a year but thats what comments are for)

What if someone have 100 such lines one under another ? Visualy he could get a football pitch to display it. What about analysing it, changing, thats a mess and a big headache. Ofcourse coders can do this because, its not a language used, make someone a coder, but specific way of thinking, creating algorithms, manipulating data as a small parts and as a whole. The language no matter if its C, Python, PHP, Java or Visual scripting is only a tool to write down the thoughts. And here, Imho, normal typing with keyboard is most fastest and readable form to write it down. On the other side If someone cant code, do you expect him to suddenly reveal algorythmic genius and perceptivity to not get lost within own idea and Visual representation of it, considering that when we think game - we talk about something more complex than two balls bashing each other with physics.

So for whom really Visual Scripting would be ? To make coders life harder or to limit godot to level - engine for "simple games" for beginers ?

vnen commented 8 years ago

People, there's a long discussion about Visual Scripting in #1220. Let's please not discuss the same topics again in here.

avril-gh commented 8 years ago

People, there's a long discussion about Visual Scripting in #1220. Let's please not discuss the same topics again in here.

Most of posts here were so long, perhaps made me lost myself while reading. Sorry :relaxed:

ghost commented 8 years ago

@RebelliousX Even with RTTI, C++ would still have much better performance than GDScript. Although it's true that templates could be a problem.

The solution proposed by @reduz in #3936 would already make coding in C++ fairly trivial - you just do it with your editor and compiler of choice and link against Godot's API. If this is implemented, even if scripting in C++ would be nice, it wouldn't be much different than writing code in C++ and then calling it from GDScript, in terms of performance. In short, I think focusing on #3936 (which is a simple solution) would greatly improve:

Then there could be focus on static typing in GDScript and optimizing the interpreter (via a JIT or by compiling GDScript to C++), but this can come later if writing modules is made easier.

Warlaan commented 8 years ago

I just want to mention a couple of points that have snuck into this discussion but weren't addressed yet:

ghost commented 8 years ago

@Warlaan About the first point, I think you could post here, as it's related to the topic.

RebelliousX commented 8 years ago

@Warlaan no offense taken. I know that GDscript is a class of its own and I know that variables are like normal member variables in C++ class, but what it seems that you missed my point entirely. You will understand it when you have a script with more than 1000 lines of code. What I want is references or pointers, instead of creating myriads of member variables, just pass them around between member functions. It is more safe that way.

Zylann commented 8 years ago

I like C#, but I see pros and cons.

Pros:

Cons:

Most of this also applies to Java. Maybe I forgot other things because it's late here.

Warlaan commented 8 years ago

Ok, this is my experience regarding feature-rich scripting languages resp. a complete lack of a scripting language depending on your definition of "scripting language". I'll try to keep it short. ;-)

I have been working as the dean for engineering at the School4Games in Berlin, Germany for several years now. At that school we don't have a faculty for "pure" game design, but our game design course is called "game development" and includes enough programming lessons to teach game designers how to develop their own prototypes and to understand the possibilities and limits of the hardware and common software architectures. So the students that I teach are people who sometimes have a raised interest in programming but none of whom applied to become a programmer. Every semester they have to form teams and develop one game. Since almost all of the potential future employers of our students use Unity it has been a requirement for the first two semesters to work with that engine.

Now let's get to the point regarding the effect of scripting languages: These students split up into two groups. One that either tries to avoid programming or has lost hope (meaning they will attend programming classes but will not ask for help if they run into trouble but silently give up) and one that dives into programming so deep that they skip right ahead to topics that usually you wouldn't be concerned with while writing game prototypes. For example one of my students from the first semester has recently published a tutorial on how to write a Singleton in C# using generics so that you can turn a Unity component class into a singleton by inheriting from the generic class from the tutorial. The interesting point is not so much that he was able to write that article, after all he of course did receive help from his teachers and there are quite a lot of resources on the topic on the internet. The interesting point is that a student who applied for a course that is focused mostly on game design rather than programming would be interested in such a specific programming topic. The code from that tutorial will never change due to changes in game design, it's a pure programming construct. Something similar happened with a different student who used a similar class to transport information from one game scene to another. He was quite surprised when I showed him that he could do the same thing with a public static member, which shows that he was looking for complete, complicated solutions before he completely understood all the basic elements in it.

So if you skipped ahead this sums up the text so far: while it is possible to write simple code in feature-rich languages I have observed several times that people are likely to dismiss simple solutions where complicated alternatives exist.

This is not just due to prejudice. Sure, that's probably one factor. If you see that the code in tutorials, examples or other classes in your project looks complicated you may conclude that yours should look complicated too. But I think the real reason is that in programming it makes sense to try to create code that is error-proof. It is a natural desire to write code that doesn't break as soon as it's used in a different place or as soon as it receives different input. And that requires you to find out what options there are that you may have to prepare for. I think this feeling of having to check for every eventuality is what splits up my students into those that drown in the vast number of features of C# and those who jump right in and lose focus in the language.

Zylann mentioned the phrase "quick and dirty". We often use those two terms as a phrase, but when you think about it those are actually two different factors. Whether or not it's possible to code quickly is quite measurable. Whether or not the resulting code is dirty on the other hand depends on a lot of factors, the most important one being the number of features the used language has. For example creating a top-level node and using it as a singleton in Godot is totally fine since GDScript doesn't offer the features necessary to implement the pattern in the same way you would in languages like C#. Sure, using the autoload feature would be better since that's the first place other developers would look for singletons (and it makes the syntax a little nicer), but if a team decides to implement it that way I doubt that there would be much of an argument. Imagine on the other hand that someone implemented a singleton in Unity just by adding a public static member to a class. It's just as quick, in a way it's even the same thing (both are class instances in the most public place), but since C# does offer the option to make the constructor private, access the singleton via a property with lazy initialization etc. it's expected that you do so, otherwise the code will be perceived as very dirty if not broken.

Now the fact that game design students dive into topics like these may be a vague hint at what my point is, but I think I can illustrate it even better by talking about the situation at my first job at a large F2P MMO developer. The team I joined is one of the most experienced game developers in Germany. Their head of development has been creating his own in-house engines since 1995 and even though they had just been bought by another company they were still one of the most successful developers at the time. By the time I joined the team they were using the third version of the in-house engine, which did not have a scripting language. They had implemented one before but in that version of the engine they reverted back to not having any scripting language since there were issues with the code quality the game designers delivered. In other words since the scripting language was too powerful the decision was made to shift the barrier between programmers and game designers to the point where game designers would only edit levels and change settings in config sheets while the programmers did all the programming - in retrospect I noticed that this is pretty much the same situation my students end up in (and it seems many professional studios working with Unity end up in). Now why would I care? If this is happening time and again then doesn't that prove that it's a successful way to work? My answer is no, because there were issues, both technical and in game design, that could easily be explained by the fact that the communication between programmers and game designers was reduced to writing tasks in the one direction and exposing settings in the other. From the game designers' perspective the features became black boxes that could be enabled and disabled, but on that side of the team there was no one who could discuss or even prototype alternatives. The programmers on the other hand were pushed almost naturally into a backend mentality. The "quick and dirty" KISS mentality was gone, because none of us could foretell how the features we built were going to be used. I remember vividly how once the database broke down because a game designer had implemented an easter egg hunt causing the inventories to grow a lot larger than they used to be. That was the last time I just assumed the requirements of a feature would probably stay about the same.

That's why I think that having a low-feature scripting language as a defined area for game code is extremely important and why I think that not having it has a bad effect on game design.

It is not possible to imagine game development today without using prebuilt libraries of classes, after all that's what makes engines with toolsets like Godot, Unity, Unreal etc. so successful. But the difference between all of these engines is where the line between programming and game design is drawn and how much of a gap is created between the two sides. And based on my observations I think that the choice of scripting language is one of the most important factors that can create such a gap or close it.

By the way the reason why I have become so involved in Godot is that I am working on establishing it as the mandatory engine for the first semester. Just so you know that I am not just talking but also drawing my consequences. ;-)

Warlaan commented 8 years ago

@RebelliousX I have to admit that I still don't quite understand what you are getting at. But since you said that what you would want is references or pointers could you open up a new feature request and post a code example for your problem in there? To be honest it still sounds like your problem is one of code architecture rather than one of missing language features.

Zylann commented 8 years ago

I should have added that KISS mostly benefits for small teams. Godot is so feature-packed that one developer can make a game. But as soon as a project has more developers, "quick-and-dirty" things become less likely, and are left for prototyping or temporary fixes, then rules/guidelines have to be setup. So, it really depend on who is using the engine, and for what.

Godot in general also has more constraints than we think. You cannot make "c-static-style" singletons or global variables for a reason: memory leaks and thread friendlyness. GDScript is not as featured as Python for a reason: focused on game dev tasks and performance. The scene system is also object-oriented for a reason: you can make independant "boxes" that can be tested and re-used :)

This topic is about adding a C# (or Java) module support, but I see no example code. Let's try something on the fly :)

using GodotEngine;

// Inherit a node type
public class Spikeball : RigidBody2D {

    // Exported variables
    [Export] public float damage = 60f;
    [Export] public float rotationSpeed = 2f;

    // Notice the naming convention. Should Godot API follow languages or should languages follow Godot?

    void _Ready() {
        SetProcess(true);
        // Should we use the generic system?
        Connect("BodyEnter", this, "_OnBodyEnter")
        // Or use C# features?
        this.bodyEnterEvent += _OnBodyEnter;
    }

    void _Process(delta) {
        var sprite = (Sprite)GetNode("Sprite");
        sprite.SetRot(sprite.GetRot() + delta*rotationSpeed);
        // Or we can have properties
        sprite.rot = sprite.rot + delta*rotationSpeed;
    }

    public void _OnBodyEnter(PhysicsBody2D body) {
        // We cannot invent C# members on the fly, so we can do this if the other script is in C# too.
        // ScriptInstance GetScript();
        var health = body.GetScriptInstance() as IHaveHealth;
        if(health != null) {
            health.TakeDamage(damage);
        }
        // But what if the other is GDScript?

        // A generic approach would look like this, a bit like SendMessage in Unity3D
        // object Call(string funcname, object arg1, ...); // where object can be seen as Variant
        body.GetScriptInstance().Call("TakeDamage", damage);

        // Same thing if we want to get a script variable
        var category = (string)body.GetScriptInstance().Get("category")
        Console.Print(category);
    }

}

What do you think? This file could then be compiled as a DLL asset (or run on the fly). But speaking about this, would we need to generate a csproj like Unity?

ghost commented 8 years ago

@Warlaan thanks for sharing your experience. Correct me if I got it wrong (it was a long post), but are you saying that offering a language with fewer features is better for the sake of the programmers, so that they can focus on developing their games rather than overcoding?

If so, this is a very subtle observation. I think the Godot devs have to do what's best for their userbase - they know what's best.

And I myself today was wondering if some people here (myself included) aren't just subtly asking for Urho3D, while others are asking for GDevelop. Godot is clearly a middle-of-the-road tool between those two (but perfectly suitable for pros, more like Urho3D), and I think it should stay so, but Unity is always going to cast a shadow on it because many people here come from it.

I don't think it's fair to expect Godot to be a Unity ripoff - Godot has clearly better design and as far as I know, better performance. But some people think GDScript is not suited for "serious" development and will never be because it's a custom runtime, despite the fact that the old version of Mono that Unity uses is also in a way a "custom" runtime. And besides, when you write C# in Unity, you write code that works only in Unity for the most part and follow their design patterns, so you might as well use another language.

I think those people who want C# are wrong, but a good compromise in my opinion would be to offer:

1) Better performance (static typing, maybe a JIT) 2) Better support for third-party libraries (via FFI and easier C++ integration)

for GDScript. The rest can be done in C++, including writing modules which implement other scripting languages (which don't need to be first-party - everyone can write a C# module, if they want).

@Zylann I see no advantage in writing that code instead of the equivalent C++, honestly, and the C++ code will have better performance.

Zylann commented 8 years ago

@paper-pauper the advantage of writing this code is the same as GDScript: you don't need to recompile the engine for every platform you want to export to, and... well, you get the choice of language (and performance is not the only one point, as I mentionned earlier). I agree that currently, GDScript experience is superior, and C++ is the best choice for pure performance. But, there are people that just don't want to do C++, whatever good it is. I'm not personally interested in Godot+C#, just evaluating what happens if you add it to Godot. And it's not that straighforward :p

RebelliousX commented 8 years ago

After reading the great book Game Scripting Mastery (you can't find many books about the subject, except the non gaming book about compilers the Red Dragon). My conclusion is that, GDscript is adequate, it is so easy to keep adding features to a scripting language that makes it lose its power. The most important thing is to implement a non bloated script language and as general as possible to make it suitable for different projects. From the same book, it says that Unreal is using C++ with LLVM.

ghost commented 8 years ago

Another idea which might be more lightweight than implementing a separate runtime: what about adapting a transpiler like TypeScript (which is very similar to C#, without the runtime) to emit GDScript instead of JavaScript? This doesn't have to be included in Godot, in fact it might be a third-party module. It would at least offer static typing (at compile time) and a number of libraries, with the same performance as GDScript (because it'd be GDScript).

vnen commented 8 years ago

I like TypeScript, but I don't see the point of adding such complication. If someone do that, they'll have to maintain it to be compatible of newer versions of TS. Also, TS is a superset of JS, so would this be able to transpile JS to GDScript? And then, we would have some people with bugs in the transpiler thinking it's a bug in the engine.

I still think a better idea is to have a static version GDScript that can resort more easily on JIT and still be closely related with the engine and with the current GDScript itself.

The point of C# is to use a established language that could be used outside of Godot too. TypeScript may fit this, but I'm not convinced that it's easier to make a TS transpiler than to embed a Mono runtime.


For me, as I said on IRC, the best option would be the ability to make dynamically linked modules. So you can work in C++ more easily and also there can be third-party modules with different languages, like one for C# and one for C++ as scripting language. It'd increase the ability of growing Godot's resources without having to bloat the main engine binary.

ghost commented 8 years ago

@vnen

For me, as I said on IRC, the best option would be the ability to make dynamically linked modules. So you can work in C++ more easily and also there can be third-party modules with different languages, like one for C# and one for C++ as scripting language. It'd increase the ability of growing Godot's resources without having to bloat the main engine binary.

Oh, I 100% agree - in fact I expressed a similar view in #3936. I was just throwing it out there since we mentioned C#'s runtime as a drawback :)

Penthee commented 8 years ago

For me, that example C# module by @Zylann is lovely, I'd switch from Unity right now if that was available - it's not about the higher performance of C++ or the 'easiness' of GDScript, it's about being comfortable.

I'm still super new to Godot and I've barely had a chance to make a test game yet so you guys may not find my opinion valid, but for me GDScript is the biggest hurdle, not in how it's supposed to work with Nodes and Scenes - I understand that (and it's pretty neat!).

But for me, it's literally the syntax of GDScript that is really off-putting to say the least, not to mention the code editor is severely lacking - I'd love to use VS as I know all of the shortcuts already. I've got years of writing C# worked into my hands and honestly I feel like a kid trying to write in GDScript.

What would be lost by allowing developers to write comfortably? I don't need the plethora that is Mono or fanciness like Linq, I just want to be comfortable while I'm writing my code. I would settle for a C#-like syntax for GDScript, at least the option to use curly parenthesis, semi-colons and explicit types - I can't stand implicit types personally, they drive me crazy. I think GameMaker allows for variations in syntax to accommodate different demographics.

This is of course, just my 2 cents from several hours with Godot - feel free to disagree (as I'm sure most of you will).

Also, I think I'm missing something - what is it exactly about GDScript that everybody loves so much? I'm not trying to offend, I just don't see it yet. I'm quite familiar with Perl so I know the power of implicit types and whatnot but there's got to be more than that, right?

vnen commented 8 years ago

@Pikl:

Also, I think I'm missing something - what is it exactly about GDScript that everybody loves so much? I'm not trying to offend, I just don't see it yet.

The point about GDScript is not much about syntax (which is Pythonesque) but more about how integrated it is with the engine. It might sound pedantic, but syntax is the least of the concerns when moving to another system. What matters most is the API. Even if we added C# right now, you'd probably feel uncomfortable with the new paradigm, since the way you do it in Unity is not the same way you do in Godot.

Sorry, but if we added languages to attend the comfort zone of every programmer, we'd spend the eternity doing just that. While might make sense to bring Unity users with the least stress (right now we're trying to make a Godot guide for Unity users), I don't think Godot should adapt itself to work like Unity. Otherwise we'd have to do the same for users of Unreal, Urho3D, GameMaker, etc.

This is not to say C# isn't happening (it might be if it's feasible and within the interest of the engine), it's just that these arguments would apply to many other languages and engines too.

Warlaan commented 8 years ago

@Pikl First of all thanks for providing the first argument in favor of C#. Now let me explain why I think your opinion is invalid. ;-P

Let's have a closer look at the start of the code example by Zylann:

    using GodotEngine;

    public class Spikeball : RigidBody2D {

    [Export] public float damage = 60f;
    [Export] public float rotationSpeed = 2f;

As a rule of thumb every keyword and every non-keyword-character has a meaning. If it doesn't it shouldn't be there. It starts with using GodotEngine; which means that this code is referring to functions imported from the "GodotEngine" package. Since every script in Godot refers to those functions and there are no other packages to import from it's pointless to add that line, so let's remove it.

Next we have public class Spikeball : RigidBody2D { Everything in GDScript is public so why mention it? class Spikeball : RigidBody2D { Every GDScript file contains a class with the same name as the script. That's not just a coding convention like in other languages, it is defined like that, so where's the point in repeating the class name? : RigidBody2D { Now since the : is the only meaningful "keyword" in this line let's replace it with something a little more readable. extends RigidBody2D { Any coder with a little bit of experience will use indentation to mark the different areas of the code. That means that the code inside the class can be identified by the surrounding braces AND by the indentation, which is why the developers of Python decided to make the indentation mandatory and get rid of the now redundant braces. In our case indentation isn't even necessary on the class level since every script file is defined to be one class (unless you are using subclasses which are marked by indentation). extends RigidBody2D

Next we have the export lines.

    [Export] public float damage = 60f;
    [Export] public float rotationSpeed = 2f;

The []-characters mark attributes that are defined in classes of the same name, which is a mechanism that doesn't exist in Godot, so it simply uses keywords instead.

    export public float damage = 60f;
    export public float rotationSpeed = 2f;

Again, everything is public:

    export float damage = 60f;
    export float rotationSpeed = 2f;

and you don't need to specify the data type.

    export var damage = 60f;
    export var rotationSpeed = 2f;

Exports are an exception because the inspector needs to know which widget to show you, so the type is really just an extra information for the export keyword.

    export(float) var damage = 60f;
    export(float) var rotationSpeed = 2f;

So the difference between this C# code

    using GodotEngine;

    public class Spikeball : RigidBody2D {

    [Export] public float damage = 60f;
    [Export] public float rotationSpeed = 2f;

and this GDScript code

extends RigidBody2D

export(float) var damage = 60f;
export(float) var rotationSpeed = 2f;

is simply that every character and keyword was removed that did not describe the options you have in Godot. I am assuming that now it's pretty clear what people like about GDScript. You aren't forced to type in stuff that's meaningless or redundant and the syntax reflects the options you have instead of hinting at options or language features that don't exist in Godot.

capnlove commented 8 years ago

Coming from a C++/C#/TorqueScript background I have to say that Godot's paradigm takes a few days to get used to but once its simplicity "clicks", you can move from idea to execution about as fast as you can type.

Penthee commented 8 years ago

@vnen:

it's just that these arguments would apply to many other languages and engines too

Fair enough, I'm not holding my breath nor do I expect to be accommodated - this isn't my territory.

right now we're trying to make a Godot guide for Unity users

Maybe I could help with that? I've been using Unity for several years and know the thing quite well compared to any other engine - I'd be a good lab rat for this guide.

@Warlaan:

I am assuming that now it's pretty clear what people like about GDScript. You aren't forced to type in stuff that's meaningless or redundant and the syntax reflects the options you have instead of hinting at options or language features that don't exist in Godot.

That makes perfect sense - it goes along with Perl's ideology of reducing the amount of keystrokes needed to type a script. But really, the amount of keystrokes I would actually type for that example would be the same - I use VS's auto complete to the max and rarely have to type more than 3 characters for whatever keyword, type or variable name before I press space or open bracket to complete it. And as for the actual extra 'unneeded' characters there, I prefer having them there, that one is just a syntactic sugar preference. Godot has autocomplete but it's slow, it takes so long that I have often typed my entire line of code before it even shows up most of the time.

So what people like about GDScript is that it's stripped down to be as minimal as possible providing the exact functionality that's available for use and nothing more, as well as reducing keystrokes.

I get that, but it does nothing to help me enjoy it any more - I'm just not comfortable typing GDScript, I can read it perfectly fine, though. I'm not struggling to learn it, I just don't like it, it seems. Maybe a few more hours making a Space Invaders clone would help convince me - I want to like GDScript more than I do.

Afterthought: Is it possible to use only C++ in Godot? I honestly think I would prefer to learn C++ and use that over GDScript.

neikeq commented 8 years ago

Maybe I could help with that? I've been using Unity for several years and know the thing quite well compared to any other engine - I'd be a good lab rat for this guide.

@StraToN made a post in the facebook group asking for this kind of help. Contact him (I am not sure if there is someone else working on that too).

Penthee commented 8 years ago

@neikeq Thanks, done!

Zylann commented 8 years ago

@Warlaan I understand your code comparison, but for me it mainly proves that C# has more features, and as such, is more verbose.

You need using because there are namespaces to avoid name collision with lots of classes (which already happens to me in my own game project). You need public because there is a notion of encapsulation to prevent coder errors over time. You have [SomeClass] because we can extend built-in annotations to suit different project needs and improve tooling. As for braces... I don't see an advantage, except for defining scopes.

These features are here for a reason. Among them, I would say scalability. Would you develop a huge cross-platform 3D game with all codebase in GDScript? Well, you can. But a lot of users will prefer C++, C# or Java, because of the pros I listed (and I speak purely about the language, not the framework).

But at the same time, there is no "huge" game project I know of being developped with Godot, so not so much examples :p Also, I see a few bad features in C# (warning: personal opinion ahead):

You can have static variables. This is wrong, so much errors come from global states/singletons. Unlike auto-load, they are not bound to any scene scope. You can mistype a semicolon at the end of a while() of if() statement, making it useless and hard to find. You can overcode. I agree that, when used the wrong way, C# code can become very convoluted while another simpler code would do the same. But it depends on people/experience.

Oh. I didn't mentionned preload(). This just can't make it to C#/Java, unless you rely on compiler tricks :p

Did anyone already started to experiment a Mono module?

DerRidda commented 8 years ago

To add my most humble opinion, as somebody who is a C# developer, to this...

I don't think there is much value in adding C# to Godot, as you would still have to learn Godot's classes to get anything done and the only thing you would really gain from adding C#, is the more familiar (to many) C style syntax and static typing. The syntax thing is debatable, Python has the reputation of being easy to learn for beginners and since GDScript is highly similar to Python, I think the same holds true for it. Somewhat experienced programmers shouldn't have any trouble picking up on that syntax anyway, it's consistent and has considerably less pitfalls than the more free form C style syntax.

Now static typing on the other hand can have some value, aside from helping with performance, it can also help with speed of development in some respect. Auto-completion tools just love being told what type a give function/method expects and returns but type hints alone can achieve that. This could be added to GDScript though, no need for any additional language.

Also implementing C# probably wouldn't be all that easy and considerable amount time and effort would be spent on just getting the engine to the state it currently is in but now with C# on top or instead of GDScript.

As a closing comment, which I know some people will take the wrong way, I have this to say:

It has been my observation that some programmers that might not be as solidly footed as they should be in our craft have the tendency to cling to the stuff they do know with all force available to them. This phenomenon appears to me to be especially widespread in the C# dev communities, though this might just be my bias. If any of the people reading this think they might fit into that description I can only recommend to step outside this familiar box and start learning something new, it's not as daunting of a task as you might think it is and once you do have a firm grasp of that new thing, you will probably also have increased your understanding of what you already knew. It's just worth it.

Penthee commented 8 years ago

I would love static types, but if that happened how would you deal with generics? Would you simply use a dynamic type in that instance or would you want to be able to use constraints? - only allow ints and bools for example.

Namespaces would be extremely welcome, I'm surprised that they don't already exist in GDScript.

The option to use braces instead of colons for methods would be lovely too, I know they're unneeded but I like having them there - it's like reading a book without any full stops, it's jarring.