Closed salazarbarrera closed 8 months ago
I just realized something that may help others though. If one clears the screen and properly nulls all the objects, one can call a game from another one as long as:
It's not as straightforward as the Load() command, but it's a good workaround
Here's a proof of concept of how a launcher could be made with the current codebase. It basically takes the scripts, comments out all calls to pyxel.init() and pyxel.run(), injects code to the update method of the scripts and finally runs it. It can't adapt to different width and heights, it always runs with the default frame rate, and the size of the window and pixels is the default one too.
Everything is very hacky, and probably a re-implementation of pyxel.show() and pyxel.init() could make the task way easier, but at least a solution exist.
Thank you for the prototype. I've also experimented with restarting code in the past when I wanted to do so.
If I were to add an app load feature to Pyxel, I think I would need a method that meets the following conditions:
Works the same in both web and native environments Supports resolution for each application Can restart not only the Pyxel code but also other Python modules being used I haven't found such a method yet, but if I do, I'd like to implement this feature.
Since there is no change in the situation, I will close this issue.
The only way to do this would not be at the Python level, because of all the interpreter state (imported modules, globals…) as well as pyxel state (resolution, palette…), so I can only see using os.execl to execute a clean new process, replacing the current one.
The only thing missing for a pico8-style function would be a way to pass info about the caller, so that the loaded game can provide a way to go back to the original. That could be done with an environment variable for example.
Note: At least I think it's a feature not implemented yet, correct me if I'm wrong.
Would it be possible to implement a method similar to Load() that allows to play or run a pyxel program from within another pyxel program? This would allow to make custom launchers and other kind of experiments. I know it would be trivial to create a standalone launcher that uses the sys module to run pyxel under the hood, but that wouldn't be an option for browser-based releases (which in turn allow to create mobile-compatible releases), nor an efficient solution (an instance of the platform would be loaded every time a script in run).
I tried to directly use the run_python_script() method from cli.py, to directly use runpy and to directly import other pyxel programs, but in the best case scenario, I only could get the following runtime error:
"an `EventPump` instance is already alive - there can only be one `EventPump` in use at a time."
Because of this, I guess an alternative to having a Load() interface could be a way to destroy the EventPump (I'm not sure if that's possible) or allow the creation of independent processes.
Right now the alternative I see is to create third party launchers (like using a GUI to execute commands on desktop or making a website that loads the games inside iframes), but nothing native.
Edit: I just realized that the problem originates in the Rust core. I guess it could be possible to tell the core to use the same Platform singleton, or at least use the same instance of sdl_event_pump, but I know almost nothing about Rust, so what I just wrote could be just nonsense as far as I know. I guess the third party launcher is the way to go for now. Here's the error I get when I tried to call
pyxel.cli.run_python_script()
from a Pyxel program running in the Web Launcher: