Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Raylib-Python-CFFI on the web #58

Open
Yu-Vitaqua-fer-Chronos opened this issue Feb 7, 2022 · 22 comments
Open

Raylib-Python-CFFI on the web #58

Yu-Vitaqua-fer-Chronos opened this issue Feb 7, 2022 · 22 comments
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@Yu-Vitaqua-fer-Chronos
Copy link

Heya, I looked though all of the issues and found #45 stating that it wasn't supported but projects like Pyodide exist now and allow you to run your Python code in the web via WebAssembly, and it's also possible to use C modules on the web as long as it's compiled for use with Pyodide. I think it'd be a neat addition and worthwhile to look into, thanks for your time!

@electronstudio
Copy link
Owner

There was a lot of discussion of this on the Raylib Discord group, but I haven't had time to check that for a while.

Pyodide for a long time had a blocker with.... i think cffi not working(?). When that was fixed I did make an attempt because it sounds like it should be possible, but just getting Pyodide to compile was a ridiculous process - even their own docker image created for that purpose didn't work.

There's also https://github.com/plasticityai/coldbrew that might be worth trying.

It would be cool if it 'just worked' but it's not something I have a real use for at the moment so I doubt I will have time - someone else would have to do it.

@electronstudio electronstudio added enhancement New feature or request help wanted Extra attention is needed labels Feb 7, 2022
@Yu-Vitaqua-fer-Chronos
Copy link
Author

Fair enough haha

@captain0xff
Copy link

captain0xff commented Mar 6, 2022

There's another project that can be used https://github.com/ethanhs/python-wasm instead of pyodide

@electronstudio
Copy link
Owner

electronstudio commented Jun 27, 2022

I tried again with latest Pyodide docker image.

It is necessary to delete any EM_ASM and EM_JS macros from Raylib, because these can only be used in a 'main' WASM module, i.e. Pyodide itself, and not in any 'side' modules that it loads. Command to compile Raylib is
/src/emsdk/emsdk/upstream/emscripten/emcmake cmake -DPLATFORM="Web" -DCUSTOMIZE_BUILD=ON -DWITH_PIC=on -DBUILD_EXAMPLES="OFF" -DSUPPORT_MODULE_RAUDIO=OFF -DUSE_AUDIO=OFF ..

However, the resultant wheel still will not load. It's not the only wheel that won't load, other wheels that are shipped with Pyoxide such as CFFI also fail to load, so it may not be anything Raylib specific. There's no error given so next steps would be:

  1. Figure out how to make Pyodide print actual errors.
  2. Find example of Pyodide loading modules like CFFI that works.
  3. Try the dynamic loading .so version of Raylib Python CFFI

@sDos280
Copy link
Contributor

sDos280 commented Nov 2, 2022

@electronstudio in the last past few days I have been trying to compile python with Nuitka and an idea just came to my mind.
what if it is possible to compile python to CPP using Nuitka and then compile the CPP code to webassembly...

please let me know if you think this may work

also, let's try to build the dynamic library first because as I can see it, it is much easier to use this dynamic loading with cffi than generate a lib file using cffi, but I may be wrong on that...

@sDos280
Copy link
Contributor

sDos280 commented Nov 4, 2022

Or even using cython compiler to generate the C code and then compile it to the web

https://stackoverflow.com/questions/6985109/how-to-compile-c-code-from-cython-with-gcc

https://stackoverflow.com/questions/32354762/unable-to-compile-cython-generated-c-file

I didn't try those yet, but I will try

@sDos280
Copy link
Contributor

sDos280 commented Dec 12, 2022

@electronstudio great news, while working on my binding it seems that someone was able to port it to webassembly
take a look: sDos280/raylib-python-ctypes#9 , https://pygame-web.github.io/showroom/raylib/

Started to work on some documentation. sDos280/raylib-python-ctypes#10

@pmp-p
Copy link

pmp-p commented Jan 11, 2023

Hi, here's the someone from previous post :)

  1. pyodide cannot load SDL2 or GLFW or GLES/GL bridge because it is not compiled in the main module, critical javascript "os" glue is missing
  2. there's a bug in emscripten that will prevent loading shared libraries

pygbag offers a runtime that fixes all that, https://pypi.org/project/pygbag
we host files at pygame-web github pages and we now have a wheel for @sDos280's work

you can even run gist snippets eg https://pygame-web.github.io/showroom/pypad.html#https://gist.githubusercontent.com/pmp-p/1c41aeedb6a165c6a5cd994c530b233d/raw/91dbfedbd901c9c23ead4195471c45f4ed330664/test_rl_julia.py

pmp-p added a commit to pygame-web/showroom that referenced this issue Feb 20, 2024
@pmp-p
Copy link

pmp-p commented Feb 20, 2024

pygame-web now provides a raylib-5.0.0.1-cp310-abi3-wasm32_bi_emscripten.whl wheel
eg https://pygame-web.github.io/showroom/pythongit.html?cpython3.13#src/test_raylib.py

source https://github.com/pygame-web/showroom/blob/main/src/test_raylib.py

nb: InitWindow() could need a fix for forcing canvas so hardware scaler (css) sync to new size after init
that's why there is a pygbag specific call in the sample

    import platform
    platform.window.window_resize()

@electronstudio
Copy link
Owner

Looks cool.

The raylib package has a dependency on the inflection package, so when I try to use any of the pyray functions I get

ModuleNotFoundError: No module named 'inflection'

How can I add inflection?

@pmp-p
Copy link

