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

port pygame #289

Closed
illume opened this issue Jan 6, 2019 · 47 comments · Fixed by #4602
Closed

port pygame #289

illume opened this issue Jan 6, 2019 · 47 comments · Fixed by #4602

Comments

@illume
Copy link

illume commented Jan 6, 2019

Hello,

I'm from the pygame project, and I'd like to get pygame working with pyodide.
Here's the pygame issue tracking things: pygame/pygame#718

cheers,

@rth
Copy link
Member

rth commented Jan 6, 2019

That would be nice. I suspect one difficulty would be to build libsdl. There is some existing work for that in https://github.com/emscripten-ports/SDL2.

@vasiljevic
Copy link

Is it better to use a port of SLD2 or to implement (a reasonable subset of) Pygame directly on the top of canvas API?

One such implementation of the Pygame API subset is https://github.com/Petlja/pygame4skulpt (we have made it for educational purposes).
Besides the question "Port low level layer or passthrough to similar API in browser environment?" there is an issue what to do with synchronous (blocking) functions (pygame.event module is fully synchronous). Skulpt, for instance, implement blocking functions asynchronously under the hood using suspensions (https://github.com/skulpt/skulpt/blob/master/doc/suspensions.txt).

@illume
Copy link
Author

illume commented Jan 9, 2019

Hi @vasiljevic I'm not sure I've seen that before. Very cool!

@illume
Copy link
Author

illume commented Jan 9, 2019

@rth I think SDL2 emscripten support in the main repo works quite well now too.

@mdboom
Copy link
Collaborator

mdboom commented Jan 10, 2019

Yes, it's my understanding that the SDL port that comes with emscripten is pretty solid, so I'd definitely use that as a starting point. Realistically, I probably don't have the bandwidth to help much, but I think this would be a super-cool project, so definitely reach out if you get stuck.

Cc: @kripken (just FYI)

@kripken
Copy link

kripken commented Jan 10, 2019

Yeah, emscripten's SDL2 port is in very solid shape at this point (well-tested, used in production, in upstream SDL, and actively developed).

@cchudant
Copy link

Hey, I would like to port pygame to pyodide.
How can I do this?
Do you have any documentation on how to port packages?

@PythonLinks
Copy link

At a talk on WASM yesterday, the speaker said that games are one of the 3 biggest application areas for WASM.

@mdboom
Copy link
Collaborator

mdboom commented May 15, 2019 via email

@Python-Ninja-Hebi
Copy link

Is pygame possible with pyodide now?

@ryanking13
Copy link
Member

Is pygame possible with pyodide now?

Not yet. But it looks like there is an upstream effort on supporting WebAssembly build for pygame and they already have some demos, so I'm pretty sure that there is no explicit blocker.

@hoodmane
Copy link
Member

hoodmane commented May 9, 2022

@pmp-p

@pmp-p
Copy link
Contributor

pmp-p commented May 10, 2022

The way i see it dynamic build of pygame module rely on static build working first, so it gets only one module to dlopen instead of ... 38.
Once static build is upstreamed it will very easy for pyodide recipe to turn the static lib into a dynamic module that python can load normally.
So pygame with pyodide is very possible though there could be some points to consider:

  • performance hits due to nature of dynamic linking.
  • input/frame lag when used in worker.
  • no sound support in worker.
  • SDL2 preloading hooks would need to be adapted to pyodide.

All those are non-problem when linking statically to CPython running in main thread.

@pmp-p
Copy link
Contributor

pmp-p commented Jul 8, 2022

@hoodmane pygame wasm static is now fully ok and integrated with CI, but it's built on 3.11. As i could not backport correctly all Christian's patches to 3.10.5 : i have some bad tests results on pyodide's numpy module so it would be loss of time to insist. Is there any 3.11.0b3 based pyodide early build around ? ( with just the numpy module i don't need more to test dynamic loading )

@hoodmane
Copy link
Member

hoodmane commented Jul 8, 2022

My most recent 3.11 build was in April:
https://github.com/hoodmane/pyodide/tree/python-tot
I think @antocuni was talking about trying to get a 3.11b3 build working. When I was working on 3.11 before, numpy didn't build correctly but hopefully it will be easier now that 3.11 is a bit farther along.

@pmp-p
Copy link
Contributor

pmp-p commented Oct 16, 2022

pygame experimental wheels are ready. They load fine on cpython-3.11 statically linked to SDL2

