diff --git a/.github/workflows/jekyll-gh-pages.yml b/.github/workflows/mdbook.yml
similarity index 62%
rename from .github/workflows/jekyll-gh-pages.yml
rename to .github/workflows/mdbook.yml
index e31d81c..9d2f244 100644
--- a/.github/workflows/jekyll-gh-pages.yml
+++ b/.github/workflows/mdbook.yml
@@ -1,5 +1,8 @@
-# Sample workflow for building and deploying a Jekyll site to GitHub Pages
-name: Deploy Jekyll with GitHub Pages dependencies preinstalled
+# Sample workflow for building and deploying a mdBook site to GitHub Pages
+#
+# To get started with mdBook see: https://rust-lang.github.io/mdBook/index.html
+#
+name: Deploy mdBook site to Pages
on:
# Runs on pushes targeting the default branch
@@ -25,18 +28,26 @@ jobs:
# Build job
build:
runs-on: ubuntu-latest
+ env:
+ MDBOOK_VERSION: 0.4.36
steps:
- - name: Checkout
- uses: actions/checkout@v4
+ - uses: actions/checkout@v4
+ - name: Install mdBook and preprocessors
+ run: |
+ curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf -y | sh
+ rustup update
+ cargo install --version ${MDBOOK_VERSION} mdbook
+ cargo install mdbook-admonish
+ cargo install mdbook-pagetoc
- 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 mdBook
+ run: mdbook build
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
+ with:
+ path: ./book
# Deployment job
deploy:
diff --git a/.gitignore b/.gitignore
index a3816f7..42f62cc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,8 @@
/.idea
+# ignored generated pagetoc files from mdbook-pagetoc
+theme/pagetoc.css
+theme/pagetoc.js
+
# for local testing
-Gemfile.lock
-Gemfile
-.jekyll-metadata
-_site
+book
diff --git a/README.md b/README.md
index 08b3cc2..a8a80fc 100644
--- a/README.md
+++ b/README.md
@@ -4,142 +4,21 @@
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.
+## building the website
+To build this mdBook website, [install mdBook](https://rust-lang.github.io/mdBook/guide/installation.html)
+and run
```
-
-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"
+mdbook serve --open
```
+where the current directory contains `book.toml`.
-### 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)):
+To use the [pagetoc](https://github.com/slowsage/mdbook-pagetoc) and
+[admonishment](https://github.com/tommilligan/mdbook-admonish) preprocessors,
+you need to install some Rust tools:
```
-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:
+cargo install mdbook-pagetoc
+cargo install mdbook-admonish
```
-*.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)
+Without these tools, the book may not compile. They only provide helpful but
+nonessential rendering, so you comment out their respective section in the
+`book.toml`.
\ No newline at end of file
diff --git a/book.toml b/book.toml
new file mode 100644
index 0000000..806a9fe
--- /dev/null
+++ b/book.toml
@@ -0,0 +1,19 @@
+[book]
+authors = []
+language = "en"
+multilingual = false
+src = "src"
+
+[preprocessor.pagetoc]
+
+[preprocessor.admonish]
+command = "mdbook-admonish"
+assets_version = "3.0.3" # do not edit: managed by `mdbook-admonish install`
+
+[output.html]
+additional-css = ["theme/pagetoc.css", "./mdbook-admonish.css"]
+additional-js = ["theme/pagetoc.js"]
+no-section-label = true
+git-repository-url = "https://github.com/pygame-web/pygame-web.github.io"
+git-repository-icon = "fa-github"
+edit-url-template = "https://github.com/pygame-web/pygame-web.github.io/edit/main/{path}"
diff --git a/mdbook-admonish.css b/mdbook-admonish.css
new file mode 100644
index 0000000..88dd2b1
--- /dev/null
+++ b/mdbook-admonish.css
@@ -0,0 +1,351 @@
+@charset "UTF-8";
+:is(.admonition) {
+ display: flow-root;
+ margin: 1.5625em 0;
+ padding: 0 1.2rem;
+ color: var(--fg);
+ page-break-inside: avoid;
+ background-color: var(--bg);
+ border: 0 solid black;
+ border-inline-start-width: 0.4rem;
+ border-radius: 0.2rem;
+ box-shadow: 0 0.2rem 1rem rgba(0, 0, 0, 0.05), 0 0 0.1rem rgba(0, 0, 0, 0.1);
+}
+@media print {
+ :is(.admonition) {
+ box-shadow: none;
+ }
+}
+:is(.admonition) > * {
+ box-sizing: border-box;
+}
+:is(.admonition) :is(.admonition) {
+ margin-top: 1em;
+ margin-bottom: 1em;
+}
+:is(.admonition) > .tabbed-set:only-child {
+ margin-top: 0;
+}
+html :is(.admonition) > :last-child {
+ margin-bottom: 1.2rem;
+}
+
+a.admonition-anchor-link {
+ display: none;
+ position: absolute;
+ left: -1.2rem;
+ padding-right: 1rem;
+}
+a.admonition-anchor-link:link, a.admonition-anchor-link:visited {
+ color: var(--fg);
+}
+a.admonition-anchor-link:link:hover, a.admonition-anchor-link:visited:hover {
+ text-decoration: none;
+}
+a.admonition-anchor-link::before {
+ content: "§";
+}
+
+:is(.admonition-title, summary.admonition-title) {
+ position: relative;
+ min-height: 4rem;
+ margin-block: 0;
+ margin-inline: -1.6rem -1.2rem;
+ padding-block: 0.8rem;
+ padding-inline: 4.4rem 1.2rem;
+ font-weight: 700;
+ background-color: rgba(68, 138, 255, 0.1);
+ print-color-adjust: exact;
+ -webkit-print-color-adjust: exact;
+ display: flex;
+}
+:is(.admonition-title, summary.admonition-title) p {
+ margin: 0;
+}
+html :is(.admonition-title, summary.admonition-title):last-child {
+ margin-bottom: 0;
+}
+:is(.admonition-title, summary.admonition-title)::before {
+ position: absolute;
+ top: 0.625em;
+ inset-inline-start: 1.6rem;
+ width: 2rem;
+ height: 2rem;
+ background-color: #448aff;
+ print-color-adjust: exact;
+ -webkit-print-color-adjust: exact;
+ mask-image: url('data:image/svg+xml;charset=utf-8,');
+ -webkit-mask-image: url('data:image/svg+xml;charset=utf-8,');
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-size: contain;
+ content: "";
+}
+:is(.admonition-title, summary.admonition-title):hover a.admonition-anchor-link {
+ display: initial;
+}
+
+details.admonition > summary.admonition-title::after {
+ position: absolute;
+ top: 0.625em;
+ inset-inline-end: 1.6rem;
+ height: 2rem;
+ width: 2rem;
+ background-color: currentcolor;
+ mask-image: var(--md-details-icon);
+ -webkit-mask-image: var(--md-details-icon);
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-size: contain;
+ content: "";
+ transform: rotate(0deg);
+ transition: transform 0.25s;
+}
+details[open].admonition > summary.admonition-title::after {
+ transform: rotate(90deg);
+}
+summary.admonition-title::-webkit-details-marker {
+ display: none;
+}
+
+:root {
+ --md-details-icon: url("data:image/svg+xml;charset=utf-8,");
+}
+
+:root {
+ --md-admonition-icon--admonish-note: url("data:image/svg+xml;charset=utf-8,");
+ --md-admonition-icon--admonish-abstract: url("data:image/svg+xml;charset=utf-8,");
+ --md-admonition-icon--admonish-info: url("data:image/svg+xml;charset=utf-8,");
+ --md-admonition-icon--admonish-tip: url("data:image/svg+xml;charset=utf-8,");
+ --md-admonition-icon--admonish-success: url("data:image/svg+xml;charset=utf-8,");
+ --md-admonition-icon--admonish-question: url("data:image/svg+xml;charset=utf-8,");
+ --md-admonition-icon--admonish-warning: url("data:image/svg+xml;charset=utf-8,");
+ --md-admonition-icon--admonish-failure: url("data:image/svg+xml;charset=utf-8,");
+ --md-admonition-icon--admonish-danger: url("data:image/svg+xml;charset=utf-8,");
+ --md-admonition-icon--admonish-bug: url("data:image/svg+xml;charset=utf-8,");
+ --md-admonition-icon--admonish-example: url("data:image/svg+xml;charset=utf-8,");
+ --md-admonition-icon--admonish-quote: url("data:image/svg+xml;charset=utf-8,");
+}
+
+:is(.admonition):is(.admonish-note) {
+ border-color: #448aff;
+}
+
+:is(.admonish-note) > :is(.admonition-title, summary.admonition-title) {
+ background-color: rgba(68, 138, 255, 0.1);
+}
+:is(.admonish-note) > :is(.admonition-title, summary.admonition-title)::before {
+ background-color: #448aff;
+ mask-image: var(--md-admonition-icon--admonish-note);
+ -webkit-mask-image: var(--md-admonition-icon--admonish-note);
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-repeat: no-repeat;
+}
+
+:is(.admonition):is(.admonish-abstract, .admonish-summary, .admonish-tldr) {
+ border-color: #00b0ff;
+}
+
+:is(.admonish-abstract, .admonish-summary, .admonish-tldr) > :is(.admonition-title, summary.admonition-title) {
+ background-color: rgba(0, 176, 255, 0.1);
+}
+:is(.admonish-abstract, .admonish-summary, .admonish-tldr) > :is(.admonition-title, summary.admonition-title)::before {
+ background-color: #00b0ff;
+ mask-image: var(--md-admonition-icon--admonish-abstract);
+ -webkit-mask-image: var(--md-admonition-icon--admonish-abstract);
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-repeat: no-repeat;
+}
+
+:is(.admonition):is(.admonish-info, .admonish-todo) {
+ border-color: #00b8d4;
+}
+
+:is(.admonish-info, .admonish-todo) > :is(.admonition-title, summary.admonition-title) {
+ background-color: rgba(0, 184, 212, 0.1);
+}
+:is(.admonish-info, .admonish-todo) > :is(.admonition-title, summary.admonition-title)::before {
+ background-color: #00b8d4;
+ mask-image: var(--md-admonition-icon--admonish-info);
+ -webkit-mask-image: var(--md-admonition-icon--admonish-info);
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-repeat: no-repeat;
+}
+
+:is(.admonition):is(.admonish-tip, .admonish-hint, .admonish-important) {
+ border-color: #00bfa5;
+}
+
+:is(.admonish-tip, .admonish-hint, .admonish-important) > :is(.admonition-title, summary.admonition-title) {
+ background-color: rgba(0, 191, 165, 0.1);
+}
+:is(.admonish-tip, .admonish-hint, .admonish-important) > :is(.admonition-title, summary.admonition-title)::before {
+ background-color: #00bfa5;
+ mask-image: var(--md-admonition-icon--admonish-tip);
+ -webkit-mask-image: var(--md-admonition-icon--admonish-tip);
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-repeat: no-repeat;
+}
+
+:is(.admonition):is(.admonish-success, .admonish-check, .admonish-done) {
+ border-color: #00c853;
+}
+
+:is(.admonish-success, .admonish-check, .admonish-done) > :is(.admonition-title, summary.admonition-title) {
+ background-color: rgba(0, 200, 83, 0.1);
+}
+:is(.admonish-success, .admonish-check, .admonish-done) > :is(.admonition-title, summary.admonition-title)::before {
+ background-color: #00c853;
+ mask-image: var(--md-admonition-icon--admonish-success);
+ -webkit-mask-image: var(--md-admonition-icon--admonish-success);
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-repeat: no-repeat;
+}
+
+:is(.admonition):is(.admonish-question, .admonish-help, .admonish-faq) {
+ border-color: #64dd17;
+}
+
+:is(.admonish-question, .admonish-help, .admonish-faq) > :is(.admonition-title, summary.admonition-title) {
+ background-color: rgba(100, 221, 23, 0.1);
+}
+:is(.admonish-question, .admonish-help, .admonish-faq) > :is(.admonition-title, summary.admonition-title)::before {
+ background-color: #64dd17;
+ mask-image: var(--md-admonition-icon--admonish-question);
+ -webkit-mask-image: var(--md-admonition-icon--admonish-question);
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-repeat: no-repeat;
+}
+
+:is(.admonition):is(.admonish-warning, .admonish-caution, .admonish-attention) {
+ border-color: #ff9100;
+}
+
+:is(.admonish-warning, .admonish-caution, .admonish-attention) > :is(.admonition-title, summary.admonition-title) {
+ background-color: rgba(255, 145, 0, 0.1);
+}
+:is(.admonish-warning, .admonish-caution, .admonish-attention) > :is(.admonition-title, summary.admonition-title)::before {
+ background-color: #ff9100;
+ mask-image: var(--md-admonition-icon--admonish-warning);
+ -webkit-mask-image: var(--md-admonition-icon--admonish-warning);
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-repeat: no-repeat;
+}
+
+:is(.admonition):is(.admonish-failure, .admonish-fail, .admonish-missing) {
+ border-color: #ff5252;
+}
+
+:is(.admonish-failure, .admonish-fail, .admonish-missing) > :is(.admonition-title, summary.admonition-title) {
+ background-color: rgba(255, 82, 82, 0.1);
+}
+:is(.admonish-failure, .admonish-fail, .admonish-missing) > :is(.admonition-title, summary.admonition-title)::before {
+ background-color: #ff5252;
+ mask-image: var(--md-admonition-icon--admonish-failure);
+ -webkit-mask-image: var(--md-admonition-icon--admonish-failure);
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-repeat: no-repeat;
+}
+
+:is(.admonition):is(.admonish-danger, .admonish-error) {
+ border-color: #ff1744;
+}
+
+:is(.admonish-danger, .admonish-error) > :is(.admonition-title, summary.admonition-title) {
+ background-color: rgba(255, 23, 68, 0.1);
+}
+:is(.admonish-danger, .admonish-error) > :is(.admonition-title, summary.admonition-title)::before {
+ background-color: #ff1744;
+ mask-image: var(--md-admonition-icon--admonish-danger);
+ -webkit-mask-image: var(--md-admonition-icon--admonish-danger);
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-repeat: no-repeat;
+}
+
+:is(.admonition):is(.admonish-bug) {
+ border-color: #f50057;
+}
+
+:is(.admonish-bug) > :is(.admonition-title, summary.admonition-title) {
+ background-color: rgba(245, 0, 87, 0.1);
+}
+:is(.admonish-bug) > :is(.admonition-title, summary.admonition-title)::before {
+ background-color: #f50057;
+ mask-image: var(--md-admonition-icon--admonish-bug);
+ -webkit-mask-image: var(--md-admonition-icon--admonish-bug);
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-repeat: no-repeat;
+}
+
+:is(.admonition):is(.admonish-example) {
+ border-color: #7c4dff;
+}
+
+:is(.admonish-example) > :is(.admonition-title, summary.admonition-title) {
+ background-color: rgba(124, 77, 255, 0.1);
+}
+:is(.admonish-example) > :is(.admonition-title, summary.admonition-title)::before {
+ background-color: #7c4dff;
+ mask-image: var(--md-admonition-icon--admonish-example);
+ -webkit-mask-image: var(--md-admonition-icon--admonish-example);
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-repeat: no-repeat;
+}
+
+:is(.admonition):is(.admonish-quote, .admonish-cite) {
+ border-color: #9e9e9e;
+}
+
+:is(.admonish-quote, .admonish-cite) > :is(.admonition-title, summary.admonition-title) {
+ background-color: rgba(158, 158, 158, 0.1);
+}
+:is(.admonish-quote, .admonish-cite) > :is(.admonition-title, summary.admonition-title)::before {
+ background-color: #9e9e9e;
+ mask-image: var(--md-admonition-icon--admonish-quote);
+ -webkit-mask-image: var(--md-admonition-icon--admonish-quote);
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-repeat: no-repeat;
+}
+
+.navy :is(.admonition) {
+ background-color: var(--sidebar-bg);
+}
+
+.ayu :is(.admonition),
+.coal :is(.admonition) {
+ background-color: var(--theme-hover);
+}
+
+.rust :is(.admonition) {
+ background-color: var(--sidebar-bg);
+ color: var(--sidebar-fg);
+}
+.rust .admonition-anchor-link:link, .rust .admonition-anchor-link:visited {
+ color: var(--sidebar-fg);
+}
diff --git a/src/README.md b/src/README.md
new file mode 100644
index 0000000..c71a9a2
--- /dev/null
+++ b/src/README.md
@@ -0,0 +1,143 @@
+# pygame-web.github.io
+
+
+
+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
diff --git a/src/SUMMARY.md b/src/SUMMARY.md
new file mode 100644
index 0000000..a3ec81d
--- /dev/null
+++ b/src/SUMMARY.md
@@ -0,0 +1,25 @@
+# Summary
+
+[Get Started](README.md)
+
+# Reference Wiki
+
+- [Wiki Intro](wiki/README.md)
+ - [pygbag](wiki/pygbag/README.md)
+ - [pygbag-code](wiki/pygbag-code/README.md)
+ - [pygbag-configuration](wiki/pygbag-configuration/README.md)
+ - [pygbag-debug](wiki/pygbag-debug/README.md)
+ - [pygbag-internals](wiki/pygbag-internals/README.md)
+ - [pygbag-script](wiki/pygbag-script/README.md)
+ - [python-wasm](wiki/python-wasm/README.md)
+ - [dinovm](wiki/dinovm/README.md)
+ - [pkg](wiki/pkg/README.md)
+ - [nurses_2](wiki/pkg/nurses_2/README.md)
+ - [panda3d](wiki/pkg/panda3d/README.md)
+ - [publishing]()
+ - [github.io](wiki/publishing/github.io/README.md)
+ - [itch.io](wiki/publishing/itch.io/README.md)
+
+# Misc
+- [platform_wasm](platform_wasm/README.md)
+- [assets](assets/README.md)
\ No newline at end of file
diff --git a/assets/README.md b/src/assets/README.md
similarity index 100%
rename from assets/README.md
rename to src/assets/README.md
diff --git a/assets/pyg1.png b/src/assets/pyg1.png
similarity index 100%
rename from assets/pyg1.png
rename to src/assets/pyg1.png
diff --git a/assets/pyg2.png b/src/assets/pyg2.png
similarity index 100%
rename from assets/pyg2.png
rename to src/assets/pyg2.png
diff --git a/assets/pygbag_logo.png b/src/assets/pygbag_logo.png
similarity index 100%
rename from assets/pygbag_logo.png
rename to src/assets/pygbag_logo.png
diff --git a/platform_wasm/README.md b/src/platform_wasm/README.md
similarity index 100%
rename from platform_wasm/README.md
rename to src/platform_wasm/README.md
diff --git a/wiki/README.md b/src/wiki/README.md
similarity index 98%
rename from wiki/README.md
rename to src/wiki/README.md
index fb8fc03..390e477 100644
--- a/wiki/README.md
+++ b/src/wiki/README.md
@@ -109,6 +109,3 @@ Python WebAssembly at PyCon FR 2023 (in French):
- [WebAssembly/Python Discord Server](https://discord.gg/MCTM4xFDMK)
Thanks for reading and supporting pygame-ce and pygbag. These tools could not have existed without your support.
-
-
-[edit this page](https://github.com/pygame-web/pygame-web.github.io/edit/main/wiki/README.md)
diff --git a/wiki/dinovm/README.md b/src/wiki/dinovm/README.md
similarity index 100%
rename from wiki/dinovm/README.md
rename to src/wiki/dinovm/README.md
diff --git a/wiki/pkg/README.md b/src/wiki/pkg/README.md
similarity index 100%
rename from wiki/pkg/README.md
rename to src/wiki/pkg/README.md
diff --git a/wiki/pkg/nurses_2/README.md b/src/wiki/pkg/nurses_2/README.md
similarity index 100%
rename from wiki/pkg/nurses_2/README.md
rename to src/wiki/pkg/nurses_2/README.md
diff --git a/wiki/pkg/panda3d/README.md b/src/wiki/pkg/panda3d/README.md
similarity index 100%
rename from wiki/pkg/panda3d/README.md
rename to src/wiki/pkg/panda3d/README.md
diff --git a/wiki/publishing/github.io/README.md b/src/wiki/publishing/github.io/README.md
similarity index 90%
rename from wiki/publishing/github.io/README.md
rename to src/wiki/publishing/github.io/README.md
index eaabb8d..01eeb21 100644
--- a/wiki/publishing/github.io/README.md
+++ b/src/wiki/publishing/github.io/README.md
@@ -37,4 +37,4 @@ Finally, go back to "Actions" and run the "pages-build-deployment" action. Now y
-[contribute to this page](https://github.com/pygame-web/pygame-web.github.io/edit/main/wiki/pygbag/github.io/README.md)
+
diff --git a/wiki/publishing/github.io/actions.png b/src/wiki/publishing/github.io/actions.png
similarity index 100%
rename from wiki/publishing/github.io/actions.png
rename to src/wiki/publishing/github.io/actions.png
diff --git a/wiki/publishing/github.io/pages.png b/src/wiki/publishing/github.io/pages.png
similarity index 100%
rename from wiki/publishing/github.io/pages.png
rename to src/wiki/publishing/github.io/pages.png
diff --git a/wiki/publishing/github.io/pygbag.yml b/src/wiki/publishing/github.io/pygbag.yml
similarity index 100%
rename from wiki/publishing/github.io/pygbag.yml
rename to src/wiki/publishing/github.io/pygbag.yml
diff --git a/wiki/publishing/github.io/yml.png b/src/wiki/publishing/github.io/yml.png
similarity index 100%
rename from wiki/publishing/github.io/yml.png
rename to src/wiki/publishing/github.io/yml.png
diff --git a/wiki/publishing/itch.io/README.md b/src/wiki/publishing/itch.io/README.md
similarity index 92%
rename from wiki/publishing/itch.io/README.md
rename to src/wiki/publishing/itch.io/README.md
index a0ad6ca..e1dc79e 100644
--- a/wiki/publishing/itch.io/README.md
+++ b/src/wiki/publishing/itch.io/README.md
@@ -33,4 +33,4 @@ Though, if you are unable to do so, you can ask for help in the [pygame discord
-[contribute to this page](https://github.com/pygame-web/pygame-web.github.io/edit/main/wiki/pygbag/itch.io/README.md)
+
diff --git a/wiki/pygbag-code/README.md b/src/wiki/pygbag-code/README.md
similarity index 98%
rename from wiki/pygbag-code/README.md
rename to src/wiki/pygbag-code/README.md
index 9ad0213..97d027c 100644
--- a/wiki/pygbag-code/README.md
+++ b/src/wiki/pygbag-code/README.md
@@ -233,5 +233,5 @@ TODO
-[contribute to this page](https://github.com/pygame-web/pygame-web.github.io/edit/main/wiki/pygbag-code/README.md)
+
diff --git a/wiki/pygbag-configuration/README.md b/src/wiki/pygbag-configuration/README.md
similarity index 100%
rename from wiki/pygbag-configuration/README.md
rename to src/wiki/pygbag-configuration/README.md
diff --git a/wiki/pygbag-debug/README.md b/src/wiki/pygbag-debug/README.md
similarity index 100%
rename from wiki/pygbag-debug/README.md
rename to src/wiki/pygbag-debug/README.md
diff --git a/wiki/pygbag-internals/README.md b/src/wiki/pygbag-internals/README.md
similarity index 100%
rename from wiki/pygbag-internals/README.md
rename to src/wiki/pygbag-internals/README.md
diff --git a/wiki/pygbag-script/README.md b/src/wiki/pygbag-script/README.md
similarity index 94%
rename from wiki/pygbag-script/README.md
rename to src/wiki/pygbag-script/README.md
index 746a3aa..959168c 100644
--- a/wiki/pygbag-script/README.md
+++ b/src/wiki/pygbag-script/README.md
@@ -55,4 +55,4 @@ python3 -x index.html
~~follow that issue : https://github.com/psf/black/issues/3214~~
done, now you can use `black -x -l 132` to format your code
-[contribute to this page](https://github.com/pygame-web/pygame-web.github.io/edit/main/wiki/pygame-script/README.md)
+
diff --git a/wiki/pygbag/README.md b/src/wiki/pygbag/README.md
similarity index 98%
rename from wiki/pygbag/README.md
rename to src/wiki/pygbag/README.md
index ed9de73..0cf41bc 100644
--- a/wiki/pygbag/README.md
+++ b/src/wiki/pygbag/README.md
@@ -204,4 +204,4 @@ There is very little because Python-WASM is just a web-friendly version of CPyth
## Conclusion
Congratulations for finishing this tutorial! Now you can go ahead and make all your Python games playable in the browser! Thank you for reading.
-[Contribute to this page.](https://github.com/pygame-web/pygame-web.github.io/edit/main/wiki/pygbag/README.md)
+
diff --git a/wiki/python-wasm/README.md b/src/wiki/python-wasm/README.md
similarity index 91%
rename from wiki/python-wasm/README.md
rename to src/wiki/python-wasm/README.md
index 6c25c58..fcb04be 100644
--- a/wiki/python-wasm/README.md
+++ b/src/wiki/python-wasm/README.md
@@ -61,4 +61,4 @@ if __name__ == "__main__":
Everything else is probably specific to Pygbag. You can find more information/code [here](https://pygame-web.github.io/wiki/pygbag-code/#pygbag-code-specificssamples).
-[Contribute to this page](https://github.com/pygame-web/pygame-web.github.io/edit/main/wiki/python-wasm/README.md)
+