Skip to content

Introducing <script type="py-game"> #2265

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

Merged
merged 3 commits into from
Feb 5, 2025

Conversation

WebReflection
Copy link
Contributor

@WebReflection WebReflection commented Dec 12, 2024

Description

This MR would like to land an experimental implementation of the py-game special type with the following features:

  • a <script type="py-game"> with either content or an src and an optional target to reach the desired canvas, where by default it expects to be a <canvas id="canvas"> as suggested by the SDL2 Emscripten implementation
  • currently, this script can only work on the main thread due limitations of the underlying stack (window.screen required + cursor not working and so on and so forth ... no worker driven for now)
  • there is no mpy-game counter-part for the time being
  • most of the pyscript namespace should work out of the box regardless ... the whole stdlib is available
  • the script doesn't use <py-config> and it doesn't have an <py-game-config> custom config type ... by default pygame-ce is used as package and extra packages can be added manually as explicit config ... this might change in the future

Changes

Checklist

  • I have checked make build works locally.
  • I have created / updated documentation for this change (if applicable).

@WebReflection WebReflection force-pushed the script-type-py-game branch 2 times, most recently from 87f2976 to 7c62a30 Compare December 12, 2024 13:02
@WebReflection WebReflection requested a review from ntoll December 12, 2024 13:03
@Neon22
Copy link
Contributor

Neon22 commented Jan 28, 2025

Question was asked in the newsletter about how to signal "pygame": toml or tag.
I vote for toml.

Reasons:

  • It doesn't "need" to be at the top level visibility for ease of use,
  • It just needs to be documented clearly as to what to do in the special case of "writing a pygame",
    • and possibly in the general case of "including it because the user is going to do something novel".
  • Keeps the script tags as minimal as possible - which seems like the right thing to do.

@mhsmith
Copy link

mhsmith commented Jan 29, 2025

I agree with @Neon22. As it stands, there's a pretty clear separation between the script tag selecting the interpreter, and the config file configuring it. Adding package-specific options to the script tag would confuse that division of responsibility.

The newsletter expressed a concern that "this doesn’t make it obvious from the <script> tag that PyGame is needed". But there's never been any suggestion that the script tag should make it obvious if a script is using Invent, or any other GUI framework. All it needs to make obvious is which file you should look at for further details.

@WebReflection
Copy link
Contributor Author

as internally mentioned, py-game-ce is "a different beast":

  • it cannot use workers, the env is different from regular pyodide env
  • we don't allow multiple py scripts on the main thread ... here the story might be different, as example, bootstrapping more than a single game on the same page
  • we cannot optimize to have a shared env created ad-hoc for games only because work on that area would affect also regular pyodide expectations

When a new type is used, like it is for py-editor, it's because if the config flag, or the attribute, would completely change the whole way regular py counterpart would work, it feels less intuitive, harder to document or reason about, all the things that config flag did.

If py-game was out of a config flag, it would not be just an opt-in for scripts that used to work before that, so in that sense py-game helps separating capabilities, features, and allow optimizations or new patters around py-game-ce potentials.

Yes, I fully agree <script type="py-matplotlib"> is a nonsense, when just a package is needed to make matplotlib happen, but here there was an initial simplification that could grow further and provide a lovely DX later on without confining py-game to just py-game-ce package and limitations, actually just providing a new way to write pyodide games on the Web.

I am not strongly convinced it was the best decision, but I am sure having py-game-ce just as package that automatically will break or change the way pyodide works and interferes with currently supported attributes (worker to name one) will lead to confusion and least expectations from anyone trying to just load that package in a way or another.

I hope this helps clarifying why this was the decision at the time this MR landed but I am happy to hear solutions around these concerns.

@mhsmith
Copy link

mhsmith commented Jan 29, 2025

I admit I don't know much about the internals here. I guess the main thing I didn't understand about the newletter's description of the feature is: if it "uses PyScript’s built-in plugin system", then couldn't it be activated using the plugins configuration setting?

@Neon22
Copy link
Contributor

Neon22 commented Jan 29, 2025

Ahh I see how the implications are going to be hard to clearly communicate.
There doesn't appear to be an ideal answer unless some new kind of extra field labelling is used (which I can't think of).

So a "script tag" is probably the only viable solution. Just as you have already identified.

Perhaps the tagname could indicate a limitation in some way.
Like maybe "py-game-unique", or "py-game-limited", "py-game-solo", "py-game-isolated", ... grab your thesaurus :)