There are already forks of pyodide with SDL2 support around ( see kytao's Pyxel module ).

Apart from lack of SDL2 support, i think pyodide abi loading problems should be solved as soon as pyscript/pyscript#610 and pyscript/pyscript#610 are sorted.

@ryanking13
Copy link
Member

Thanks for the information @pmp-p! I think then we can consider providing both SDL2-linked and SDL2-not-linked versions of Pyodide if there are some requests to use SDL2 in Pyodide.

@Python-Ninja-Hebi
Copy link

@pmp-p, is it now possible to use Pygame with pyscript?

@pmp-p
Copy link
Contributor

pmp-p commented Dec 19, 2022

@Python-Ninja-Hebi as long as pyscript accepts multiple core yes.
Also you don't have to build a core yourself and can actually use one with SDL2 already enabled from https://km19809.github.io/pyxelodide .

My 3.11 wheels are available here https://github.com/pygame-web/archives/tree/main/repo/pkg

@ryanking13
Copy link
Member

ryanking13 commented Jan 25, 2023

#3508 will hopefully make it possible to run SDL-based packages in Pyodide. For pygame, I think pygame/pygame#3371 needs to be merged first in order to make it work in Pyodide.

@pmp-p
Copy link
Contributor

pmp-p commented Jan 25, 2023

yes pygame/pygame#3371 would seriously reduce amount of patching required to get a dynamic lib from an in-tree pyodide build, since it simplifies everything to a single "import pygame_static" which take care of loading everything packed in the same wasm lib. Without that one all modules would need to be in builtins module inittab ( which can only be static )

@pmp-p
Copy link
Contributor

pmp-p commented Feb 8, 2023

it seems @illume was not interested in my PR so i just closed it. I know he's still active on pygame repo
so it just proves he was ghosting me.

Sidenote for some reason i cannot anymore create PR or comment anything on pygame repo so somebody will have to take over

. I find attitude from the person responsible very childish and disrespectfull of people that spent 1 year solving a problem on their free time and in the end kept them hanging for 1 missing review.

i for one think PSF should be alerted for that matter because pygame is an important element of python ecosystem.

@illume
Copy link
Author

illume commented Feb 9, 2023

If you want to open the PR again, let me know. Happy to take a look when I get some time. It wasn’t ghosting, it was just me having a life. Looking at your PR, it seems other people were reviewing it. There was nothing I can see stopping you getting it merged in, but happy to work with you to fix anything blocking it being merged.

However you’d need to additionally apologize or retract your comments. Otherwise, I’m not interested in collaborating with you.

If you want to be friendly with me, happy to collaborate. Let me know?

@ryansobol
Copy link

I'd like to reset this thread, if I may.

First, congratulations to @ryanking13, @rth, and the Pyxel team for adding SDL-based package support to Pyodide, and for adding the pyxel package to Pyodide as a proof-of-concept (#3508). These are huge developments for Pyodide, Pyxel, and the Python game development communities! As an outside observer, it is exciting to see years of hard work paying off.

I work at a company called TechSmart, and we teach kids from grades 3–12 in the US public school system how to code. We've been doing this for about a decade, using a custom Python 2 + Pygame 1 runtime environment that runs in the browser using ASM.js. Suffice to say, we've been watching this space for a while now, and we'd really like to get out of the business of maintaining our own custom runtime.

When it comes to migrating a decade worth of coding curriculum to a modern Python + Pygame runtime, in my mind, Pyodide is the clear leader. It has a robust Javascript <=> Python foreign function interface, out-of-the-box support for the Python scientific stack, and now preliminary support for SDL-based packages.

Long story short, it feels very much like natively supporting Pygame in Pyodide is within reach. Speaking for hundreds of thousands of children, and as a person where the current technical challenges are a bit over my head, what can we do to keep the momentum moving forward?

@pmp-p
Copy link
Contributor

pmp-p commented Apr 3, 2023

@ryansobol pygame-ce is ready to be dynamically loaded in pyodide ( also in cpython-wasm as currently demonstrated here https://pygame-web.github.io with pygbag tool ).

I will personnally ensure proper operation in pyodide and pyscript, i'm just a bit busy actually and i'd like to first fix the obvious problems uncovered by real use cases with pygbag so pyodide does not inherit them.

Some modules ( like audio/video capture module , or music ) also need some discussions amongst python wasm runtimes mainteners to set a common modus operandi for adding missing operating systems functions to the emscripten layer ( like a common way to load javascript extra support when module loads if they cannot be implemented 100% in C via emscripten API ).

@ryanking13
Copy link
Member

Thanks for the ping @ryansobol. Yes, I am working on porting pygame(-ce) to Pyodide.

pygbag and Pyodide use different approaches: pygbag statically links everything for optimized performance, while Pyodide dynamically links packages to support various Python ecosystem, so I need to handle some incompatibilities, but I hope we can make it work in the next release.

@pmp-p
Copy link
Contributor

pmp-p commented Apr 4, 2023

@ryanking13 no they use the same approach : since 0.7 and the switch to pygame-ce pygbag does not link anything statically, it uses fetch + pypa/installer to install wheels at runtime exactly like pyodide would. So loading pygame-ce is just a matter of packaging upstream.

pyodide and python-wasm incompatibilities are in platform handling which is not normalized. As I discussed with @rth at PyCon FR, it's also perfectly possible ( and imho better) to have pyodide embedding a game engine dedicated loop, especially when using threads you would want the game loop to be prioritized, so pyodide I/O calls don't interfere with rendering.

Yes, I am working on porting pygame(-ce) to Pyodide.

Glad to ear that, where is your work in progress ?

@ryanking13
Copy link
Member

@ryanking13 no they use the same approach : since 0.7 and the switch to pygame-ce pygbag does not link anything statically, it uses fetch + pypa/installer to install wheels at runtime exactly like pyodide would. So loading pygame-ce is just a matter of packaging upstream.

Wow, that's good news!

Glad to ear that, where is your work in progress ?

You can see my WIP here: https://github.com/ryanking13/pyodide/blob/94030d71163dbf616b24888a9d99dc3b1b440edd/packages/pygame-ce/meta.yaml

It is not organized yet, but you can see the comments there about what issues I have now. I think I will continue working on that branch after Pyodide release 0.23.1. For now, the issue is that after building pygame wheel, Pyodide doesn't know about the module "pygame_static" until it imports "pygame/static.so" + some dynamic linking symbol visibility issues.

@pmp-p
Copy link
Contributor

pmp-p commented Apr 4, 2023

The idea is to package pygame_static.so directly in the pygame-ce wheel upstream for pyodide/pyscript , this will have no impact on pygbag since it has its own wheels repo.

As the pyodide build wheel would have bigint it would be less compatible than python-wasm, i think then it's time to integrate threading to facilitate code porting. I saw that quite a lot of people new to pygame/python don't get how to asyncify game engine loops.

I would like to keep pygbag for jammers and pygame regulars and pyodide/pyscript for education.

sidenote: on your wip i don't see where you get SDL2_image exactly from, the only good one is the git last release version of it, the emscripten one may be way too old. Imho the patch is not required and could be harmfull, removing static linking of the pygame modules in only one (pygame_static.so) is not a good idea. emsdk linker is not robust enough to handle so many dynamic modules. It would also possibly break pygame C-API which make heavy use of functions pointers beetween all those modules ( no trampoline ).

@ryanking13
Copy link
Member

The idea is to package pygame_static.so directly in the pygame-ce wheel upstream for pyodide/pyscript , this will have no impact on pygbag since it has its own wheels repo.

Yes, that is what I am trying to do. Though I hope it could be upstreamed so that we don't need to do it manually. Or maybe someday we can build SDL libraries in shared libraries, so we can remove pygame_static at all.

i think then it's time to integrate threading to facilitate code porting. I saw that quite a lot of people new to pygame/python don't get how to asyncify game engine loops.

Yeah, dealing with loops is a problem (#3697). Could you elaborate a little more about threading? Does pygbag use threading?

on your wip i don't see where you get SDL2_image exactly from, the only good one is the git last release version of it, the emscripten one may be way too old.

I built SDL2_image 2.6.2, and yes emscripten one is too old (but they updated it recently).

@pmp-p
Copy link
Contributor

pmp-p commented Apr 4, 2023

pygbag will probably never use bigint or threading ( and also aim to be wasi compatible soon ) target is Chromium 95 ( android 5) and safari 14 ( unsure ).

That's why i'd like to explore threading on pyodide, to get even better pygame code portability on web only ( at the expanse of performance, compatibility and complexity which game jammers may not want ). There's also wasm asyncify which maybe be handy since threading may not have sound ( but is it really a problem for education ?)

i'll track my efforts to build directly a pyodide wheel from pygame-ce CI here pygame-web/pkg-porting-wasm#20

@pmp-p
Copy link
Contributor

pmp-p commented Apr 6, 2023

@ryanking13 here's my bigint wheel https://pmp-p.ddns.net/pygame_ce-2.3.0.dev1-cp311-cp311-emscripten_3_1_34_wasm32.whl but i get an Uncaught RuntimeError: unreachable which i think comes from the use of asyncify in the main module.

@ryanking13
Copy link
Member

@pmp-p Thanks! I'll check when I have time.

@ryansobol
Copy link

Hey everyone. It's been about four months; and in that time, we've seen the release of pyodide 0.23.4 and pygame-ce 2.3.0 (with 2.3.1 right around the corner). Well done! It's super impressive how hard you have worked to improve these tools for the benefit of the community. I sincerely appreciate everything you do!

This is just a friendly reminder about how critical the integration of these two technologies are to advance the state of Python education. Hopefully, this nudge is well-received and reignites your passion around that effort.

I know there are a couple of big hurdles in the way of seamless interoperability. It seems there are some open questions around bigint and threading—not small engineering topics! Maybe if we keep the communication flowing, we can all better understand the nature of the problems and begin coordinating on how to work toward bite-sized solutions.

@ryanking13
Copy link
Member

Sorry, I haven't been paying attention to this issue. Thanks for the reminder @ryansobol, and sorry for the very late response @pmp-p.

I resumed work on building the pygame package for Pyodide. I was able to build and load pygame-ce, but I got following error message when I tried to load an example in pygame:

>>> import pygame
pygame-ce 2.1.4 (SDL 2.24.2, Python 3.11.3)
>>> import pygame.examples.stars
>>> pygame.examples.stars.main()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/lib/python3.11/site-packages/pygame/examples/stars.py", line 105, in main
    screen = pg.display.set_mode((600, 500))
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pygame.error: The video driver did not add any displays

So it looks like I need some way to set the display to HTML canvas.

@tigercoding56
Copy link

tigercoding56 commented Aug 11, 2023

can someone reply to this comment , and notify me when pyodide has support for pygame

@pmp-p
Copy link
Contributor

pmp-p commented Sep 17, 2023

pygame.error: The video driver did not add any displays

I don't think the problem is on pygame-ce side, most likely you have some parts of sdl2 linked both in the main and side module.

Somehow that configuration hides the main module window handle from the side module.

At some point it should be decided if side module must ship its whole third party requirements or can pyodide serve as a host ( pygbag used to do that, but i'm moving away from that now that wasm wheels are viable).

@ryanking13
Copy link
Member

I don't think the problem is on pygame-ce side, most likely you have some parts of sdl2 linked both in the main and side module.

Yeah, we link JS part of the SDL2 to the main module and native parts to the side module.

@pmp-p
Copy link
Contributor

pmp-p commented Sep 19, 2023

i also get trouble with pygame.font/freetype init, once again I think main module is shadowing critical handles from side module. i'd say it looks like bug behaviour from emscripten, would not be the first time ;)

@ryanking13
Copy link
Member

Hmm... okay. Thanks for the information. Which parts of the pygame codebase would be helpful to look at? It's hard to understand what's going on just by looking at high-level errors at the python level.

@pmp-p
Copy link
Contributor

pmp-p commented Nov 23, 2023

@ryanking13 i could repro something similar to your problem with cpython wasm + pygame-ce wheel when hooking on import errors in a toplevel async context.

I think maybe display init is failing if maybe an exception not yet reported is set before entering set_mode(). It could maybe be a cython code exception, how exactly did you get the shared library instanciated and did you give it some time after streaming compilation ?.

I really have no certitude, it's only best guess i could get for now.

implementing PEP0723 on failing sample solved it for me

@ryanking13
Copy link
Member

@pmp-p Thanks for the info!

how exactly did you get the shared library instanciated and did you give it some time after streaming compilation ?.

Pyodide instantiates all shared libraries inside the wheel when we call pyodide.loadPackage, before importing a module.

implementing PEP0723 on failing sample solved it for me

This sounds very interesting. I'll try to see if it works in Pyodide too.

@ryanking13
Copy link
Member

Okay, I made some large progress on this. I think I can open a PR soon.

Here are some demos running pygame.examples

@pmp-p I am having some trouble rendering fonts. The error says "pygame.error: Library not initialized". Is it related to your draft PR (pygame-community/pygame-ce#1967)?

@pmp-p
Copy link
Contributor

pmp-p commented Feb 17, 2024

@ryanking13 most likely, as i apply it automatically pmp-p/pygame-ce-wasm#3 . Did not have time to see exactly what is really needed in the PR

@ryanking13
Copy link
Member

@ryanking13 most likely, as i apply it automatically pmp-p/pygame-ce-wasm#3 . Did not have time to see exactly what is really needed in the PR

Thanks. I'll apply your patch and see if it works.

@Vandivier
Copy link

@pmp-p @ryanking13 is this doc out of date? i don't see pygame listed
https://developers.cloudflare.com/workers/languages/python/packages/

@hoodmane
Copy link
Member

@Vandivier that isn't Pyodide documentation it is cloudflare's documentation. Our documentation of the package set is here:
https://pyodide.org/en/latest/usage/packages-in-pyodide.html
and it correctly includes pygame-ce.

Btw @ryanking13 this probably deserves a release note.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.