mode777 / rayjs

Javascript bindings for raylib in a single ~3mb executable
MIT License
83 stars 4 forks source link

native module #3

Open konsumer opened 10 months ago

konsumer commented 10 months ago

I love what you are doing here!

I think it would also be cool to load a normal native quickjs module, so games can run in plain quickjs runtime. I am not sure, but it seems like it might just take a little work with the bindings you have made. I saw this article. If there is interest, I can look into it.

mode777 commented 9 months ago

Hey @konsumer sorry for the delay. I kind of missed the notification. That sounds like a nice idea. Right now I stripped out most of the libc specific stuff from quickjs as it was written with posix in mind. So native modules the way quickjs implements it are not a good choice when you want to support Windows IMO. It could be fixed by introducing a compatibility layer for dlopen. Another option would be to introduce an FFI interface. To be honest right now I'm trying to get the full raylib API covered and more stable but I'm open for Pull-Requests :)

mode777 commented 9 months ago

I had some more thought about this. The problem I have with native moduels is always the distribution part. Native modules have to be compiled for a certain platform which means, you either of have to anticipate which platform someone will be using, cross-compile for all of them or make the consumer compile it themselves (see e.g. node-gyp). This is frustration for both developer and consumer. What would be nice is if we could compile them to an intermeddiate format and then consume it from there. WebAssembly for desktop is currently getting more traction. I would like to investigate this idea a little bit more in the future. E.g. using https://github.com/bytecodealliance/wasm-micro-runtime

konsumer commented 9 months ago

The problem I have with native moduels is always the distribution part. Native modules have to be compiled for a certain platform which means, you either of have to anticipate which platform someone will be using, cross-compile for all of them or make the consumer compile it themselves (see e.g. node-gyp). This is frustration for both developer and consumer.

I work on node-raylib. We deal with this, for the most part, by building pre-mades in CI and downloading them on install, but it's not really an extra problem, over compiling a whole quickjs runtime fork. Like with a runtime or native module, users need to either be able to compile your code or download a pre-made. I agree, though, it's a pain for everyone.

WebAssembly for desktop is currently getting more traction. I would like to investigate this idea a little bit more in the future. E.g. using https://github.com/bytecodealliance/wasm-micro-runtime

I also made raylib-wasm. While it works great on web, WASM/WASI has no standard for graphical output, so no native WASM runtimes would be able to do this stuff. People have cobbled together a non-accelerated 2d framebuffer interface (see wasmer's), but it really isn't even in the same category, and it's not part of a standard, so it will only run in one wasm runtime. In my opinion, it's sort of an unrelated problem to "I want to use raylib with quickjs". That said, I am HUGE fan of WASI and WASM.

I am making a game-engine that uses wasm as the "game language", so users can make games in any language. I expose a bunch of functions to wasm (no standard, just my own API, like draw_image(imageID, x, y). I implemented it in native & pn web. Something like that could be used to give quickjs a "raylib-like api, made with wasm" but quickjs would still need native access to hardware, like it just sort of moves the original problem around.

If you are interested in native wasm-runtimes, in C, I highly recommend wasm3 and web49. I have experimented with both of these in my engine, and they work pretty well. web49 is a bit faster for most things, and I found it simpler to use, but I did manage to make a full 2D game-engine with wasm3.

Maybe an idea would be to make a quickjs native module that does lower-level GL stuff, and then expose it to wasm (maybe even the one I made for raylib on the web.) It would still be a lot of work, but a smaller surface-area than all of raylib, just figure out how to expose the stuff that emscripten generates for the web-host, on native.

Another solution is FFI. Raylib offers ready-made DLLs for lots of platforms, and it's pretty easy to build, if your platform is not supported (they have a bunch though.) Putting the burdon "load this native DLL" on another library like quickjs-ffi would mean that the bindings could just be written in js, and users would still need raylib + quickjs-ffi, but the bindings themselves would be cross-platform and no-compile.