godotengine / godot

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

Integrate javascript support as scripting language #937

Closed yuri-karadzhov closed 8 years ago

yuri-karadzhov commented 9 years ago

As javascript is well known and really popular language it will be grate for godot to implement it as scripting language. As godot already supports C it can be done with help of this project http://duktape.org/

reduz commented 9 years ago

I'd rather programmers learn GDScript and then have a good experience, than use something they know and then have a bad experience, so probably never going to happen.

On Sun, Dec 7, 2014 at 1:48 PM, Yuri Karadzhov notifications@github.com wrote:

As javascript is well known and really popular language it will be grate for godot to implement it as scripting language. As godot already supports C it can be done with help of this project http://duktape.org/

— Reply to this email directly or view it on GitHub https://github.com/okamstudio/godot/issues/937.

reduz commented 9 years ago

even if it means they'd rather not use Godot

On Sun, Dec 7, 2014 at 3:41 PM, Juan Linietsky reduzio@gmail.com wrote:

I'd rather programmers learn GDScript and then have a good experience, than use something they know and then have a bad experience, so probably never going to happen.

On Sun, Dec 7, 2014 at 1:48 PM, Yuri Karadzhov notifications@github.com wrote:

As javascript is well known and really popular language it will be grate for godot to implement it as scripting language. As godot already supports C it can be done with help of this project http://duktape.org/

— Reply to this email directly or view it on GitHub https://github.com/okamstudio/godot/issues/937.

yuri-karadzhov commented 9 years ago

I believe as an option it's not a problem to provide js syntax and precompile it to gdscript. There is no big difference between these languages. It seems API is the one that matter.

SuperUserNameMan commented 9 years ago

I've discovered Godot rencently, and learning GDscript syntax and its special features was easy and fast. The only thing that I missed was the switch/case statement and the C++ multiline comment, mainly because I'm too lazy to replace them with if/then/else and a # for each line.

I'd be curious to know what features you miss from JS in GDscript ?

godotengine commented 9 years ago

