We now have this fantastic ability to create behaviours in the event sheet.
We also have the ability to write js code- straight in the event sheet.
But what use is writing js code for your game, when you cannot import any third party js libraries? This is literally the biggest weakness in our api atm imo. Compared to this:
https://www.construct.net/en/make-games/addons/1/javascript
Including third party libraries to extend a GD game is very difficult.
So the request here is simple- make it easy. As easy as typing import MyClass from "myscriptsFolder/MyClass" in the monaco editor. Or as easy as an event sheet action.
WIthout third party libraries, our extension ecosystem is not going to get any of the cool things happening in opensource html5 gamedev world.
That is kind of where construct3's js is still ahead of gd. Most of their extensions are based on some library that the dev simply exposed to construct:
https://www.construct.net/en/make-games/addons/plugins
In gd4 I've copy paste socket.io inside js events , why I can't do same in
GD5 ? If socket.io is global (window.socket) I should have the possibility
to get in all JS events
Le sam. 1 juin 2019 18:15, Todor Imreorov notifications@github.com a
écrit :
We now have this fantastic ability to create behaviours in the event sheet.
We also have the ability to write js code- straight in the event sheet.But what use is writing js code for your game, when you cannot import any
third party js libraries? This is literally the biggest weakness in our api
atm imo. Compared to this:
https://www.construct.net/en/make-games/addons/1/javascriptIncluding third party libraries to extend a GD game is very difficult.
So the request here is simple- make it easy. As easy as typing import
MyClass from "myscriptsFolder/MyClass" in the monaco editor.—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/4ian/GDevelop/issues/1077?email_source=notifications&email_token=AAMX4DUJBRAZ63RSVTYGPN3PYKOCBA5CNFSM4HSA2GOKYY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4GXDICMA,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAMX4DTHHLUWRVGSQJEBVWLPYKOCBANCNFSM4HSA2GOA
.
So while I agree that adding support for "raw" JavaScript file is interesting, there is something that I want to clear:
That is kind of where construct3's js is still ahead of gd. Most of their extensions are based on some library that the dev simply exposed to construct
All of these plugins require JavaScript to be written, aka, they are the same as GDevelop extensions right? And of course it's possible to add any arbitrary JS library/file to a GDevelop extension, that's how Physics or Tween extensions are working 😊
See:
https://github.com/4ian/GDevelop/blob/master/Extensions/TweenBehavior/JsExtension.js#L56
So I think that you're slighlty confusing the fact that GDevelop allow you to use JavaScript (which is not yet the case for C3 - afaik it's being added right now) and the fact that C3 have plugins with third party libraries? Or is there something that I am missing?
Most of their extensions are based on some library that the dev simply exposed to construct
So tell me again if I'm mistaken, but it's perfectly possible to re-develop all the extensions, that are on the page you linked, for GDevelop.
Or did I miss something and it's somehow easier for C3?
I know that this is not the main point of the topic, but I want to get our facts straight 😊It's important because there are so much important things to do on GDevelop that I don't want to develop things "because C3 is ahead of GD" to discover later than in fact GD is on the same point (and even more advanced as allowing JavaScript in your events).
To get back to what you're asking, is the solution of Bouh potentially usable? Best way to have me work on something for GD is to actually show me a proof of concept using for example a library embedded in a JS event that works. At which point I will have a valid, proven use case to allow arbitrary JS files to be included - which will need rework of the exporters and make things like minification more complex.
(Again, I understand that this would be an interesting feature, it's just that I don't want arguments that are biased because it's a dangerous way to prioritise things)
Said in other words: if tons of JS plugins exist in Construct to re-use JS libraries, that they are done by written plugins in JS and knowing that we can do the same in GDevelop, then the question is:
Question for which there are multiple hypothesis:
If it's 1, we can surely make it easier to write extensions - or see why it's harder and how to improve that. If it's 3, we can enhance the doc. If it's 2, GDevelop is growing so hopefully we'll get more people contributing :)
I know that I am a pain, but I really want us to explore all available options before risking to bloat the software. Simplicity is something that is hard to achieve, and supporting things like "import MyClass from "myscriptsFolder/MyClass"" is actually a very complex feature involving JS bundlers, syntax transformers and all kind of things that will make me spend 2 months of my time doing this - while maybe a line in the doc or a way to include files to Extensions made in GD will be enough :)
But for now I'm not sure what is the proper solution, that's why I'm asking all the questions 😉
Turns out there is already a card on the roadmap: https://trello.com/c/jnT2J2Td/230-add-support-for-embedding-arbitrary-js-files-in-the-game
I'm linking the discussion here.
There is a card yes. Sorry I totally forgot this was requested in the past.
It will really help with prototyping extensions if we could include js files directly in the event sheet, yes.
The motivation behind this is to make development of extensions in GD more and more enjoyable and encourage the development of extensions. From my point of view the ability to import js libraries is very important for creating extensions. Almost everything I am interested in making an extension of depends on it
Fair enough, for now I have no better solution than asking you to put the whole file in a JS event but I see the idea. Could be part of extensions that you can create in GD (so basically, that would call addIncludeFile, like in extensions).
If I create 2 js code events, one after the other, can I call functions declared in event A inside event B?
I will give this a try with a simple js library. Pasting it's minified contents in an event and trying to call a method from it in event B
Not out of the box because declarations in JavaScript are scoped to the function where they are running (in other words, what you declare in event A stays in event A).
The solution is to:
runtimeScene. Be super careful and name your variable with a very explicit name like "runtimeScene._extensionXXXMyStuffThatIsShared" to be sure that it won't collide and destroy something (method or variable) that belongs to runtimeScene.window variable, which in JS make the variable global. i.e: window.MyLibrary = function() { /*...*/} means that I can then do MyLibrary() anywhere in the codebase.Historically, JS libraries used the third approach, exposing themselves in a global variable. Things have improved with the introduction of JavaScript bundlers, allowing you to require files and bundle everything inside a single JS file that you import in your index.html (this is what is done for GDevelop IDE). This requires libraries to "export themselves" using something called AMD or CommonJS. See https://medium.com/computed-comparisons/commonjs-vs-amd-vs-requirejs-vs-es6-modules-2e814b114a0b for what seems a good explanation.
In practice, most libraries are still doing a dual approach of both exposing themselves to be used in a CommonJS environement (i.e: "require") AND can also expose themselves as a global on the window object (this is called UMD: universal module definition. If the library says it support UMD, then it can be used as a global in the browser. For example, shifty.js is UMD)
The game engine and GD events/JS code is still using the "good old" approach of having a bunch of files without bundlers or anything - notably because this is simple (for preview it's especially important to be fast) and avoid bundlers adding weird stuff or applying transforms to the JS that would be unwanted. This means that everything is located under gdjs object. Any extension using a third party library must include the file containing the library (using addIncludeFile) and be sure that the library is exposing itself as a global.
So at the end, what does all of this has to do with using libraries in a JS code event? If the library is exposing itself on window, you should be able to:
1) paste it in a JS code event
2) be sure that this JS code event is only executed once when the game launch/scene is started.
3) be sure that the library is available on window (depends on the library, but usually it's explained in the README)
4) if it's not exposed on the library, you can still console.log it in the JS code event (after you pasted the library minified code) and expose it to window:
// Code of the library
console.log(MyLibrary); // Will crash if it's not here
window.MyLibrary = MyLibrary; // MyLibrary is now available anywhere
// You can also expose it on GDJS, but be careful:
gdjs.ExtensionXXXMyLibrary = MyLibrary.
5) Enjoy :)
Let me know if you can get something working this way.
Thank you @4ian :) I will give this a try tonight
It works for something simple I wrote. For bondage.js I get this error:
Uncaught TypeError: Cannot read property '_babelPolyfill' of undefined
at Object.<anonymous> (code0.js:94)
at Object.<anonymous> (code0.js:94)
at t (code0.js:94)
at Object.<anonymous> (code0.js:94)
at t (code0.js:94)
at code0.js:94
at Object.gdjs.New_32sceneCode.userFunc0x8254e8 (code0.js:94)
at Object.gdjs.New_32sceneCode.eventsList0x825424 (code0.js:111)
at Object.gdjs.New_32sceneCode.eventsList0xb22f0 (code0.js:427)
at gdjs.RuntimeScene.gdjs.New_32sceneCode.func [as _eventsFunction] (code0.js:1089)
websocket-debugger-client.js:21 WebSocket connection to 'ws://127.0.0.1:3030/' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
https://raw.githubusercontent.com/jhayley/bondage.js/master/dist/bondage.min.js
This is a very old minified compile of
https://github.com/jhayley/bondage.js
I assume this is related to babel, which is used in ALOT of libraries, to compileto a minified file for including in other projects
Do you have this issue when simply running the preview without using bondage at all or do you have some code calling bondage? Can you paste it here if so?
when calling bondage.
I find that in order to execute nested functions, you have to do this
window.myFunc = function(evt="err"){
console.log(evt)
window.myFunc.sub = function(){
console.log("subfunc")
}
}
when usually the case for libraries you import is:
window.myLibrary = function(evt="err"){
sub = function(){
console.log("subfunc")
}
}
You can try with the js version of
http://depts.washington.edu/madlab/proj/dollar/pdollarplus.html
which is not minified. Try executing a function or logging it to console
Actually I get it with a black screen, simply by declaring bondage as
window.bodagejs=function(){
...minified contents...
}
no need to call it
What if you paste directly the minified content without adding the window.bodagejs=function(){, this seems strange to me? This seems strange to me to do this, you wont get bondage in it, just a function executing a bunch of stuff.
Can you share the project with me? Will be easier to debug.
black screen. I will share a project tonight :)
Minified libraries seem to be all transpiled to nested functions emulating classes with methods. So you have something like this:
myClass = function(){
aMethod=function(){
..stuff happens
}
anotherMethod=function(){
..stuff happens
}
}
My Observation is that GD's monaco code can't handle that at all. As noted previously, you can't execute a nested function, unless it has been declared like this:
myClass = function(){
myClass.aMethod=function(){
..stuff happens
}
}
This kind of makes it impossible to import and use the code - even if you copy and paste it.
Nested functions don't work as they are supposed to in minified js
No it's normal, classes don't exist in JavaScript and are transpiled to functions.
GD code editor has nothing to do with execution of JS itself.
Most libraries are wrapped into a self executing function that is called immediately after being defined. This is to avoid leaking variables into the outside. This is common for UMD/libraries running in browsers
I know, my point was that when I wrote a tiny test in monaco as
myClass = function(){
mySubfunc=function(){
..stuff happens
}
}
I couldn't execute the subfunction. This suggests that declaring a minified library in monaco by pasting it like this
window.bondagejs = function(){ ...pasted minified contents here }
will still have the problem of not being able to access any of the pasted contents
Right, but we must not do this, right? You must paste the minified content and that's all.
Re-read https://github.com/4ian/GDevelop/issues/1077#issuecomment-498176041 => I never said to put the library in a function right? Or am I missing something?
I'll give it a try as soon as I can, that will be easier :)
Still give it a try as I explained:
- in a js event, paste the lib
- do it only at the beginning of the scene
This return a error : Uncaught TypeError: Cannot read property '_babelPolyfill' of undefined
I have a great deal of trouble too, adding libraries.
But I have found this way to do why it works I don't know, and knowing why the other way doesn't work is just as important.
@blurymind
You need start this JS code once at beginning of the scene
Dont keep my link (witly.fr/GD11/bondage.min.js) i will delete it in few days
window.loadscript = function(url){
var script = document.createElement("script"); // create a script DOM node
script.src = url; // set its src to the provided URL
document.head.appendChild(script); // add it to the end of the head section of the page (could change 'head' to 'body' to add it to the end of the body section instead)
};
window.bondage = loadscript('http://witly.fr/GD11/bondage.min.js');
I did a try with Shifty.js and it works. In the case of bondage, can you give me an example game?
@Bouh thank you! :)
window.bondage = loadscript('http://witly.fr/GD11/bondage.min.js');
wouldn't that require internet connection to play the game? I want the script to be distributed with the game and working out of the box- with or without internet
I am attaching a test project- its just a copy of the js example:
bondageJSinGD.zip
@Bouh 's method works, @4ian 's method results in black screen- so I commented it. I would prefer @4ian 's method to work though as it doesnt require internet connection :)
It' strange as monaco displays some of the regular expressions in the minified script as commenting out of code, yet if you load it with @Bouh 's approach it works regardless. Bouh's method does not work when I try loading it with github's host raw file url - so it also requires for the minified scripts to be uploaded to a different host too.
Found the issue in my "solution". GDevelop wraps all the JS code in a function using "use strict":
function(runtimeScene, objects) {
"use strict";
// .. Your code here ..
}
This allow to use JS strict mode, which prevents basically "bad" things like using undeclared variables (that would be implictely global) and other things that make JS stricter, which also means much much safer: https://www.w3schools.com/js/js_strict.asp
The good news is that GD does this for you to protect you against old JavaScript caveats, that gave a bad reputation to this language when it was first created.
The bad news is that bondage.js is not compatible with this an so the error with e. _babelPolyfill (e should be window, but is undefined in strict mode).
With @Bouh solution, you're loading a script from another website, bypassing strict mode, so it kind of works (I say kind of, because it's not "officially" supported and you can get some hairy problems with CORS) (though it's a good start to experiment - but it's only a temporary solution).
Strict mode was added in GDevelop, but turns out that you can disable it in the JSON of the game:

