pygame-community / pygame-ce

🐍🎮 pygame - Community Edition is a FOSS Python library for multimedia applications (like games). Built on top of the excellent SDL library.
https://pyga.me
930 stars 154 forks source link

pygame for web browser (718) #540

Open GalacticEmperor1 opened 1 year ago

GalacticEmperor1 commented 1 year ago

Issue №718 opened by illume at 2019-01-06 07:47:00

There are various python and pygame on web browser projects.

Comments

*bendavis78 commented at 2019-12-19 22:35:31*

This would be a game changer (no pun intended) for education, as students will want to easily share their games with friends. The web is the ideal distribution platform due to its low barrier of entry. Also as online IDEs such as Repl.it become more popular, they should be able to serve as a fantastic education platform that anyone can use.

I see the most potential in a WASM solution -- skulpt and similar projects have the issue of needing to implement the entire pygame API, and will always be behind ([as you can see](https://github.com/Petlja/pygame4skulpt# implemented-parts), not all of pygame is implemented).

Since both CPython and SDL2 are working on emscripten, there should feasible path to this (not sure about audio, though?)


*dugo3number2 commented at 2021-02-13 22:23:08*

This would be very helpful! I don't use Pygame very much, but when I think of anything related to WASM / programs usually on PC in the web browser, I think of Pygame. All 4 of the other engines/libraries I have used already have it either through emscripten or their own compilation (Raylib, SDL2, libGDX, Unity).


*Olney1 commented at 2021-12-01 21:57:33*

This would be extremely beneficial for Play to Earn cryptocurrency game development. Many Play to Earn cryptocurrency games are taking off right now and will dominate 2022.


*robertpfeiffer commented at 2021-12-02 10:06:05*

https://github.com/ethanhs/python-wasm is especially promising, as it is just a bunch of shell scripts that compile regular CPython without any patches!


*Zireael07 commented at 2021-12-02 10:23:12*

@robertpfeiffer: In my experience, combining any of those "compile X to WASM+Emscripten" projects are basically unusable for combining with any project (they're just REPLs and can't really be expanded upon to provide graphics etc. - I tried to add some graphics on top of such a Lua project)


*robertpfeiffer commented at 2021-12-02 11:56:49*

In my experience, combining any of those "compile X to WASM+Emscripten" projects are basically unusable for combining with any project (they're just REPLs and can't really be expanded upon to provide graphics etc. - I tried to add some graphics on top of such a Lua project)

AFAIK getting CPython to compile with emscripten was the hard part all along. SDL2 already supports emscripten, so we have graphics, we just need to put it together.


*pmp-p commented at 2022-01-21 20:49:23*

they're just REPLs and can't really be expanded upon to provide graphics etc.

no there are projects already very advanced. like that one - still experimental regarding Panda3D quality standards - like https://rdb.name/panda3d-webgl/editor.html ( btw Panda3D is built automatically a as part of pydk mentionned in first post )

SDL2 already supports emscripten, so we have graphics, we just need to put it together.

indeed, but it won't support threading/socket/remote IO unless all your python code is fully async and handle all those if you stay on browser thread.

wasm WILL get better with cpython 3.11. as it builds fine and can run in a web worker But there are still things to tinker to get all SDL2 running from inside the worker ( related https://github.com/ethanhs/python-wasm/issues/32 )

i managed to init SDL2 along with pymain 3.11 yesterday in a worker so i'll try to build pygame soon. sadly pygame does not access SDL2 via ffi/ctypes, that complicates things a lot and makes everything huge.


*sleepntsheep commented at 2022-02-05 09:53:20*

this would be very useful!


*pmp-p commented at 2022-03-04 15:21:29*

when regenerating C sources using cython 3.0.0dev, it can be built against python3.11a5 with minor modifications, main one is force-removing v4l2 because it thinks it's Linux

next step is to gather all objects files and build a static module to link against libpython ( that's how Panda3d does ) with a custom main to call the module init.


*pmp-p commented at 2022-03-06 17:39:24*

it's alive, for now set_mode, 2D draw primitives, font rendering/mouse seem to work

sprites/sound/keyboard not yet tested or working

https://github.com/pmp-p/pygame-wasm/tree/pygame-wasm

for those insterested by this very WIP, testing happens on pygame._sdl2 of Pygame Community discord https://discord.gg/ZjxmYHzXV6

requires Linux env + emscripten sdk portable + https://github.com/pmp-p/pydk (wasm arch ) + https://github.com/ethanhs/python-wasm


*pmp-p commented at 2022-03-07 21:43:05*

i'll try to put WIP demo each time a step is reached here https://pmp-p.github.io/pygame-wasm

step 0 for now :

*pmp-p commented at 2022-03-15 20:29:35*

since most of wasm port is working, i'll begin to upstream changes so more people can test it and find corner cases. first PR is fixing the obvious https://github.com/pygame/pygame/pull/3080


*pmp-p commented at 2022-03-31 12:34:44*

next steps are : 1) fix the major name conflict from https://github.com/pygame/pygame/blob/a1725cf7375f50a1719c09c758096617b2f4dc07/src_c/include/_pygame.h# L295 and https://github.com/pygame/pygame/blob/a1725cf7375f50a1719c09c758096617b2f4dc07/src_c/surface.c# L107 i suggest pgSurface_New2 instead because of pgSurface_New already mentionned in C-API docs.

  fix some smaller ones like PyInit_math / PyInit_time that collides with CPython builtins modules

  remove conditionnally very few duplicates static found in globals.

2) add one C file that merge all modules and the matching config_emsdk.py + Setup.Emscripten.SDL2.in to compile it. that file will also force turn off of PYGAME_C_API to avoid function pointers (ab)use


*pmp-p commented at 2022-04-01 00:22:50*

The base port is ready when cumulating PR listed above, so next step is intensive testing of Pygame functions.

socket support + basic I/O are outside Pygame code scope


*pmp-p commented at 2022-04-04 18:24:01*

newer demos added here https://pmp-p.github.io/pygame-wasm thanks a lot to @DaFluffyPotato for providing me such good material. Also it was very easy to adapt less than 10LOC mod.

basically juste have

a_global = 1

# setup something

while True:
    # no global declaration
    if finished:
        break
    # end of loop

that will turn into

a_global = 1

def setup():
    global setup
    #  ^ which is automatically expanded into a global list via the loader at runtime
    # setup something

def loop():
    global loop 
    #  ^ which is automatically expanded into a global list via the loader at runtime
    #   in place of break
    if finished:
        return False
    # end of loop
    return True

the setup/loop scheme i came from is taken from Arduino platform .


*pmp-p commented at 2022-04-09 02:32:00*

and now thanks to (very) basic asyncio support : the exact same code can run on all platforms

import asyncio #  this one can be a shim generated by the wasm loader

async def main():
    while True:
        # game looping
        pygame.display.update()
        await asyncio.sleep(0)

if __name__ == "__main__":
    asyncio.run(main())  # this one is Not Blocking when coming from the wasm shim

    #  do not do anything from here that would not behave the same on all platforms

*pmp-p commented at 2022-04-11 20:04:52*

notes:

using lzma compression the webloader ( ie python+pygame + minimal stdlib for startup including asyncio and debug/trace tools ) should be around an initial download of 7 to 8MiB

emsdk does not provide lzma

emsdk requires python 3.8+ at least

SDL2 rwops cannot read from anything else but a real file unless https://github.com/pygame/pygame/blob/d965bf6896db2bd3c117065220bbfbb3b24f4b48/src_c/rwobject.c# L60 https://github.com/pygame/pygame/blob/d965bf6896db2bd3c117065220bbfbb3b24f4b48/src_c/rwobject.c# L475 are fixed to use function pointer with void return values


*pmp-p commented at 2022-04-15 22:54:56*

physic engine ( pymunk 0.4 ctypes based as cffi is still too rough and 0.5 / 0.6 are cffi based ): unreliable depends on clang 15 stabilization

https://pmp-p.github.io/pygame-wasm/pygame.html?org.chipmunk6.pymunk04

pygame sprite module in action thx @GuilhermeJuventino : https://pmp-p.github.io/Generic-Space-Shooter-V3-wasm/python311.html?generic.shooter.space

sidescrolling and sdl2.Window by @CAPTAIN1947 :

https://pmp-p.github.io/pygame-wasm/pygame.html?gh.captain1947.flappybird


*pmp-p commented at 2022-04-18 18:22:59*

now with automated CI publishing for github the gh action workflow :

https://github.com/pmp-p/python-wasm-plus/blob/main/support/__EMSCRIPTEN__.yml

and the result:

https://github.com/CAPTAIN1947/Flappy-Bird/tree/gh-pages

note : won't be public until you add the missing "index.html" that maybe could load the game in an iframe.


*pmp-p commented at 2022-04-28 17:12:36*

added https://pmp-p.github.io/pgzero-wasm/pygame.html?gh.lordmauve.pgzero examples don't run themselves use the shell to launch them with commands: ls cd pgzrun

(should) support pygame zero scripts without modification.

this time a dynamic module is used and loaded : _pyfxr.cpython-311-wasm32-emscripten.so

also feature interpreter recycling, you can now change program without reloading ( that's a step forward to running testsuite )

Pygame for web browser was featured at PyCon US 2022 see the slides https://twitter.com/ChristianHeimes/status/1519409483205685250


*pmp-p commented at 2022-05-19 10:38:09*

code changes have been merged, now static building is possible. But to reach fully automated wasm artefacts there are still some steps:


*pmp-p commented at 2022-05-21 18:30:31*

Meanwhile i made a tool for everyone to test pygame-wasm locally, and even publish : https://pypi.org/project/pygbag/

Thanks to all who helped birth it on # pygame-web discord channel of Pygame Community <3


*pmp-p commented at 2022-06-06 22:03:06*

And finally with less than 10 lines modification : https://pmp-p.itch.io/stuntcat


*pmp-p commented at 2022-06-10 09:59:20*

and a promising CI system ( fast ! ) to review : https://github.com/pygame/pygame/pull/3203


*pmp-p commented at 2022-06-19 22:54:57*

CI is now running fine

now with 3.10.5 backport, it was possible to import numpy (built from pyodide and got from their CDN)

A game using that https://pmp-p.github.io/pygame-wasm-plus/python310.html?beatgame thx @bydariogamer & @Sogolumbo


*Python-Ninja-Hebi commented at 2022-07-10 18:19:53*

Is it useable with pyscript?


*pmp-p commented at 2022-07-10 20:27:17*

@Python-Ninja-Hebi probably when pyscript is rebuilt against pyodide 3.11 i will probably add dynamic loading, please follow https://github.com/pyodide/pyodide/issues/289

Be aware that https://pygame-web.github.io is more performance oriented and could execute pyscript tags quite easily https://github.com/pygame-web/pygbag/issues/24 while still using cpython upstream.


*pmp-p commented at 2022-07-26 03:35:10*

not really related to the port, but interesting enough, mypyc wasm output is quite good and so pygame in the browser could run slightly faster than uncompiled native ( on fibonaci around 80% faster )


*pmp-p commented at 2022-09-07 05:54:36*

While waiting for pyodide modules and its core to bump to 3.11 ( should be in 3 months), since pyscript cannot load pygame and also cannot run on old browsers like on a plethora of mobile devices stuck without updates.

I've made a "pygame-script" based upon pygbag runtime that don't use bigints and can run on mobile starting with android 4.4 and chrome/bromite 81.0.4044.83

demo: https://pygame-web.github.io/showroom/pygame-scripts/org.pygame.touchpong.html

doc: https://pygame-web.github.io/wiki/pygame-script/

Page with QR codes: https://pmp-p.itch.io/

pygame scripts files can also run on desktop with "python3 -x" using the old ms-dos shebang hack incorporated long ago in cpython.


*pmp-p commented at 2022-10-14 05:27:08*

dynamic loading is ready pending the linked above PR.

next step is to change bdist_wheel so it only includes pygame_static library which wrap all .so in only one.

pypa/installer is a suitable tool for installing that kind of wheels directly in browsers.

side note : now black https://github.com/psf/black/releases/tag/22.10.0 supports "-x" like python and can format python scripts that have an html header


*ryansobol commented at 2023-01-12 18:04:31*

Has work on bringing pygame to the web browser stalled?


*oddbookworm commented at 2023-01-12 18:07:49*

Has work on bringing pygame to the web browser stalled?

Not at all, @pmp-p is the mastermind of it https://github.com/pygame-web/pygbag


*pmp-p commented at 2023-01-12 19:53:53*

@ryansobol now it is more a matter of distribution - pypa is not ready for wasm yet - so as linked above your best bet is on pygbag and the small custom repo hosted on github pages. The wheel is here https://github.com/pygame-web/archives/blob/main/repo/pkg/pygame_static-1.0-cp311-cp311-wasm32_mvp_emscripten.whl and a suitable runtime aware of wasm wheels is here https://pygame-web.github.io/showroom/python.html ( same used in pygbag or cpython web tetsuite )


*ryansobol commented at 2023-01-13 19:46:39*

@pmp-p This is great information, thank you! I'm curious, how does this wheel fit in with the Pyodide runtime?

FYI, the Pyodide team is currently working on an upgrade to Python 3.11, which is likely to be released in v0.23. When this work is complete, do you expect this wheel be runnable in Pyodide?


*pmp-p commented at 2023-01-13 20:57:43*

@ryansobol

do you expect this wheel be runnable in Pyodide ?

No i don't for multiple reasons, first because pyodide's goal is scientific stack and reducing download size. but pygame relies on SDL2 ( and all of it ! )

They most likely won't add that excess weight on standard release. But some people have already forked pyodide and added SDL2 support so it should be possible to switch runtimes eg in pyscript and load wheels.

second is that pyodide compatibility with wasm standard is quite poor ( lots of extensions are used ), while the pygame wheel linked above is made for wasm 1.0 ( chrome 81 no threads ). So pyodide or its forks would probably require at least a wheel using "BigInt" extension ( and test simmd/neon accel btw ).

third, game loop would not be optimal in pyodide ( setTimeout instead of requestAnimationFrame on vsync ).

Meanwhile pygbag's goal is game engines and their specific needs, use stock libpython and stick to wasm standards.

pmp-p commented 1 year ago

continuation from https://github.com/pygame/pygame/issues/718

next step would be to switch build system to pypa/build and get a wasm wheel automatically.

@pygame-contributors : 3.11.4 actually issue a warning about setup.py being deprecated and 3.12 is removing setuptools/disutils from stdlib

/opt/python-wasm-sdk/devices/x86_64/usr/lib/python3.11/site-packages/setuptools/_distutils/cmd.py:66: EasyInstallDeprecationWarning: easy_install command is deprecated.
!!

        ********************************************************************************
        Please avoid running ``setup.py`` and ``easy_install``.
        Instead, use pypa/build, pypa/installer or other
        standards-based tools.

        See https://github.com/pypa/setuptools/issues/917 for details.
        ********************************************************************************

!!
  self.initialize_options()
warning: build_py: byte-compiling is disabled, skipping.
pmp-p commented 4 months ago

@Vandivier sorry for late response to https://github.com/pygame/pygame/issues/718#issuecomment-2132386539 but I cannot reply there, and anyway pyodide pygame support is provided by pygame-ce.

pygbag is probably still the best way to run games, because pyodide has no support yet for :

known differences :