you can use multiline comments python style with """

On Sun, Dec 7, 2014 at 6:03 PM, UsernameIsAReservedWord < notifications@github.com> wrote:

I've discovered Godot rencently, and learning GDscript syntax and its special features was easy and fast. The only thing that I missed was the switch/case statement and the C++ multiline comment, mainly because I'm too lazy to replace them with if/then/else and a # for each line.

I'd be curious to know what features you miss from JS in GDscript ?

— Reply to this email directly or view it on GitHub https://github.com/okamstudio/godot/issues/937#issuecomment-65954920.

OkamStudio

SuperUserNameMan commented 9 years ago

@okamstudio : thanks for the info ! I'll test it more seriously tomorrow, because I tried 3 " at the begining, and 3 others " at the end, and the editor just told me : Parse Error : Unexpected token: Constant:.

yuri-karadzhov commented 9 years ago

@UsernameIsAReservedWord Personally I do not care about the language itself and look at API, but in terms of community it can be good to have support of popular languages.

reduz commented 9 years ago

The problem is that it's impossible to use an existing VM and have it work as well as GDScript, the experience will be worse and that is undersired

On Sun, Dec 7, 2014 at 6:25 PM, Yuri Karadzhov notifications@github.com wrote:

@UsernameIsAReservedWord https://github.com/UsernameIsAReservedWord Personally I do not care about the language itself and look at API, but in terms of community it can be good to have support of popular languages.

— Reply to this email directly or view it on GitHub https://github.com/okamstudio/godot/issues/937#issuecomment-65955849.

yuri-karadzhov commented 9 years ago

Got it, it is hard to support two VM simultaneously. But instead it is possible to use preprocessor that compiles JS to GDScript or C++ directly. Probably it will be possible to use some kind of source map for debugging.

reduz commented 9 years ago

It's not really a problem of supporting two VMs, Godot is well designed for that (and for a long time GDScript and Squirrel both worked). The problem is that godot expects a lot from VMs, and most (lua, python, JS, etc) can't deliver, such as:

-ability to run in multiple threads and share a context (most VMs are stack based so this fails) -ability to use vector types efficiently (most fail at this) -ability to run in interpreted mode if JIT is not supported (most JS VMs do not support this)

This rules out pretty much everything,

I think it's more attractive to have something that works, even if you have to learn a new language, than having something patched up that does not deliver or is inconsistent, even if familiar to existing users.

On Sun, Dec 7, 2014 at 6:46 PM, Yuri Karadzhov notifications@github.com wrote:

Got it, it is hard to support two VM simultaneously. But instead it is possible to use preprocessor that compiles JS to GDScript or C++ directly. Probably it will be possible to use some kind of source map for debugging.

— Reply to this email directly or view it on GitHub https://github.com/okamstudio/godot/issues/937#issuecomment-65956661.

adolson commented 9 years ago

@UsernameIsAReservedWord - in addition to the multiline comment reduz mentioned, you can toggle comment on many lines all at once by just highlighting all the lines, then press Ctrl+/ This will work in the most recent devel and stableRC releases, and newer.

SuperUserNameMan commented 9 years ago

@adolson : thanks for this info ! I tried Alt+/ with RC1, but it did not work. Maybe because I'm using an AZERTY keyboard ?

@okamstudio : I tried the python style multiline comment again. It seems to work only inside functions, though the editor does not highlight all the lines in brown. Outside func, the editor complains about an Unexpected token constant. Duno if it's a normal behavior, or if RC1 is already outdated compared to all the recent fixes and pushes in the github ? Should I open an issue about this ?

adolson commented 9 years ago

@UsernameIsAReservedWord - sorry, I meant Ctrl+/ - try that! (will update earlier comment as well)

SuperUserNameMan commented 9 years ago

@adolson : this works ! thanks !

korinVR commented 9 years ago

JavaScript is popular, but not a good language for 3D. I don't think there is a merit to specifically support it on game engines.

There is an insightful article about that.

"JavaScript and 3d graphics don't mix" http://mortoray.com/2014/01/06/javascript-and-3d-graphics-dont-mix/

yuri-karadzhov commented 9 years ago

This article actually proves nothing. The same problems appears in many other languages. JS 7 will have types ad operators overloading (UnityScript and ActionScript have them already, but GDScript don't). And when it comes to performance - there is no such concept as language performance, instead there is VM performance. So there is nothing wrong with language itself but the author appears to have some troubles with three.js API and modern browsers.

korinVR commented 9 years ago

GDScript has built-in Vector/Matrix types. It solves the problems written in the article elegantly. That the reason you don't need operator overloading in GDScript.

ActionScript does not have operator overloading. As for ECMAScript 7 types, I don't believe it will be available within 5-10 years. And even UnityScript has operator overloaded geometry classes, almost all Unity users use C#.

JavaScript is a great language, but it is not for games. C/C++, C# and some script languages (like Lua or GDScript) are popular in the game industry.

yuri-karadzhov commented 9 years ago

The same way you can make realization of Vector/Matrix types and use them in JS. So the article mostly mentioned problems of tree.js.

It does not matter when ES7 comes to browser, we talk about language not browsers or VMs. Thats not true many Unity users use UnityScript for supplementary tasks. However due to lack of convinient class system they prefer C# for more serious tasks (but still it's not a problem of JS).

Few years ago it was not for servers or desktop app, and now we have cocos2d and can use JS for everything. JS is not worse or better then python, lua or other general purpose script language, so it's only a question is ES standard suits Godot execution model and should we use this standard or may be we can use just syntax for decresing learning curve.

korinVR commented 9 years ago

I don't think you understand the problems well. It is sure there are a number of 2D games written in JavaScript, but a bit complex game physics will bring you into hell easily (therefore I prefer Cocos2D-x rather than the JavaScript binding). And when it comes to 3D, the complexity increases exponentially. It's the problem of the language itself, not Three.js's.

But at least ECMAScript 7 is going to address the issue. Probably time will tell.

yuri-karadzhov commented 9 years ago

I don't think you understand the answer and the ticket itslef.

And when it comes to 3D, the complexity increases exponentially

This is nonsense, it increases linearly.

Talking about the article:

  1. By reference assignment - the same in C# and other high level languages
  2. Lack of type safety - same in every dynamic languages (ES7 will have it)
  3. No (operator) overloading - ES7 will have it
  4. Performance - have sense only if we discuss VM

So, as I wrote before, we can use ES7 syntax right here and right now and precompile it to GDScript with some source map.

reduz commented 9 years ago

let me put it simply:

if you want to contribute this yourself and make sure you maintain it until it's bug-free, and help everyone having problems with it, then fine.

Otherwise I think there are way too many things that are more important to dedicate time to.

On Mon, Dec 29, 2014 at 10:35 AM, Yuri Karadzhov notifications@github.com wrote:

I don't think you understand the answer and the ticket itslef.

And when it comes to 3D, the complexity increases exponentially This is nonsense, it increases linearly.

Talking about an article:

  1. By reference assignment - the same in C# and other high level languages
  2. Lack of type safety - same in every dynamic languages (ES7 will have it)
  3. No (operator) overloading - ES7 will have it
  4. Performance - have sense only if we discuss VM

So, as I wrote before, we can use ES7 syntax right here and right now and precompile it to GDScript with some source map.

— Reply to this email directly or view it on GitHub https://github.com/okamstudio/godot/issues/937#issuecomment-68253869.

yuri-karadzhov commented 9 years ago

@reduz definetly, there are many things that most important than JS in godot. I am able to write precompiller which translate ES7 syntax to GDScript, but I won't have time to support it properly and integrate debugging into godot. So that was idea for others to implement and discussion that there is nothing wrong with JS.

I believe some day it can come to life.

akien-mga commented 8 years ago

Archiving as this likely won't be implemented based on a feature request. Support of additional languages has been discussed many times, but it's not a priority right now.

rosshadden commented 7 years ago

I didn't see it mentioned anywhere here so I wanted to point out that the absolute best reason to use an existing, standardized language is that they tend to have well-established ecosystems. This is more true for JavaScript than any other such language, as npm is currently the biggest package repository in existence. When you add the fact that the language itself is battle-tested, evolving, and that ES2015/2016/2017 are very well-suited for gamedev, I don't think it's smart to just write it off. I would go as far as to say that ideally JS should be the only language supported, but of course I know that would be too abrasive a request and get immediately rejected.

I know you hear complaints and requests for this a lot, and I really do respect that there are things on your plate that you feel are more important than this. So really, I want to know how you would feel if we the community attempted to implement it ourselves. From the perspective of an outsider to godot, having to use what many people would label a "dead-end language" because it's only ever going to be for this specific application, is by far the biggest turn-off. If you are not going to consider such efforts I don't want to waste my time, but if you are not opposed to it two years after this issue was opened (a two years that has seen amazing progress in the EcmaScript standard I might add), I might try to lead the charge and rally people to help me.

reduz commented 7 years ago

It is not technically possible to do this, it was explained several times why. It's in the docs and the FAQ.

On Sat, Dec 31, 2016 at 3:12 PM, Ross Hadden notifications@github.com wrote:

I didn't see it mentioned anywhere here so I wanted to point out that the absolute best reason to use an existing, standardized language is that they tend to have well-established ecosystems. This is more true for JavaScript than any other such language, as npm is currently the biggest package repository in existence. When you add the fact that the language itself is battle-tested, evolving, and that ES2015/2016/2017 are very well-suited for gamedev, I don't think it's smart to just write it off. I would go as far as to say that ideally JS should be the only language supported, but of course I know that would be too abrasive a request and get immediately rejected.

I know you hear complaints and requests for this a lot, and I really do respect that there are things on your plate that you feel are more important than this. So really, I want to know how you would feel if we the community attempted to implement it ourselves. From the perspective of an outsider to godot, having to use what many people would label a "dead-end language" because it's only ever going to be for this specific application, is by far the biggest turn-off. If you are not going to consider such efforts I don't want to waste my time, but if you are not opposed to it two years after this issue was opened (a two years that has seen amazing progress in the EcmaScript standard I might add), I might try to lead the charge and rally people to help me.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/godotengine/godot/issues/937#issuecomment-269876297, or mute the thread https://github.com/notifications/unsubscribe-auth/AF-Z2_bEHG5znPCuXg08JCJ5-2MFwOTcks5rNpr7gaJpZM4DFSv6 .

bojidar-bg commented 7 years ago

@rosshadden Well, you are welcome to implement it as a module -- there is no way we can stop you :wink:

If you do it, we would be happy to advertise it around, and, maybe, some day have semi-official modules build with it.

That being said, I would like to note that to me, JS is a dying language in agony -- IHMO it is a ship to stay away from, just so that if it sinks, it won't take your vessel with it to the bottom. That is obviously my personal opinion, which nobody has to take. Still, too much hype, way too many libraries and plenty of community divisions (plus even more plenty of languages to compile to and fro to it), and adding a mix of new features in ES6/7 while supporting the previous ones is going to make even more libraries, and more hype and more community divisions (IMO). (Again, this is here just as a 2¢ -- I don't really think it would be constructive to discuss at all, just something I would like others to keep in mine)

AbhimanyuAryan commented 6 years ago

javascript as a language is picking really fast

It's growing exponential and Javascript has a huge developer community. If Godot picks Javascript there is huge chance that of other JS developers to contribute to this project including employees from Google/Mozilla

Also, Unity has ML-Agent which is the future of robotics and so many things. We should definitely move GODOT to that area of AI & Simulations

Future is JS not GodotScript or C#

AbhimanyuAryan commented 6 years ago

I'll try to reimplement GODOT in Javascript. I don't know if that's possible or not but now I have set my intention. Nothing will change if you change nothing 💯

AbhimanyuAryan commented 6 years ago

My vision is that Godot should get as modular as any other JS module

npm install -g godot-animation npm install -g godot-cinemachine

Even if you are building WebGL games you should be able to mix React Native code in that to build better game UI for iOS/Android

I don't know how to begin but I think I'll have to write down my entire plan on white sheet of paper and build a solid plan before I begin to code this bad boy :)

vnen commented 6 years ago

I'll try to reimplement GODOT in Javascript.

Well, I'm not sure if this even possible. Assuming you want to run on a browser with WebGL it might be, but it's a very huge endeavor, there's a lot of code to port. Especially if you consider all the dependencies.

Now, if you want just to use JavaScript inside Godot as a scripting language, you don't need to reimplement anything, just create a module with a custom language, or use PluginScript (which is used for the Python scripting support).

etamity commented 5 years ago

I have been doing research about embed V8 engine into game engine. https://www.reddit.com/r/gamedev/comments/52tlqu/integrating_v8_into_your_game_engine/

vnen commented 5 years ago

Well, it's not something I haven't tried on the past: https://github.com/vnen/godot/tree/v8

The main problem was dealing with threads. But my attempt is massively outdated. Now it would be simpler to use PluginScript to embed JS if you want, like it's done for Python.

etamity commented 5 years ago

@vnen thank you for the response, can you give me some direction about PluginScript? I couldn't find any document about it?

jkb0o commented 5 years ago

I tried to do it using PluginScript with several backends - JavaScriptCore, ChakraCore, Duktape and JerryScript. I wrote bindings to atomic types (Vector, Transform, RID, etc.). I used something like this code to test performance:

// Vector2 is bindings to Godot's Vector2
// JSVector2 is pure JS implementation

// test how fast pure js calculations
var k = new JSVector2();
for (var i =0; i< 1000000; i++){
  k = k.multiply(1.00001);
}
print(time_to_calcculate_k)

// test how fast js -> c++ bridge
var v = new Vector2(1, 1)
for (var i = 0; i < 1000000; i++){
  v = v.multiply(1.00001);
} 
print(time_to_calculate_v)

I compare all backends with similar code written on GDScript.

Well, Duktape and JerryScript are 50-100 times slower then GDScript in both cases (pure JS and C++ bridge).

ChakraCore and JavaScriptCore both perform superfast pure js calculations (50-200 times faster then GDScript), I suppose it is because of JIT. But using the bridge to C++ is still very slow (10-30 times slower then GDScript) and I suppose this can't be improved (at least with those backends). I took a look into ReactNative (this framework allows you to write logic in JavaScript and render on mobile devices using native modules), and found it is focused to reduce JS->native messaging to the minimum as it is a bottleneck. As far as I can't reduce JS->native messaging in Godot I decide to drop this idea.

rosshadden commented 5 years ago

Wow great work @jjay! It's a shame that the bridge to C++ is slow. Now that you have mentioned it, someone here might come up with an idea on how that problem could be solved or mitigated. @vnen maybe?

Geequlim commented 5 years ago

@jjay Would you mind share the code how you bind javascript with these backends ?

sankumar-ari commented 5 years ago

@jjay please share the code how you bind javascript with these backends?

jkb0o commented 5 years ago

@Geequlim @sankumar-ari shame on me, it is on a broken laptop only. I will fix it and share code in 2-3 weeks.

Geequlim commented 5 years ago

I'm working on the duktape binding for godot. I think it is possiable to achive the same performence level with gdscript.

arimus commented 5 years ago

@Geequlim @jjay any code you have or information about the challenges you run into around bindings for JavaScript would be much appreciated. Looking for the same and trying to pick apart the other binding projects (e.g. Python, Rust, GoLang) to get there. Cheers.

arimus commented 5 years ago

I've eaten up my weekend, but I was able to get an extremely rudimentary native binding example set up for Godot and Duktape working, with a little assistance from dukglue to make life easy out the gates. Currently, only binding a single class and print method to call Godot::print, since that seemed like a good choice for testing (Godot appears to swallow all of stdout...perhaps a setting I'm missing somewhere?).

Still need to auto-gen all the bindings from the api.json now, for which I'm using the godot-cpp binding_generator.py script as an example. Also need to generate some TypeScript definitions while I'm at it. I don't think that part will be too difficult now that I've gotten the above end-to-end working and have a feel for what I'm doing. I'll report back in the near future when I have something more useful to share and provide some results and code.

Btw, Duktape has mostly been straight forward for integration thus far, however performance is likely to be a bit more meh than desired, given it isn't a JIT-capable engine and has no plans to be. Once I get this prototype working, I may look into V8 or another embed-able engine that's known for performance, but first thing's first. It's been awhile since I flexed my C++ muscles ;)

Geequlim commented 5 years ago

@arimus If you are interested in the work of my binding you can refer this repo https://github.com/Geequlim/ECMAScript It not finished yet. All classes defined in C++ can work correctly in javascript now. It still in development and a lot of work need to do.

arimus commented 5 years ago

@Geequlim thanks. I'll take a look to see if it helps me.

rosshadden commented 5 years ago

I do recommend trying with a much faster engine, like v8 or ChakraCore. They are a lot harder to embed, but I don't think Duktape will ever quite cut it. From my experiences with it I found it not only slower than the others, but also it's not very far along the ECMAScript standards path. They implement everything from scratch and are pretty lacking in terms of the kind of ECMAScript features that are more useful for gamedev.

I tried doing what you guys are talking about before PluginScript was a thing (or at least before I knew about it), and found that ChakraCore is far easier to work with embedding than v8. But I didn't really know what I was doing so hopefully you guys with better field knowledge can figure it out.

arimus commented 5 years ago

Just an update. Was trying my hand integrating SpiderMonkey, given it targets a wide-range of platforms, but there were some challenges along the way. Switched over to V8 integration, for both speed and size (substantially smaller). Unfortunately iOS won't be supported given some iOS limitations for JIT runtimes going this route, but can always wedge in WebKit like the Chrome devs do at some point.

In any case, I have some very minimal test code working and will be trying to wire everything up into a semblance of something usable. V8 integration is much more complex than something like DukTape unfortunately, but I'm giving it a go in my spare time. No promises, but I'll try to share where I leave off no matter what.

Geequlim commented 5 years ago

@rosshadden Here are some reason why I choose Duktape for the initial ECMAScript engine.

  1. Duktape is small. About 100kB after compiled.
  2. Duktape can run on all major platforms which godot runs on.
  3. Duktape is easy to integrate into godot.
  4. The script performence is reasonable. It is the same level with GDScript.
  5. ECMAScript E5/E5.1 compliant. So it is ready for ES6/TypeScript with tools like webpack.

My plan is to find a good way to bind JavaScript into Godot. The first implementation with Duktape will save a lot of time. I will abstract the binding process with minimal engine dependence. After this binding process is verified, we can replace other faster engines in the same way in the future.

arimus commented 5 years ago

@Geequlim It is easier to work with for sure. The performance will definitely be on the slower side of things, but as you point out it would still likely be functional for many use cases. However the testing notes from @jjay above are of general concern.

Either way, I'm trying to use an adapter class, such that any JS engine could be plugged in moving forward. That way it's flexible enough to use DukTape, V8, WebKit, etc. In either case, automatically generating the adapter bindings for Godot integration will be key, as manual bindings would be tedious to maintain over the long-haul.

arimus commented 5 years ago

Still working on the Godot bindings themselves, but I have a rudimentary setup that I'm posting which is using duktape and the built in console logging extra. I've created a github project for it (https://github.com/godot-js/godot-js), so feel free to take a peek if you are interested.

Again, my C++ skills are rusty, so forgive the roughness. The repo has a working example of the latest Godot executing an index.js file which just prints a log line. Took me awhile to clean everything up and make it semi-presentable, but it does provide a starting point. Check the README for details.

I tabled V8 for the moment, but looking to get a good prototype working with DukTape end-to-end first. Then, perhaps another more performance implementation may be in order. For now, up next is automating the bindings generation using the API JSON data to generate DukTape integration classes.

Cheers

rosshadden commented 5 years ago

@arimus Have you looked into ChakraCore? It's one of those things (like TypeScript) that I had initially unfairly/ignorantly written off because it was made by Microsoft, but is really good. Like I said, it was far easier to work with its bindings than V8 in my experience. I think you're a LOT better than me at this stuff, so you would benefit even more than I did in the simplicity. Their examples are extremely helpful and practical.

It's the best JS engine for embedding that I've seen other than Duktape, and while I understand and appreciate what @Geequlim is saying about just using that as a starting point (I do prototypes like that all the time!), I would hope that any successes with Duktape would quickly be sought to be replaced with another engine. Yes you can transpile to their ES 5.1 (which when I used it was actually not compliant and had many bugs with normal JS things like Sets and Maps), but polyfilling things like Promises and and for-of loops are orders of magnitude less performant than using an engine that supports them first-class, and many features are not possible to polyfill. In my opinion ES6/2015/whatever you call it is very intriguing for a gamedev scripting language, but <=ES5 seems like essentially trying to use JS for the sake of trying to use it, not to benefit from the recent niceties in the spec. WeakMaps for example are pretty much critical for gamedev, and proxies are very useful.

rosshadden commented 5 years ago

For reference on just how slow-moving Duktape is for spec support, these issues that I was commenting a lot in and very invested in at the time were opened way back in mid 2015 and 2016 respectively: https://github.com/svaarala/duktape/issues/276 and https://github.com/svaarala/duktape/issues/1015

Edit: I'm not meaning to sound negative. Progress is progress! Duktape is great for what it is, and I've used it before in a game engine of my own, and dealt with it while using Atomic Game Engine as well. Maybe embedding a bigger engine would have size problems on mobile. I am admittedly thinking about this more from a desktop platform mindset, on which I would much rather have speed and features than a small footprint. So the idea of supporting multiple engines might be good too. I don't know.