pmp-p commented Feb 21, 2024

for scripts adding "inflection" to the PEP 723 block should allow integrated pypa/installer to get the pypi wheel at runtime.

Another way is to unzip the wheel/source folder of desired version next to main.py when using pygbag packager ( pygame-scripts harder to use when dealing with lot of assets )

@electronstudio
Copy link
Owner

I added inflection to the PEP 723 block but it does not seem to make any difference. Here is the whole project so you can see what I'm doing wrong:

https://github.com/electronstudio/raylib-python-cffi-pygbag-examples

@pmp-p
Copy link

pmp-p commented Feb 21, 2024

it seems automatic install from pypi is failing for "inflection" i'll look into making a wheel right now

btw if you are interested in no hassle automatic wheel build you could vendor pygbag into building raylib-python-cffi, i already have the necessary pipeline that build raylib+python with python-wasm-sdk available ( and as i maintain it you don't have to fight with raylib/python/emsdk changes ) .

exemple of pygbag vendoring https://github.com/harfang3d/harfang-wasm or https://github.com/pmp-p/panda3d-wasm ( vendor + packages.d folders )

@pmp-p
Copy link

pmp-p commented Feb 21, 2024

ho i found why, inflection is a py2/py3 module and parser does not account yet for those wheels, i'll fix that asap
shot-2024-02-21_1708491257

yep got it with py -m pygbag --PYBUILD 3.12 --git --ume_block 0 --template noctx.tmpl main.py locally, cdn should update in about half an hour

@pmp-p
Copy link

pmp-p commented Feb 21, 2024

cdn is updated ! it should work locally and in CI https://pmp-p.github.io/raylib-python-cffi-pygbag-examples/

yml typical for raylib is a bit different from pygame because of 2D/3D context switch so here it is https://github.com/pmp-p/raylib-python-cffi-pygbag-examples/tree/master/.github/workflows

@electronstudio
Copy link
Owner

Thanks, that is great. I put up some examples here: https://electronstudio.github.io/raylib-python-cffi-pygbag-examples

I'm not sure the platform.window.window_resize() fix is working, some of them seem to have wrong size

@pmp-p
Copy link

pmp-p commented Feb 21, 2024

I'm not sure the platform.window.window_resize() fix is working, some of them seem to have wrong size

Seems that pyray.init_window() is not setting canvas render buffer size correctly, i'll have a look to raylib internals.
Normally canvas.width and height should match init_window() called values, while canvas.style.width and height handle hardware scaler (screen pixel values )
it is important to fix that to avoid huge drop of perf on mobile.

@electronstudio
Copy link
Owner

@pmp-p I'm not sure what you mean by vendoring. Currently all the binary wheels are built on github actions https://github.com/electronstudio/raylib-python-cffi/blob/master/.github/workflows/build.yml and cirrus CI https://github.com/electronstudio/raylib-python-cffi/blob/master/.cirrus.yml . Is there an easy way to add the wasm binary wheels to one of these?

@sDos280
Copy link
Contributor

sDos280 commented Mar 2, 2024

Looks cool.

The raylib package has a dependency on the inflection package, so when I try to use any of the pyray functions I get

ModuleNotFoundError: No module named 'inflection'

How can I add inflection?

Hi, electron-studio and pmp. it has been a long time. I saw that you had the same problem as I had the first time I tried to use python on the web (with raypyc).

the same as you I used inflection for the underscore function. back then I didn't know how to fix it so I just settled by copying inflection underscore code to my project (with the reference to the inflection library):

def underscore(word: str) -> str:
    """
    Make an underscored, lowercase form from the expression in the string.

    Example::

        >>> underscore("DeviceType")
        'device_type'

    As a rule of thumb you can think of :func:`underscore` as the inverse of
    :func:`camelize`, though there are cases where that does not hold::

        >>> camelize(underscore("IOError"))
        'IoError'

    """
    word = re.sub(r"([A-Z]+)([A-Z][a-z])", r'\1_\2', word)
    word = re.sub(r"([a-z\d])([A-Z])", r'\1_\2', word)
    word = word.replace("-", "_")
    return word.lower()

hope that would help.

@pmp-p
Copy link

pmp-p commented Mar 3, 2024

the idea of vendoring is to inherit current pygbag build, so the ABI matches when building the wheels ( eg in case of emscripten changes or new python version). For pygbag 0.9+ i will start to add a WASI testsuite for CI, the wheels will benefit of that too.

And then later i can setup a script that will grab the released wheels and merge them in the main "pypi" repo

I find that way lib dev would be more in control of their wasm packages.

Pyodide (which anyway is not made for games loops) and others are more difficult to publish since you have to put a recipe in their repo + patches and have no control over main flags.

if you fork pygbag renamed to "pygbag-raylib" or "raylib-wasm" i can PR the build scripts so you can get an idea of the WIP. Also it is good for handling specific raylib issues by activating them on the fork. I already found some with shaders.

@sDos280's idea for inflection seems to load way faster than grabbing the pypi wheel and it is not much code to maintain

@pmp-p
Copy link

pmp-p commented Mar 3, 2024

ho i also forgot the main argument for using pygbag as wheel builder, it is FAST ( less than 5 minutes ) while a full CI for wasm would take more than 30 minutes ( get emsdk, build thirdparties ( emsdk ports + python + raylib ) , build the wheel )

electronstudio added a commit that referenced this issue Mar 3, 2024
@electronstudio
Copy link
Owner

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

5 participants