diff --git a/.github/workflows/jekyll-gh-pages.yml b/.github/workflows/deploy.yml similarity index 77% rename from .github/workflows/jekyll-gh-pages.yml rename to .github/workflows/deploy.yml index e31d81c..49e7eff 100644 --- a/.github/workflows/jekyll-gh-pages.yml +++ b/.github/workflows/deploy.yml @@ -1,5 +1,4 @@ -# Sample workflow for building and deploying a Jekyll site to GitHub Pages -name: Deploy Jekyll with GitHub Pages dependencies preinstalled +name: Deploy sphinx site to Pages on: # Runs on pushes targeting the default branch @@ -26,17 +25,18 @@ jobs: build: runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v4 + - uses: actions/checkout@v4 + - name: Install Sphinx and other dependencies + run: pip install -r requirements.txt # assume ubuntu-latest will have pip - name: Setup Pages + id: pages uses: actions/configure-pages@v5 - - name: Build with Jekyll - uses: actions/jekyll-build-pages@v1 - with: - source: ./ - destination: ./_site + - name: Build with Sphinx + run: sphinx-build source build - name: Upload artifact uses: actions/upload-pages-artifact@v3 + with: + path: ./build # Deployment job deploy: diff --git a/.gitignore b/.gitignore index a3816f7..b2f564d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,5 @@ /.idea # for local testing -Gemfile.lock -Gemfile -.jekyll-metadata -_site +.venv +build diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..95120d1 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,4 @@ +{ + "printWidth": 80, + "proseWrap": "always" +} \ No newline at end of file diff --git a/README.md b/README.md index 08b3cc2..67a3bf3 100644 --- a/README.md +++ b/README.md @@ -1,145 +1,33 @@ # pygame-web.github.io -![pygbag logo](assets/pygbag_logo.png?raw=true "Pygbag Logo") +This is the CDN root used by [Pygbag](https://pypi.org/project/pygbag/) and its +documentation. -This is the CDN root used by [Pygbag](https://pypi.org/project/pygbag/). +The documentation is built with [sphinx-doc](https://www.sphinx-doc.org) and the +[furo](https://pradyunsg.me/furo/) theme. We also recommend using +`sphinx-autobuild`. -[The wiki](/wiki/). +To build the docs, install the dependencies: -[Source code](https://github.com/pygame-web/pygbag) - -[Old runtimes and current](https://github.com/pygame-web/archives) - - -### Pygbag does not track usage at all, not even for statistical purposes. -If you like it, please [star](https://github.com/pygame-web/pygbag/stargazers) the repository! - -## (Very) important points - -**Also, read the page on [making your code compatible with browser game loop](https://pygame-web.github.io/wiki/python-wasm). You will probably have to change some of your code.** - -### All operating systems - -- Name your main game script `main.py` and put it in the root folder of your game. -- Make your main loop async-aware and use `asyncio.sleep(0)` every iteration to give control back to the main thread. -- Add `--template noctx.tmpl` to pygbag command line if using 3D/WebGL. -- Put the import statements of complex packages in order (but numpy first) at the top of `main.py`. -- Avoid using CPython's standard library for web operations, GUI (like tkinter), or I/O as it is very synchronous/platform-specific and will probably stay that way. In terms of GUI alternatives, [pygame_gui](https://pypi.org/project/pygame_gui) works on top of [pygame-ce](https://pyga.me), [Panda3D](https://www.panda3d.org/) provides [directgui](https://docs.panda3d.org/1.10/python/programming/gui/directgui/index) and Harfang3D provides imgui. They are all cross-platform. -- You can add a square image file named `favicon.png` in your game's root folder to make Pygbag use it as the web package's favicon. -- Make sure all audio files are in OGG (best compression format targeting 16bits 24Khz Mono). (that is especially **not in WAV/AIFF/M4A/MP3 format**) -- Avoid raw formats like BMP for your image assets, they are too big for web use; use PNG/WEBP or JPG instead. - -- Filenames are case sensitive ( Folder/MyFile.png and folder/myfile.png are two different files). Do not use filenames like `*-pygbag.*` that pattern is reserved for pygbag internal use (optimizing pass). - -Before packaging, adapt your code this way if you still want WAV/MP3 format on desktop: -```py -if sys.platform == "emscripten": - snd = pygame.mixer.Sound("sound.ogg") -else: - snd = pygame.mixer.Sound("sound.wav") # or .WAV, .mp3, .MP3, etc. ``` - -if you have heightmaps in your assets use `--no_opt` to prevent png recompression. - -if you want to keep pixelated look whatever the device screen size is use: -```py -import sys, platform -if sys.platform == "emscripten": - platform.window.canvas.style.imageRendering = "pixelated" +pip install -r requirements.txt ``` -### Windows - -- Use Python that was downloaded from python.org rather than the Windows Store. You can check installed version(s) with the `py --list` command. -- Use `/` instead of `\​` as a path separator (e.g. `img/my_image.png` instead of `img\my_image.png`). The path should still be valid on newer Windows versions. - -### MacOS - -- If you get a SSL error, use the file `Install Certificates.command` in `Applications/Python 3.XX`. - -### Linux - -- When using webusb ftdi serial emulation, use `sudo rmmod ftdi_sio` after plugging devices. - - - -## Templates - -There is actually nothing specific for projects except naming entry point main.py, because Python-WASM is just a web-friendly version of CPython REPL with [some added facilities](https://discuss.python.org/t/status-of-wasm-in-cpythons-main-branch/15542/12?u=pmp-p). Most desktop code will run (and continue to run) with only a few changes. - -Basic structure of a game (available [here](https://github.com/pygame-web/pygbag/tree/main/test)): -``` -test -├── img -│   ├── pygc.bmp -│   ├── pygc.png -│   └── tiger.svg -├── main.py -└── sfx - └── beep.ogg -``` -where `test` is the "runtime game folder", current working directory ( os.getcwd() ) or more simply "." +To build the documentation with `sphinx-autobuild`, simply run: -Useful .gitignore additions: ``` -*.wav -*.mp3 -*.pyc -*.egg-info -*-pygbag.??? -/build -/dist +pip install sphinx-autobuild # only needed for first time using autobuild +sphinx-autobuild source build ``` -But there are templates to customize runtime startup for 2D and 3D, see [templates](/wiki/pygbag/#templates) - - -[controlling pygbag packing and options from pygbag.ini](/wiki/pygbag-configuration) - - -## Coding - -- [General Python-WASM](/wiki/python-wasm/) -- [With Pygbag specifically](/wiki/pygbag-code/) -- [Pygbag code examples](/wiki/pygbag-code/#pygbag-code-specificssamples) - -## Adding modules - -- [List of available wheels](/wiki/pkg/) -- [requesting modules](https://github.com/pygame-web/pkg-porting-wasm/issues) -- [Panda3D quickstart](https://pygame-web.github.io/wiki/pkg/panda3d) - -When importing **non-stdlib** packages (for example, numpy or matplotlib), you must put their import statements at top of `main.py`. You should also add a metadata header as specified by [PEP 723](https://peps.python.org/pep-0723/), for example: +This will watch your files for changes and update your build on save. Or, +manually, -```py -# /// script -# dependencies = [ -# "pygame-ce", -# "pyscroll", -# "pytmx", -# ] -# /// ``` -more on : https://packaging.python.org/en/latest/specifications/inline-script-metadata/#inline-script-metadata - -## Debugging / Desktop Simulator - -- The REPL shortcut http://localhost:8000?-i, REPL will (should) run concurrently as main.py. -- [How to enter debug mode](/wiki/pygbag-debug/) -- While working, you can access the simulator of the web loop by replacing `import asyncio` by `import pygbag.aio as asyncio` at top of main.py and run the program from the folder containing it. -- TODO: Android remote debugging via [chromium browsers series](https://developer.chrome.com/docs/devtools/remote-debugging/). -- TODO: Universal remote debugging via IRC Client or websocket using pygbag.net. -- [pygbag runtime ?](/wiki/pygbag-internals) - - -There's number of command line options : read Pygbag's [project description](https://pypi.org/project/pygbag/) for a more detailed overview. - - -Visit the [wiki](/wiki/) to get started! - - -**Work in progress, pull requests welcomed. Feel free to propose links to games or tutorials. Please contribute!!!** - -Logo thanks to https://github.com/FinFetChannel +sphinx-build source build +cd build +python -m http.server +``` -[Edit this page](https://github.com/pygame-web/pygame-web.github.io/edit/main/README.md) +You will be able to view the site locally at +[http://127.0.0.1:8000](http://127.0.0.1:8000). diff --git a/assets/README.md b/assets/README.md deleted file mode 100644 index 40f2b65..0000000 --- a/assets/README.md +++ /dev/null @@ -1,7 +0,0 @@ -Pygbag related community creations - -[](https://github.com/pygame-web/pygame-web.github.io/tree/main/assets) - - -[](https://github.com/pygame-web/pygame-web.github.io/tree/main/assets) - diff --git a/old/README.md b/old/README.md new file mode 100644 index 0000000..cf07dd2 --- /dev/null +++ b/old/README.md @@ -0,0 +1,145 @@ +# pygame-web.github.io + +![pygbag logo](assets/pygbag_logo.png) + +This is the CDN root used by [Pygbag](https://pypi.org/project/pygbag/). + +[The wiki](/wiki/). + +[Source code](https://github.com/pygame-web/pygbag) + +[Old runtimes and current](https://github.com/pygame-web/archives) + + +### Pygbag does not track usage at all, not even for statistical purposes. +If you like it, please [star](https://github.com/pygame-web/pygbag/stargazers) the repository! + +## (Very) important points + +**Also, read the page on [making your code compatible with browser game loop](https://pygame-web.github.io/wiki/python-wasm). You will probably have to change some of your code.** + +### All operating systems + +- Name your main game script `main.py` and put it in the root folder of your game. +- Make your main loop async-aware and use `asyncio.sleep(0)` every iteration to give control back to the main thread. +- Add `--template noctx.tmpl` to pygbag command line if using 3D/WebGL. +- Put the import statements of complex packages in order (but numpy first) at the top of `main.py`. +- Avoid using CPython's standard library for web operations, GUI (like tkinter), or I/O as it is very synchronous/platform-specific and will probably stay that way. In terms of GUI alternatives, [pygame_gui](https://pypi.org/project/pygame_gui) works on top of [pygame-ce](https://pyga.me), [Panda3D](https://www.panda3d.org/) provides [directgui](https://docs.panda3d.org/1.10/python/programming/gui/directgui/index) and Harfang3D provides imgui. They are all cross-platform. +- You can add a square image file named `favicon.png` in your game's root folder to make Pygbag use it as the web package's favicon. +- Make sure all audio files are in OGG (best compression format targeting 16bits 24Khz Mono). (that is especially **not in WAV/AIFF/M4A/MP3 format**) +- Avoid raw formats like BMP for your image assets, they are too big for web use; use PNG/WEBP or JPG instead. + +- Filenames are case sensitive ( Folder/MyFile.png and folder/myfile.png are two different files). Do not use filenames like `*-pygbag.*` that pattern is reserved for pygbag internal use (optimizing pass). + +Before packaging, adapt your code this way if you still want WAV/MP3 format on desktop: +```py +if sys.platform == "emscripten": + snd = pygame.mixer.Sound("sound.ogg") +else: + snd = pygame.mixer.Sound("sound.wav") # or .WAV, .mp3, .MP3, etc. +``` + +if you have heightmaps in your assets use `--no_opt` to prevent png recompression. + +if you want to keep pixelated look whatever the device screen size is use: +```py +import sys, platform +if sys.platform == "emscripten": + platform.window.canvas.style.imageRendering = "pixelated" +``` + +### Windows + +- Use Python that was downloaded from python.org rather than the Windows Store. You can check installed version(s) with the `py --list` command. +- Use `/` instead of `\​` as a path separator (e.g. `img/my_image.png` instead of `img\my_image.png`). The path should still be valid on newer Windows versions. + +### MacOS + +- If you get a SSL error, use the file `Install Certificates.command` in `Applications/Python 3.XX`. + +### Linux + +- When using webusb ftdi serial emulation, use `sudo rmmod ftdi_sio` after plugging devices. + + + +## Templates + +There is actually nothing specific for projects except naming entry point main.py, because Python-WASM is just a web-friendly version of CPython REPL with [some added facilities](https://discuss.python.org/t/status-of-wasm-in-cpythons-main-branch/15542/12?u=pmp-p). Most desktop code will run (and continue to run) with only a few changes. + +Basic structure of a game (available [here](https://github.com/pygame-web/pygbag/tree/main/test)): +``` +test +├── img +│   ├── pygc.bmp +│   ├── pygc.png +│   └── tiger.svg +├── main.py +└── sfx + └── beep.ogg +``` +where `test` is the "runtime game folder", current working directory ( os.getcwd() ) or more simply "." + +Useful .gitignore additions: +``` +*.wav +*.mp3 +*.pyc +*.egg-info +*-pygbag.??? +/build +/dist +``` +But there are templates to customize runtime startup for 2D and 3D, see [templates](/wiki/pygbag/#templates) + + +[controlling pygbag packing and options from pygbag.ini](/wiki/pygbag-configuration) + + +## Coding + +- [General Python-WASM](/wiki/python-wasm/) +- [With Pygbag specifically](/wiki/pygbag-code/) +- [Pygbag code examples](/wiki/pygbag-code/#pygbag-code-specificssamples) + +## Adding modules + +- [List of available wheels](/wiki/pkg/) +- [requesting modules](https://github.com/pygame-web/pkg-porting-wasm/issues) +- [Panda3D quickstart](https://pygame-web.github.io/wiki/pkg/panda3d) + + +When importing **non-stdlib** packages (for example, numpy or matplotlib), you must put their import statements at top of `main.py`. You should also add a metadata header as specified by [PEP 723](https://peps.python.org/pep-0723/), for example: + +```py +# /// script +# dependencies = [ +# "pygame-ce", +# "pyscroll", +# "pytmx", +# ] +# /// +``` +more on : https://packaging.python.org/en/latest/specifications/inline-script-metadata/#inline-script-metadata + +## Debugging / Desktop Simulator + +- The REPL shortcut http://localhost:8000?-i, REPL will (should) run concurrently as main.py. +- [How to enter debug mode](/wiki/pygbag-debug/) +- While working, you can access the simulator of the web loop by replacing `import asyncio` by `import pygbag.aio as asyncio` at top of main.py and run the program from the folder containing it. +- TODO: Android remote debugging via [chromium browsers series](https://developer.chrome.com/docs/devtools/remote-debugging/). +- TODO: Universal remote debugging via IRC Client or websocket using pygbag.net. +- [pygbag runtime ?](/wiki/pygbag-internals) + + +There's number of command line options : read Pygbag's [project description](https://pypi.org/project/pygbag/) for a more detailed overview. + + +Visit the [wiki](/wiki/) to get started! + + +**Work in progress, pull requests welcomed. Feel free to propose links to games or tutorials. Please contribute!!!** + +Logo thanks to https://github.com/FinFetChannel + +[Edit this page](https://github.com/pygame-web/pygame-web.github.io/edit/main/README.md) diff --git a/old/assets/README.md b/old/assets/README.md new file mode 100644 index 0000000..f6936a7 --- /dev/null +++ b/old/assets/README.md @@ -0,0 +1,7 @@ +# assets +Pygbag related community creations + +![pyg1](pyg1.png) + +![pyg2](pyg2.png) + diff --git a/assets/pyg1.png b/old/assets/pyg1.png similarity index 100% rename from assets/pyg1.png rename to old/assets/pyg1.png diff --git a/assets/pyg2.png b/old/assets/pyg2.png similarity index 100% rename from assets/pyg2.png rename to old/assets/pyg2.png diff --git a/assets/pygbag_logo.png b/old/assets/pygbag_logo.png similarity index 100% rename from assets/pygbag_logo.png rename to old/assets/pygbag_logo.png diff --git a/platform_wasm/README.md b/old/platform_wasm/README.md similarity index 75% rename from platform_wasm/README.md rename to old/platform_wasm/README.md index 733b852..ffc3a44 100644 --- a/platform_wasm/README.md +++ b/old/platform_wasm/README.md @@ -1 +1,2 @@ +# platform_wasm support for interfacing packages with wasm hosts diff --git a/old/wiki/dinovm/README.md b/old/wiki/dinovm/README.md new file mode 100644 index 0000000..0d9b9a5 --- /dev/null +++ b/old/wiki/dinovm/README.md @@ -0,0 +1,2 @@ +# dinovm +WIP diff --git a/wiki/README.md b/old/wiki/index.md similarity index 94% rename from wiki/README.md rename to old/wiki/index.md index fb8fc03..2da9d74 100644 --- a/wiki/README.md +++ b/old/wiki/index.md @@ -1,6 +1,8 @@ -Check out some [demos](#demos-on-itchio) before you start! +# Wiki -## Using Pygbag +```{seealso} +Check out some [demos](#demos-on-itchio) before you start! +``` - Visit [this page](/wiki/pygbag/) on how to use Pygbag to make web games with Python. - Visit [this page](/wiki/pygbag-code/) for useful Pygbag code snippets and a Pygbag FAQ. @@ -112,3 +114,19 @@ Thanks for reading and supporting pygame-ce and pygbag. These tools could not ha [edit this page](https://github.com/pygame-web/pygame-web.github.io/edit/main/wiki/README.md) + +```{toctree} +pygbag/README +pygbag-code/README +pygbag-configuration/README +pygbag-debug/README +pygbag-internals/README +pygbag-script/README +python-wasm/README +dinovm/README +pkg/README +pkg/nurses_2/README +pkg/panda3d/README +publishing/github.io/README +publishing/itch.io/README +``` \ No newline at end of file diff --git a/wiki/pkg/README.md b/old/wiki/pkg/README.md similarity index 99% rename from wiki/pkg/README.md rename to old/wiki/pkg/README.md index 7c6be65..fb294d3 100644 --- a/wiki/pkg/README.md +++ b/old/wiki/pkg/README.md @@ -1,3 +1,4 @@ +# pkg Welcome to the pygbag packages (actually wheel format) repository list. README.md should be in /wiki/pkg/``/README.md , not the pypi project name. diff --git a/wiki/pkg/nurses_2/README.md b/old/wiki/pkg/nurses_2/README.md similarity index 98% rename from wiki/pkg/nurses_2/README.md rename to old/wiki/pkg/nurses_2/README.md index bef4c2c..6ba1836 100644 --- a/wiki/pkg/nurses_2/README.md +++ b/old/wiki/pkg/nurses_2/README.md @@ -1,3 +1,4 @@ +# nurses_2 [original documentation](https://salt-die.github.io/nurses_2/index.html) diff --git a/wiki/pkg/panda3d/README.md b/old/wiki/pkg/panda3d/README.md similarity index 96% rename from wiki/pkg/panda3d/README.md rename to old/wiki/pkg/panda3d/README.md index ad5c158..f668353 100644 --- a/wiki/pkg/panda3d/README.md +++ b/old/wiki/pkg/panda3d/README.md @@ -1,3 +1,4 @@ +# panda3d [Panda3D is a framework for 3D rendering and game development for Python and C++ programs.](https://pypi.org/project/Panda3D/) [original documentation](https://docs.panda3d.org/1.10/python/index) @@ -58,7 +59,7 @@ Changes made to get a wheel [PR against webgl-port branch](https://github.com/pm -# conversion tutorial +## conversion tutorial the basic command to produce a itch.io compatible zip is @@ -70,13 +71,13 @@ note: only use `--ume_block 0` when you have no sound playing at game startup ( This zip archive can be uploaded directly on itch after selection on the HTML game type . (provided everything else works and is set up as detailed below) -## changes to the code. +### changes to the code. The base used was [https://github.com/BMaxV/panda3d_shading 03main.py](https://github.com/BMaxV/panda3d_shading 03main.py) note: preferably use a 1024x600 screen size. -## changes to the code for web +### changes to the code for web so my original code uses this kind of mainloop: @@ -125,7 +126,7 @@ import pygbag.aio as asyncio which "gives control to the browser" in between ticks. -## importing a "pure python" custom module +### importing a "pure python" custom module For example the imported custom module is https://github.com/BMaxV/panda3d_interface_glue and that one should have no dependencies except Panda3D. @@ -143,7 +144,7 @@ which builds the module into a wheel at `interfacegluedir/dist` The wheel then s -## testing +### testing If you leave `--archive` out, it starts a local webserver instead and you can visit (default) http://localhost:8000/ to test how well it works. @@ -152,7 +153,7 @@ You can visit [http://localhost:8000/?-i](http://localhost:8000/?-i) instead to The name `main.py` is actually important, your main file has to be called `main.py`, alternative names will not work. -## github pages and CI +### github pages and CI Just clone this repo and adapt to your game : https://github.com/pmp-p/pygbag-panda3d-ci diff --git a/wiki/publishing/github.io/README.md b/old/wiki/publishing/github.io/README.md similarity index 99% rename from wiki/publishing/github.io/README.md rename to old/wiki/publishing/github.io/README.md index eaabb8d..e975791 100644 --- a/wiki/publishing/github.io/README.md +++ b/old/wiki/publishing/github.io/README.md @@ -1,3 +1,4 @@ +# github.io diff --git a/wiki/publishing/github.io/actions.png b/old/wiki/publishing/github.io/actions.png similarity index 100% rename from wiki/publishing/github.io/actions.png rename to old/wiki/publishing/github.io/actions.png diff --git a/wiki/publishing/github.io/pages.png b/old/wiki/publishing/github.io/pages.png similarity index 100% rename from wiki/publishing/github.io/pages.png rename to old/wiki/publishing/github.io/pages.png diff --git a/wiki/publishing/github.io/pygbag.yml b/old/wiki/publishing/github.io/pygbag.yml similarity index 100% rename from wiki/publishing/github.io/pygbag.yml rename to old/wiki/publishing/github.io/pygbag.yml diff --git a/wiki/publishing/github.io/yml.png b/old/wiki/publishing/github.io/yml.png similarity index 100% rename from wiki/publishing/github.io/yml.png rename to old/wiki/publishing/github.io/yml.png diff --git a/wiki/publishing/itch.io/README.md b/old/wiki/publishing/itch.io/README.md similarity index 100% rename from wiki/publishing/itch.io/README.md rename to old/wiki/publishing/itch.io/README.md diff --git a/wiki/pygbag-code/README.md b/old/wiki/pygbag-code/README.md similarity index 100% rename from wiki/pygbag-code/README.md rename to old/wiki/pygbag-code/README.md diff --git a/wiki/pygbag-configuration/README.md b/old/wiki/pygbag-configuration/README.md similarity index 85% rename from wiki/pygbag-configuration/README.md rename to old/wiki/pygbag-configuration/README.md index 6c4e7cf..adb0520 100644 --- a/wiki/pygbag-configuration/README.md +++ b/old/wiki/pygbag-configuration/README.md @@ -1,3 +1,4 @@ +# pygbag-configuration TODO: pygbag.ini diff --git a/wiki/pygbag-debug/README.md b/old/wiki/pygbag-debug/README.md similarity index 99% rename from wiki/pygbag-debug/README.md rename to old/wiki/pygbag-debug/README.md index 8192a64..5c29e42 100644 --- a/wiki/pygbag-debug/README.md +++ b/old/wiki/pygbag-debug/README.md @@ -1,3 +1,5 @@ +# pygbag-debug + pygbag comes with an interactive Python-like REPL that can be used for debugging. ## to open diff --git a/wiki/pygbag-internals/README.md b/old/wiki/pygbag-internals/README.md similarity index 99% rename from wiki/pygbag-internals/README.md rename to old/wiki/pygbag-internals/README.md index 4b4d02b..a4649bd 100644 --- a/wiki/pygbag-internals/README.md +++ b/old/wiki/pygbag-internals/README.md @@ -1,3 +1,4 @@ +# pygbag-internals When running in the webpage pygbag is in fact a C runtime linked to libpython ( cpython-wasm from python.org) compiled to WebAssembly with emscripten compiler and hosted on a CDN (pygame-web.github.io). It is downloaded once per game and per version update for fast local use. diff --git a/wiki/pygbag-script/README.md b/old/wiki/pygbag-script/README.md similarity index 99% rename from wiki/pygbag-script/README.md rename to old/wiki/pygbag-script/README.md index 746a3aa..225d7a6 100644 --- a/wiki/pygbag-script/README.md +++ b/old/wiki/pygbag-script/README.md @@ -1,3 +1,5 @@ +# pygbag-script + ## When to use pygbag script ? - when you don't need assets packaging because you download them at runtime. diff --git a/wiki/pygbag/README.md b/old/wiki/pygbag/README.md similarity index 100% rename from wiki/pygbag/README.md rename to old/wiki/pygbag/README.md diff --git a/wiki/python-wasm/README.md b/old/wiki/python-wasm/README.md similarity index 100% rename from wiki/python-wasm/README.md rename to old/wiki/python-wasm/README.md diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..768a524 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +sphinx +furo +myst-parser +sphinx-copybutton +sphinx-inline-tabs diff --git a/source/conf.py b/source/conf.py new file mode 100644 index 0000000..2f7ec15 --- /dev/null +++ b/source/conf.py @@ -0,0 +1,40 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = "pygbag" +copyright = "2025, pygbag" +author = "pygbag" + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + "myst_parser", + "sphinx_copybutton", + "sphinx_inline_tabs", +] + +# https://sphinx-copybutton.readthedocs.io/en/latest/use.html +copybutton_prompt_text = r"\$ |> " +copybutton_prompt_is_regexp = True + +templates_path = ["_templates"] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] + +source_suffix = { + ".rst": "restructuredtext", + ".txt": "markdown", + ".md": "markdown", +} + + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = "furo" +html_static_path = ["_static"] diff --git a/source/contributing.md b/source/contributing.md new file mode 100644 index 0000000..a933b40 --- /dev/null +++ b/source/contributing.md @@ -0,0 +1,36 @@ +# Contributing + +## To pygbag + +Pull requests welcome at +[https://github.com/pygame-web/pygbag](https://github.com/pygame-web/pygbag). + +## To these docs + +These docs are built with sphinx. See the github page. They take inspiration +from the [Diátaxis](https://diataxis.fr) approach, as well as the documentation +sites for [Gatsby](https://www.gatsbyjs.com/docs/), +[pytest](https://docs.pytest.org), and [furo](https://pradyunsg.me/furo/). + +### Style Guide + +Markdown files are formatted with prettier (see the prettierrc) and python code +blocks are formatted with black. + +All terminal commands should be expressed with tabs, even if they are the same +command on any operating system. Highlight the terminal output with `text`, lest +stray numbers or symbols be colored. An example is shown below. + +````` +````{tab} Unix/Mac +```text +$ command +``` +```` + +````{tab} Windows +```text +> command +``` +```` +````` diff --git a/source/explanations/index.md b/source/explanations/index.md new file mode 100644 index 0000000..24439a7 --- /dev/null +++ b/source/explanations/index.md @@ -0,0 +1,4 @@ +# Explanations + +Big-picture explanations of higher-level pygbag concepts. Most useful for +understanding why things are done. diff --git a/source/how-to/index.md b/source/how-to/index.md new file mode 100644 index 0000000..dbf48f5 --- /dev/null +++ b/source/how-to/index.md @@ -0,0 +1,8 @@ +# How-to Guides + +Practical step-by-step guides to help you achieve a specific goal. Most useful +when you're trying to get something done. + +```{toctree} +quick-start +``` diff --git a/source/how-to/quick-start.md b/source/how-to/quick-start.md new file mode 100644 index 0000000..84e48e8 --- /dev/null +++ b/source/how-to/quick-start.md @@ -0,0 +1,110 @@ +# Quick Start + +```{seealso} +[](../reference/pygbag-requirements.md) +``` + +This how-to guide explains how to convert different types of existing pygame +projects to be compatible with pygbag. It also explains how to run your +converted game locally in your browser. + +## Convert for pygbag + +pygbag is not usually affected by code split into multiple files with defined +functions, classes, and libraries throughout. So, you should first follow all +[](../reference/pygbag-requirements.md). Then, if your code already works +locally, simply follow the instructions that fit your `main.py` file. + +### Simplest + +Everything is flat in the same file. + +```py +# main.py +import pygame + +class Foo: + pass + +def bar(): + pass + +# +``` + +change to + +```py +# main.py +import pygame +import asyncio + +class Foo: + pass + +def bar(): + pass + +async def main(): + # + +asyncio.run(main()) +``` + +### Existing Main Function + +```py +# main.py +import pygame + +class Foo: + pass + +def bar(): + pass + +def main(): + # + +if __name__ == "__main__": + main() +``` + +change to + +```py +# main.py +import pygame +import asyncio + +class Foo: + pass + +def bar(): + pass + +async def main(): + # + +if __name__ == "__main__": + asyncio.run(main()) +``` + +## Run in browser + +Run the command + +````{tab} Unix/Mac +```text +$ pygbag path/to/main.py +``` +```` + +````{tab} Windows +```text +> pygbag path/to/main.py +``` +```` + +This will build the web game to `path/to/build` and let you play it at the link +[http://127.0.0.1:8000](http://127.0.0.1:8000) diff --git a/source/index.md b/source/index.md new file mode 100644 index 0000000..718357c --- /dev/null +++ b/source/index.md @@ -0,0 +1,142 @@ +# pygbag + + + +`pygbag` is a command-line tool for developing `pygame` projects for the web. + +This is the CDN root used by `pygbag`, as well as the location of its +documentation. + +```{note} +Pygbag does not track usage at all, not even for statistical purposes. + +If you like it, please [star](https://github.com/pygame-web/pygbag/stargazers) the repository! +``` + +## Minimal example + +```py +# main.py +import asyncio +import pygame + + +async def main(): + pygame.init() + screen = pygame.display.set_mode((320, 240)) + clock = pygame.time.Clock() + + x_pos = 0 + while True: + screen.fill((0, 0, 0)) + pygame.draw.circle( + surface=screen, + color=(255, 255, 255), + center=(x_pos, 10), + radius=4, + ) + pygame.display.update() + + x_pos += 1 + + clock.tick(60) + await asyncio.sleep(0) + + +asyncio.run(main()) +``` + +To run this game on web: + +``` +$ pygbag main.py +... +Serving HTTP on 127.0.0.1 port 8000 (http://localhost:8000/) ... +``` + +See [](./how-to/quick-start.md) for a basic how-to guide on using `pygbag`, or +[](./tutorials/simple-game-tutorial.md) for a longer step-by-step guide. + + + +```{toctree} +:hidden: + +tutorials/index +how-to/index +reference/index +explanations/index +``` + +```{toctree} +:caption: About +:hidden: + +contributing +pygbag on PyPI +pygbag on GitHub +pygbag old/current runtimes +``` diff --git a/source/reference/code-snippets.md b/source/reference/code-snippets.md new file mode 100644 index 0000000..f488a93 --- /dev/null +++ b/source/reference/code-snippets.md @@ -0,0 +1,3 @@ +# Code Snippets + +s diff --git a/source/reference/index.md b/source/reference/index.md new file mode 100644 index 0000000..cb1a2a5 --- /dev/null +++ b/source/reference/index.md @@ -0,0 +1,10 @@ +# Reference + +Nitty-gritty technical descriptions of how Gatsby works. Most useful when you +need detailed information about pygbag's usage and requirements. + +```{toctree} +pygbag-requirements +pygbag-options +code-snippets +``` diff --git a/source/reference/pygbag-options.md b/source/reference/pygbag-options.md new file mode 100644 index 0000000..a36f22f --- /dev/null +++ b/source/reference/pygbag-options.md @@ -0,0 +1,29 @@ +# pygbag Options + +- There's number of command line options: read Pygbag's + [PyPI](https://pypi.org/project/pygbag/) project description for a more + detailed overview. + +- You can add a square image file named `favicon.png` in your game's root folder + to make Pygbag use it as the web package's favicon. + +- Before packaging, adapt your code this way if you still want WAV/MP3 format on + desktop: + + ```py + if sys.platform == "emscripten": + snd = pygame.mixer.Sound("sound.ogg") + else: + snd = pygame.mixer.Sound("sound.wav") # or .WAV, .mp3, .MP3, etc. + ``` + +- If you have heightmaps in your assets use `--no_opt` to prevent png + recompression. + +- if you want to keep pixelated look whatever the device screen size is use: + + ```py + import sys, platform + if sys.platform == "emscripten": + platform.window.canvas.style.imageRendering = "pixelated" + ``` diff --git a/source/reference/pygbag-requirements.md b/source/reference/pygbag-requirements.md new file mode 100644 index 0000000..41048ed --- /dev/null +++ b/source/reference/pygbag-requirements.md @@ -0,0 +1,74 @@ +# pygbag Requirements + +## All Systems + +### Basics + +```{seealso} +[](../tutorials/simple-game-tutorial.md), [](../how-to/quick-start.md) +``` + +- Name your main game script `main.py` and put it in the root folder of your + game. +- Make your main loop async-aware and use `asyncio.sleep(0)` every iteration to + give control back to the main thread. +- Make sure all audio files are in OGG (best compression format targeting + 16bits 24Khz Mono). (that is especially **not in WAV/AIFF/M4A/MP3 + format**) +- Avoid raw formats like BMP for your image assets, they are too big for web + use; use PNG/WEBP or JPG instead. +- Filenames are case sensitive (`Folder/MyFile.png` and `folder/myfile.png` are + two different files). +- Do not use filenames like `*-pygbag.*`. That pattern is reserved for pygbag + internal use (optimizing pass). + +### 3D/WebGL + +- Use `--template noctx.tmpl` with pygbag command line if using 3D/WebGL. + +### Packages + +- When importing **non-stdlib** packages (for example, numpy or matplotlib), you + must put their import statements at top of `main.py`. If numpy is used, it + should come first. You should also add a metadata header as specified by + [PEP 723](https://peps.python.org/pep-0723/), such as: + + ```py + # /// script + # dependencies = [ + # "pygame-ce", + # "pyscroll", + # "pytmx", + # ] + # /// + ``` + + ```{seealso} + [https://packaging.python.org/en/latest/specifications/inline-script-metadata/#inline-script-metadata](https://packaging.python.org/en/latest/specifications/inline-script-metadata/#inline-script-metadata) + ``` + +- Avoid using CPython's standard library for web operations, GUI (like tkinter), + or I/O as it is very synchronous/platform-specific and will probably stay that + way. In terms of GUI alternatives, + [pygame_gui](https://pypi.org/project/pygame_gui) works on top of + [pygame-ce](https://pyga.me), [Panda3D](https://www.panda3d.org/) provides + [directgui](https://docs.panda3d.org/1.10/python/programming/gui/directgui/index) + and Harfang3D provides imgui. They are all cross-platform. + +## Windows + +- Use Python that was downloaded from python.org rather than the Windows Store. + You can check installed version(s) with the `py --list` command. +- Use `/` instead of `\​` as a path separator (e.g. `img/my_image.png` instead + of `img\my_image.png`). The path should still be valid on newer Windows + versions. + +## MacOS + +- If you get a SSL error, use the file `Install Certificates.command` in + `Applications/Python 3.XX`. + +## Linux + +- When using webusb ftdi serial emulation, use `sudo rmmod ftdi_sio` after + plugging devices. diff --git a/source/tutorials/index.md b/source/tutorials/index.md new file mode 100644 index 0000000..278b2d9 --- /dev/null +++ b/source/tutorials/index.md @@ -0,0 +1,8 @@ +# Tutorials + +Learning-oriented lessons that take you through a series of steps to complete a +project. Most useful when you want start learning pygbag from the ground up. + +```{toctree} +simple-game-tutorial +``` diff --git a/source/tutorials/pickup_coin.ogg b/source/tutorials/pickup_coin.ogg new file mode 100644 index 0000000..cc41786 Binary files /dev/null and b/source/tutorials/pickup_coin.ogg differ diff --git a/source/tutorials/simple-game-tutorial.md b/source/tutorials/simple-game-tutorial.md new file mode 100644 index 0000000..bb78862 --- /dev/null +++ b/source/tutorials/simple-game-tutorial.md @@ -0,0 +1,282 @@ +# Simple Game Tutorial + +```{seealso} +[](../reference/pygbag-requirements.md) +``` + +In this tutorial, you will create a simple game, with a focus on keeping it +compatible with pygbag. + +Because this website is dedicated to pygbag, we will gloss over details about +pygame development. To learn more about pygame itself, refer to a dedicated +tutorial such as from the pygame-ce [docs](https://pyga.me/docs/). + +## Part 1: A Moving Player + +Here's a simple pygame project that creates a player that can be moved around +the screen with the WASD keys. Save it somewhere on your computer, preferably in +its own folder. + +```py +# main.py +import pygame + +pygame.init() +screen = pygame.display.set_mode((1280, 720)) +clock = pygame.time.Clock() +running = True + +player_pos = pygame.Vector2(screen.get_width() / 2, screen.get_height() / 2) + +while running: + # pygame.QUIT event means the user clicked X to close your window + for event in pygame.event.get(): + if event.type == pygame.QUIT: + running = False + + screen.fill("white") + + pygame.draw.circle(screen, "black", player_pos, 40) + + keys = pygame.key.get_pressed() + if keys[pygame.K_w]: + player_pos.y -= 5 + if keys[pygame.K_s]: + player_pos.y += 5 + if keys[pygame.K_a]: + player_pos.x -= 5 + if keys[pygame.K_d]: + player_pos.x += 5 + + pygame.display.flip() + + clock.tick(60) + +pygame.quit() +``` + +```{note} +To use pygbag, you will need to do a little operating of the terminal (known +as cmd or Powershell on Windows). If you are unfamiliar with basic terminal +operations such as changing directories or using executables, you may consider +finding a dedicated tutorial. +``` + +Open your terminal and change your working directory to point to `main.py`. + +`````{hint} +````{tab} Unix/Mac +If your `main.py` is located at `~/Desktop/my-game/main.py`, use +```text +$ cd ~/Desktop/my-game +``` +```` + +````{tab} Windows +If your `main.py` is located at `C:\Users\yourname\Desktop\my-game\main.py`, use +```text +> cd C:\Users\yourname\Desktop\my-game +``` +```` +````` + +You'll notice that if we try to run our program right now, it might already +work! + +````{tab} Unix/Mac +```text +$ pygbag main.py +... +Serving HTTP on 127.0.0.1 port 8000 (http://localhost:8000/) ... +``` +```` + +````{tab} Windows +```batch +> pygbag main.py +... +Serving HTTP on 127.0.0.1 port 8000 (http://localhost:8000/) ... +``` +```` + +```{hint} +To try out the web version visit the given link +([http://localhost:8000/](http://localhost:8000/), above). To close out of +pygbag, type Ctrl-c in the terminal. +``` + +To guarantee it does, and will not break on future pygbag updates, we will +follow the pygbag [requirements](../reference/pygbag-requirements.md). + +Our game file is already named `main.py`, and is at the root of our game folder. +Let's also make sure our game is compatible with the web by making it +async-aware. + +```py +# main.py +import pygame +import asyncio # IMPORT ASYNCIO + + +async def main(): # CREATE AN ASYNC MAIN FUNCTION TO WRAP YOUR CODE + pygame.init() + screen = pygame.display.set_mode((1280, 720)) + clock = pygame.time.Clock() + running = True + + player_pos = pygame.Vector2(screen.get_width() / 2, screen.get_height() / 2) + + while running: + # pygame.QUIT event means the user clicked X to close your window + for event in pygame.event.get(): + if event.type == pygame.QUIT: + running = False + + screen.fill("white") + + pygame.draw.circle(screen, "black", player_pos, 40) + + keys = pygame.key.get_pressed() + if keys[pygame.K_w]: + player_pos.y -= 5 + if keys[pygame.K_s]: + player_pos.y += 5 + if keys[pygame.K_a]: + player_pos.x -= 5 + if keys[pygame.K_d]: + player_pos.x += 5 + + pygame.display.flip() + + clock.tick(60) + await asyncio.sleep(0) # GIVE CONTROL BACK TO THE BROWSER + + pygame.quit() + + +asyncio.run(main()) # RUN THE NEW MAIN FUNCTION +``` + +This `main.py` has been modified to be requirements-compliant. Running pygbag +now is guaranteed to work. + +````{tab} Unix/Mac +```text +$ pygbag main.py +... +Serving HTTP on 127.0.0.1 port 8000 (http://localhost:8000/) ... +``` +```` + +````{tab} Windows +```text +> pygbag main.py +... +Serving HTTP on 127.0.0.1 port 8000 (http://localhost:8000/) ... +``` +```` + +Doing so creates a `build` folder that holds the files generated for web. + +````{tab} Unix/Mac +```text +$ ls +build main.py +``` +```` + +````{tab} Windows +```text +> dir +... +build +main.py +... +``` +```` + +## Part 2: Coins and Audio + +Let's add the ability for our player character to grab a coin. To represent +this, every time we press the space bar, we should play a coin audio. + +Download this [coin audio](pickup_coin.ogg) (generated from https://sfxr.me/) +and put it in your game directory: + +````{tab} Unix/Mac +```text +$ ls +build main.py pickup_coin.ogg +``` +```` + +````{tab} Windows +```text +> dir +... +build +main.py +pickup_coin.ogg +... +``` +```` + +Now we can add the functionality to our game: + +```py +# main.py +import pygame +import asyncio + + +async def main(): + pygame.init() + screen = pygame.display.set_mode((1280, 720)) + clock = pygame.time.Clock() + running = True + + coin_sound = pygame.mixer.Sound("pickup_coin.ogg") # LOAD THE SOUND + + player_pos = pygame.Vector2(screen.get_width() / 2, screen.get_height() / 2) + + while running: + # pygame.QUIT event means the user clicked X to close your window + for event in pygame.event.get(): + if event.type == pygame.QUIT: + running = False + + screen.fill("white") + + pygame.draw.circle(screen, "black", player_pos, 40) + + keys = pygame.key.get_pressed() + if keys[pygame.K_w]: + player_pos.y -= 5 + if keys[pygame.K_s]: + player_pos.y += 5 + if keys[pygame.K_a]: + player_pos.x -= 5 + if keys[pygame.K_d]: + player_pos.x += 5 + if keys[pygame.K_SPACE]: # PLAY IT WHEN SPACE KEY PRESSED + pygame.mixer.Sound.play(coin_sound) + + pygame.display.flip() + + clock.tick(60) + await asyncio.sleep(0) + + pygame.quit() + + +asyncio.run(main()) +``` + +Notice how the sound format is an `ogg`. Other formats like `mp3` or `wav` will +not work on web. + +## Conclusion + +Making a pygame project async-aware and using only `ogg` formats for audio will +suffice to convert most simple projects to work with pygbag. Congrats on +finishing this tutorial! diff --git a/wiki/dinovm/README.md b/wiki/dinovm/README.md deleted file mode 100644 index 00d7bdd..0000000 --- a/wiki/dinovm/README.md +++ /dev/null @@ -1 +0,0 @@ -WIP