BUT turns out that then the script fails to be evaluated, most probably because it's not loaded as UTF8 and so contains invalid character:

So I'll have to dig more, probably loading all scripts with charset="utf-8" in the index.html... for now, experiment with Bouh method of loading scripts (but don't expect it to work to well in an exported game).
Also, side note: isn't there any alternative/similar libraries to Bondage.js? Not to criticise anything, just that I don't know this field and how many libs are doing this kind of work.
It' strange as monaco displays some of the regular expressions in the minified script as commenting out of code
Don't pay too much attention to syntax highlighting of minified scripts. As they are minified, all whitespace and line breaks are removed, so that everything is more or less on a single line. Editors have a hard time parsing this properly and at some point, when the line is too long, they give up and stop syntax highlighting, so that you have the rest of the code that is in the color they were using before giving up. (this is actually a good thing, as this is protecting the editor (and so GD) to blow up because of a memory issue).
When you set the url with github you can't use because MIME type of file is "text/plain" and with this type chromium inside electron cannot read the script.
@4ian is there anything that can be done to make it's minified script more compatible? The author of bondage made a new web build just a few minutes ago:
https://github.com/jhayley/bondage.js/pull/48
https://github.com/jhayley/bondage.js/blob/ec1b2d0957a91b6c26a8938d242edb33e702537f/dist/bondage.min.js
Bondage is using gulp to generate the files
https://github.com/jhayley/bondage.js/blob/ec1b2d0957a91b6c26a8938d242edb33e702537f/gulpfile.js
is there some option that we can pass or avoid passing to make it more compatible with GD?
It's possible to wrap the script as text and inject this text in
@4ian bondage.js does seem to use strict mode, but we need to find out where its asking for the window to be passed
Right, there are "use strict" in the code. So I guess in this case, it would be more about making sure the whole bondage.min.js file could be run as use strict. (amending my previous message)
I am trying to find the hack. I wonder if it's added by gulp..or it's somewhere in bondage
Also, use strict could be deactivated manually on GDevelop side (though I would really like to avoid this) as I shown by editing the JS event. So replacing unicode characters and disabling use strict might be enough to get started.
For where this "non strict" code was added, might be by webpack, which is the bundler: https://github.com/jhayley/bondage.js/blob/master/gulpfile.js#L8
the entry point is asking for babel-polyfill, I wonder if we remove it that will solve it. The polyfill might be required for old browsers?
It's required for all browsers, but I don't think it's related.
(also note that all of this won't be an issue if you're making a JS Extension, as files are included as script which is equivalent to Bouh solution).
I think that webpack might be adding this to allow the library to be either loaded in node.js or in the browser. Not sure if upgrading webpack or tweaking a configuration could help.
Not that if we want to be pragmatic and avoiding dealing too much with this issue not while we're not certain that this is useful, you can:
useStrict: false for the JS event by editing manually the project JSON file.I wonder if the non-unicode characters come from some of the dependencies
I found some in one of the test files, using this regex
[^\x00-\x7F]
The test file shouldnt be a part of the minified version, so this is a bit strange
Right, this might be UglifyJS that is outputting these: https://github.com/mishoo/UglifyJS2/issues/54
An option to output ascii characters only should be hopefully available
Haha, looks like a hack again. I've never tried it, you might as well use
eval("Code of your library")but this force you to turn the whole library to a string, which is a pain and error prone and hard to update.
I love hack the things !
And it works :')
I've encoded bondage.js in base64 and loaded in html by javascript.
Copy/paste code from pastbin in a event at beginning of the scene just once :)
This is nice, but we need to solve this at bondage.js as well, so future updates will be compatible. I guess for now I can use these workarounds for experimenting, but when writing the actual extension, it will need to take bondage from the minified file, which will be included with the extension - vanilla as it came from bondage's git- in the same folder. I want to be able to update the file in one step, not 10
Right, this might be UglifyJS that is outputting these: mishoo/UglifyJS2#54
An option to output ascii characters only should be hopefully available
It is indeed uglifyjs adding them - thousands. Without it, only one is added, but the code is not minified properly. The one added looks like the one from the tests I think. A ... character. It might be from elsewhere. Maybe solution is to upgrade the plugin in webpack?
https://github.com/webpack-contrib/uglifyjs-webpack-plugin/issues/184
Hello I'm the bondage.js dev. Not using uglify is probably the most straightforward solution here, the minification isn't entirely a big deal vs trying to hack things together. I've had issues with uglify in the past.
Feel free to play around with solutions in bondage.js itself, I'll gladly accept any prs that help solve this
Thanks for dropping by! :)
An alternative to Uglify could be tried, or try to update webpack/uglify yeah.
(@blurymind careful in commenting on a closed issue starting with "lol, webpack is still using "uglify-js": "~2.7.3"", could be mis-interpreted ;) You can try a PR, but it's probable that other things like backward compatibility are being a problem here)
Thanks for dropping by! :)
An alternative to Uglify could be tried, or try to update webpack/uglify yeah.(@blurymind careful in commenting on a closed issue starting with "lol, webpack is still using "uglify-js": "~2.7.3"", could be mis-interpreted ;) You can try a PR, but it's probable that other things like backward compatibility are being a problem here)
You're right. Perhaps there can be a simpler workaround
I don't think that it is a good idea to use external libraries inside custom behaviours. This will probably cause a lot of bugs in the future. When GD, Electron or whatever library the engine uses gets updated there is a high chance that one of the custom behaviours will stop working because an old/incompatible version of some library has been pasted into a JS event and nobody knows about that anymore.
While I do like the simplicity of developing behaviours on the fly inside the IDE, I still think using the "traditional" JS extension way for writing behaviours that require external libraries is a better idea, since these have the libraries as separate files inside the extension folder that can be updated separately. And I guess the JS extensions would also run a little faster since you can better optimize the use of variables and stuff that are used inside them.
Yes these are fair points. I think that it's both important to:
So it's a spectrum, a lightweight library might be ok in a JS event, but it can be a risky choice. I still let people explore this and give help because I think flexibility is important and JS events are a really quick way to try things :)
What about a js extension that is designed to safely load libraries in GD from the project folder. @Bouh kind of demonstrated that is possible with loading them from a web address
Or why not bring this feature back from gd4
Kind of a GD equivalent to require(...)
I started developing it as a pure js extension and there seem to be no problems loading bondage.min.js that way at all :)
Seems like purely a problem with including js in gdevelop's monaco in the event sheet.
I am now thinking of adding some ways to make the pure extension development nicer. Some sort of a way to generate some boilerplate code in a folder would really lower the entry point for new devs
The monaco editor coding is currently kind of broken anyway. You can't resize its area, it freaks out when you try to move it in the event tree, grabbing it is hard.. there are all sorts of gui related problems with it, not worth fixing when you can't even import js files.
@jhayley sorry for alarming you. I will report any progress about this on GD's trello. Bondage.js in GD5 is on its way ;)
When that is in - Yarn can become the next built in editor
Now that it seems we are dropping the idea of including JS libs, only would like to add that in the trello board my request was about the possibility to include a JS library with the project. What I was referring to is a resource manager where I can add whatever I want to be included with the project at compile as in GD4. So in case we could add/remove/update files in the resource manager, all we need to do is put a comment in to the JS event //hey, this is depends on this.js and done, no confusion what is broken if something gets updated and doesn't work and all need to be done to update is to replace the lib in the resource manager with the new lib given that methods and functions have not been changed, if they changed then obviously someone need to update the JS event too. But just like with anything contributed to GD source, if there is nobody to maintain it it will break obviously, so the same risks apply. But the benefit is that we don't need to convince anyone about the usefulness of a feature and get an agreement to include it and share it, we can just do it on the forum, anywhere now that we can also export/import custom behaviors.
Regarding the benefits being able to include libs with project and use them from JS events is simply that we do not need to touch the source of GD and compile GD from source. I'm ok with scripting gameplay, using methods and functions provided by 3rd party libs but the source of GD is alien to me and I also don't really have the motivation and interest to play with the source of GD to dig deep and learn how everything is works, but I could play around with some libs using the JS event. Maybe not optimal, but this is the only way I would consider to do it personally.
My point is, not every GD user will become a JS dev eventually who seek the opportunity to improve and extend the source of GD with new features. JS events could be a nice play ground for those who just don't want to play with the source especially now with the ability to export/import behaviors and when we also be able to expose properties that can be changed in behavior settings, that could be huge with the ability to also include 3rd party libs. And as I mentioned, we don't need anyone to agree we can just share it and people can choose to use it or not.
But there is an other bigger problem, the order of execution and scope. The ability to include JS libs on it own does n''t worth anything if the JS event is not being executed at the right time in the scope, so code generation also need to be more optimal, maybe even add customization by allowing to set order of execution of our JS events and the lib we include as I mentioned on Trello.
Thanks.
Oh no, I don't think we should drop the feature. In fact I strongly believe that having it will encourage people to write js in the event sheet, combine it with events. Its useful for prototyping without having to write tons of boilerplate code.
For extensions that come bundled with gdevelop, it's better to write them as pure js extensions. I agree with @Wend1go and also am thankful, because his extensions served as better examples for me to learn howto set up an extension. Especially the screenshot extension imo is an excellent start to learn.
There are still some things that can be done to encourage people to write native js extensions. The biggest one is imo having to compile gdevelop and run it in dev mode.
All people who only want to make games with GD (not compile it) can't write pure js extensions or use external libraries without ugly workarounds. This sort of gives off the impression that Gd's js capability is very limited, which is strange for a html5 engine
I really like the idea of putting source code through the import of a file, indeed it is possible in GD4. I was able to make a proof-of-concept with socket.io. But well it's clearly not a priority, people who want this feature are not many. And we're getting around that lack for now.
I made a pure JS extension too (Video), it took me a while to understand the role of each file despite the fact that they are not many.
I watched a lot of examples "exampleJsExtension" which is well commented.
Maybe the GsoD could allow us to have a tutorial/guide on creating a pure JS extension, with schematics for explain how work the engine, and the architecture of the extention.
Otherwise a generator would be great!
With the ability to make extensions, behaviors, Javascript code and pure JS extensions, I sometimes wonder where I will put my code in GD.
I'm afraid people are confused like me.
The other thing that is kind of a pain point, how the hell do I read a json file?
Following
http://wiki.compilgames.net/doku.php/gdevelop/tutorials/jsonfile
to load
https://github.com/InfiniteAmmoInc/Yarn/blob/electron/testFiles/yarnExample.json
gives me the result of a zero. Is it easier to do in a js event? We can't import or require there
also note that when I want to hold it as a string variable - the expression editor has issues with the quotes in the json file contents (due to defaulting to " to wrap strings instead of ' - our string input is json unfriendly).
This is how we are supposed to do it?
"{" +
"\"Line1\":\"first line\"," +
"\"Line2\":\"second line\"" +
"}"
We can't have 'Strings that have "quoted strings" ', so no way of pasting a json string into an action/condition input field. You have to deal with that hacky laborious reformatting to get it.
Now imagine I have a dialogue json file with thousands of lines I want to paste anywhere in gdevelop. This sort of re-formating is hardly something the user should be made to do, but GD requires it for some reason - making it stupidly hard to keep json data- even as a string in the expression editor.
I tried the several actions to load a thing from a file, they all return a zero when giving them a relative path "yarn.json"
This stuff is easy and works when written as standard JS, but inside GD it kind of doesn't let you do anything or is harder
If we have a way to include other types of files and use them in the game - pass them to actions? This is a hurdle that prevents me from getting bassoon tracker's mod files to be parsed by GD for example. GD has no idea what a mod file and and that can't be declared as a new resource type via the js extension api if I am not mistaken.
Would be nice if we can bundle any file with the game, add it as a resource and when not recognised treat it as binary data or something. Unknown file type icon. Right now dealing with any non image/video/sound resource is a bit ridiculous
The only way around this json thing I found is to literally put the text inside a text object like this:

or to put it in a variable, this looks kind of strange when you have a huge string

wouldn't it be much more intuitive to be able to simply "Include" it from a json file in the event sheet?
I made some progress today:
The basic conditions/actions are set in place now. Still need to do option selection and some other stuff.

Question: If my library returns an array, how do I get that to the event sheet? Do I need to convert it to an object first?
This will take a while before ready for a pull, but is working now. One tricky thing to solve is ability to store the bondage.js object's state to a savegame and be able to load it
For storing Yarn data and opening yarn to edit it inside GD, I am thinking of either creating a yarn object or a yarn behaviour - something that can store metadata and be used to open Yarn to edit it. Since we can't save it to the project folder - like we can with images and sound effects, we will need to write to to project.json
Nice :)
If my library returns an array, how do I get that to the event sheet? Do I need to convert it to an object first?
You have to explain more the context about this array. What does it represents, what do you want to expose to the user? What is this array doing, what is it even composed of?
At the end, the solution is probably to expose a few actions/conditions that interact with the value inside this array - potentially taking a number or a name to identify which thing to update/read in this array.
either creating a yarn object or a yarn behaviour
Beware of creating a Yarn behavior just because it's easier, I don't know the context but let's avoid to fit everything into behaviors if it's not actually related to an object.
Since we can't save it to the project folder - like we can with images and sound effects, we will need to write to to project.json
I can add a resource type once we have something working.
You have to explain more the context about this array. What does it represents, what do you want to expose to the user? What is this array doing, what is it even composed of?
In the case of the dialogue line being of type "Options", I get a string array with the options I can give to the player to use as an answer to a question. The string array needs to be passed to gdevelop's event sheet, where it can be used to create answer buttons or whatever the dev desires.
The question is what my getOptions expression should be passing to gd?
I can add a resource type once we have something working.
awesome :D in that case I guess for now I don't need to make any behaviour to store the data in and will keep it in a scene variable. Side question - how to we declare a global variable in the extension.js parameter input field?
Once we have a json file resource type, I guess the user will be able to load the dialoguetree data from it - select it from a list of json files. And launching yarn-editor could be handled similar to how jfxr is launched to edit sound effects?
I am currently trying to figure out what the best way to bundle yarn-electron is, so it can be used in another electron app such as gdevelop.
The string array needs to be passed to gdevelop's event sheet, where it can be used to create answer buttons or whatever the dev desires.
My first idea would be to store it in a variable structure maybe?
And launching yarn-editor could be handled similar to how jfxr is launched to edit sound effects?
Could be yes, though it's not related directly to a resource contrary to jfxr/piskel so we need to think "what should be the entry point for the user for such an editor?"
Once we have a json file resource type, I guess the user will be able to load the dialoguetree data from it - select it from a list of json files.
Probably these will be stored as json resource type yeah.
how does one return a variable structure from a js extension to the event sheet? Is that something that needs to be created via gd.js or is it a standard js object? Will need to dig into it tonight :)
You can use gdjs.evtTools.network.jsonToVariableStructure that will store the result into the gdjs.Variable passed as second parameter.
If you already have a JS object, use gdjs.evtTools.network._objectToVariable.
Two things:
gdjs.evtTools.network so should not in theory be used elsewhere but turns out that I need to move them into gdjs (or statics inside gdjs.Variable) at some point.gdjs.evtTools.network._objectToVariable is supposed to be "private" as the underscore implies, but feel free to use it, it's general purpose and I should make it public and documented as it's useful.With this, you should be able to convert most JS objects into variables. Note that this should be a last resort to expose things to the events. Prefer specialized actions/conditions if possible to interact with things in memory.
@4ian so my idea for handling dialogue state - when loading and saving the game is to store it in a global variable.
I couldn't find any example of how to get a parameter input to list global variables though (jsextension.js). I know scene variables are 'scenevar', but it would make more sense if it's stored as a global game variable during runtime.. globalvar?
EDIT : nevermind it was :)
How does one convert the structured variable back to an object?
should I do:
const myObj = JSON.parse(gdjs.evtTools.network.variableStructureToJSON(gdVariable))
Yeah, globalvar.
const myObj = JSON.parse(gdjs.evtTools.network.variableStructureToJSON(gdVariable)) should work - but be aware that conversion from variable to JSON and back to a variable might not always lead to the same result: arrays are transformed into objects with keys = 0, 1, 2....
If you want to read a few information, you can do by using the gdjs.Variable methods directly (myVariable.getChild("abc").getAsString(), etc...).
Depends on what you want to store in the global variable.
Most helpful comment
I love hack the things !
And it works :')
I've encoded bondage.js in base64 and loaded in html by javascript.
Copy/paste code from pastbin in a event at beginning of the scene just once :)
https://pastebin.com/raw/r2zVZcvK