@WebReflection
Copy link
Contributor Author

the tag name could be explicitly py-game-ce too, but that has the side-effect of confining a specialized py-game (yes, I know, it's a module, but also an intent) type to only target currently awesome py-game-ce package only.

The thing with <script type="py" py-game worker terminal> is that it could fail in exponential ways around the features both worker and terminal allows on regular py type ... on top of that, because we never supported multiple <script type="py" config="something-else"> on the main thread, hence the reason we have worker to create any ad-hoc pyodide target env you like, failing at multiple games on the same page felt counter-productive or counter-intuitive to me.

We have historical guards around ensuring a unique pyodide instance can't be arbitrarily polluted with multiple tags on the same main page, but as py-game-ce is something new to explore and work with, still needed for various reasons behind the scene on the main thread, it felt "natural" or better suited for its own kind so it won't ever conflict with whatever py can do with attributes or its own standard lib (i.e. PyWorker is not allowed - yet - in py-game script type) ... also, once again: py-game as a script type has a broader scope (in the future) than just py-game-ce, it can have its own config as <py-game-config> tag or attribute, it can bootstrap multiple games where each of them is isolated, as environment, from others, it allows a possible <script type="mpy-game"> in the future too.

As summary, now that you know all the reasons py-game was shaped this way, do you still think having it as part of just py would be more beneficial than problematic?

@WebReflection
Copy link
Contributor Author

worth mentioning in here too: having conflicting attributes on the same tag has no precedent in the Web history ... so "just add py-game attribute" when it currently fails with worker is already an architectural no-go to me.

We never wanted to support multiple config on the same main thread so that, unless that changes, meaning we change entirely the bootstrap of PyScript on the main thread, I am not sure that's a good way forward ... a dedicated type for games fells way easier to reason about to me, happy to hear alternative suggestions though.

@fpliger
Copy link
Contributor

fpliger commented Jan 29, 2025

I've already discussed this with @WebReflection and just want to capture my feelings on this....

I do think that using a specific type for this is limiting and prevents future developments where we want to combine multiple frameworks in the same interpreter. I don't have a strong preference between attributes or the config but to see @mhsmith and @Neon22 points around the config and it being more flexible. I also like the fact that, if we use the config, we can also use it to extend these type of things with their own config (section) if they need it

Anyway, for now, I'm totally supportive of rolling this out as an experimental feature under an experimental type and defer these architectural decision later

@WebReflection
Copy link
Contributor Author

WebReflection commented Jan 29, 2025

I also like the fact that, if we use the config, we can also use it to extend these type of things with their own config (section) if they need it

strongly agreed, too bad we don't support multiple configs or multiple pyodide bootstrap to date on the main thread (just workers) ... if this is the drop that makes us change such historical status-quo, I'd be all in to make it happen so that users can create as many pyodide or micropython dedicated environments also on the main thread and we just bootstrap those based on each dedicated config: multiple games, multiple envs, users in charge 👍

edit for context, polyscript (the one bootstrapping PyScript) already supports this via the env attribute ... also used in our py-editor kind ... maybe it's time to fully unleash its potentials!

@WebReflection
Copy link
Contributor Author

@ntoll this is how I would describe this MR once landed:


PyGame - ⚠️ Experimental

When a <script type="py-game"> is found on the page a pyodide instance is bootstrapped with a pygame-ce package already embedded. Differently from other scripts, py-game cannot currently work through a worker and it uses an optional target attribute to define the canvas element id that will be used to render the game. If no target attribute is defined, the script assumes there is a <canvas id="canvas"> element on the page.

A config attribute can be specified to add extra packages but right now that's all it can do.

We are landing this helper as experiment but:

  • it is possible to use regular PyScript to also load pygame-ce package and use all other features, this helper simply allows multiple games and forces logic on the main thread to reduce confusion around attributes and features when pygame-ce package is meant to be used
  • the fact pygame-ce is the default "game engine" does not mean in the future a py-game script won't have other engines also available
  • as experiment, we welcome any kind of feedback, suggestions, hints on how to improve or what's missing

thoughts?

@ntoll
Copy link
Member

ntoll commented Feb 5, 2025

Folks, thank you so much for your thoughtful and collaborative input on this. This is how open-source coding is supposed to work! 🎉

Approving this on the proviso that it's experimental.

Copy link
Member

@ntoll ntoll left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit: 👾

@WebReflection WebReflection merged commit fc53356 into pyscript:main Feb 5, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants