{"id":13678306,"url":"https://github.com/pygame-web/pygbag","last_synced_at":"2026-04-06T07:01:52.142Z","repository":{"id":37410494,"uuid":"485952570","full_name":"pygame-web/pygbag","owner":"pygame-web","description":"python and pygame wasm for everyone ( packager + test server + simulator )","archived":false,"fork":false,"pushed_at":"2026-03-17T18:36:03.000Z","size":1175026,"stargazers_count":487,"open_issues_count":63,"forks_count":58,"subscribers_count":5,"default_branch":"main","last_synced_at":"2026-03-18T07:58:08.002Z","etag":null,"topics":["game-engine-2d","gamedev","pygame","pygame-wasm","python","wasm","webassembly","webassembly-python"],"latest_commit_sha":null,"homepage":"https://github.com/pygame-web","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pygame-web.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":"support/__EMSCRIPTEN__-pymain.c","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"open_collective":"pythonseverywhere","liberapay":"pmp-p"}},"created_at":"2022-04-26T21:26:32.000Z","updated_at":"2026-03-17T18:28:14.000Z","dependencies_parsed_at":"2023-09-26T06:54:03.901Z","dependency_job_id":"e1f668d4-59ae-418a-8cb7-0f4eb294b4e7","html_url":"https://github.com/pygame-web/pygbag","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/pygame-web/pygbag","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pygame-web%2Fpygbag","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pygame-web%2Fpygbag/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pygame-web%2Fpygbag/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pygame-web%2Fpygbag/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pygame-web","download_url":"https://codeload.github.com/pygame-web/pygbag/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pygame-web%2Fpygbag/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31463015,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-05T21:22:52.476Z","status":"online","status_checked_at":"2026-04-06T02:00:07.287Z","response_time":112,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["game-engine-2d","gamedev","pygame","pygame-wasm","python","wasm","webassembly","webassembly-python"],"created_at":"2024-08-02T13:00:52.254Z","updated_at":"2026-04-06T07:01:52.136Z","avatar_url":"https://github.com/pygame-web.png","language":"Python","funding_links":["https://opencollective.com/pythonseverywhere","https://liberapay.com/pmp-p"],"categories":["Python","Gameplay Systems"],"sub_categories":[],"readme":"# pygbag\n\nIt's ...\n\nPython WebAssembly for everyone ( packager + test server ) episode 2\n\nIntro : [https://github.com/pygame-web](https://github.com/pygame-web)\n\nCommunity Documentation : [https://pygame-web.github.io](https://pygame-web.github.io)\n\nRuns python code directly in modern web browsers, including mobile versions.\n\n\nQuick Start:\n\n\"your.app.folder\" must contain a main.py and its loop must be async aware eg:\n\n```py\nimport asyncio\n\n# Try to declare all your globals at once to facilitate compilation later.\nCOUNT_DOWN = 3\n\n# Do init here\n# Load any assets right now to avoid lag at runtime or network errors.\n\n\nasync def main():\n    global COUNT_DOWN\n\n    # avoid this kind declaration, prefer the way above\n    COUNT_DOWN = 3\n\n    while True:\n\n        # Do your rendering here, note that it's NOT an infinite loop,\n        # and it is fired only when VSYNC occurs\n        # Usually 1/60 or more times per seconds on desktop\n        # could be less on some mobile devices\n\n        print(f\"\"\"\n\n            Hello[{COUNT_DOWN}] from Python\n\n\"\"\")\n        # pygame.display.update() should go right next line\n\n        await asyncio.sleep(0)  # Very important, and keep it 0\n\n        if not COUNT_DOWN:\n            return\n\n        COUNT_DOWN = COUNT_DOWN - 1\n\n# This is the program entry point:\nasyncio.run(main())\n\n# Do not add anything from here, especially sys.exit/pygame.quit\n# asyncio.run is non-blocking on pygame-wasm and code would be executed\n# right before program start main()\n```\n\nUsage:\n\n    pip3 install pygbag --user --upgrade\n    pygbag your.app.folder\n\nCommand help:\n\n    pygbag --help your.app.folder\n\n\nExample :\n\n```\nuser@pp /data/git/pygbag $ py -m pygbag --help test/main.py\n *pygbag 0.8.2*\n115: cache 0.7.2 mismatch, want 0.8.2, cleaning ...\n\nServing python files from [/data/git/pygbag/test/build/web]\n\nwith no security/performance in mind, i'm just a test tool : don't rely on me\nusage: __main__.py [-h] [--bind ADDRESS] [--PYBUILD PYBUILD] [--app_name APP_NAME] [--ume_block UME_BLOCK] [--can_close CAN_CLOSE] [--cache CACHE] [--package PACKAGE] [--title TITLE] [--version VERSION] [--build] [--html] [--no_opt] [--archive] [--icon ICON] [--cdn CDN] [--template TEMPLATE] [--ssl SSL]\n                   [--port [PORT]] [--disable-sound-format-error]\n\noptions:\n  -h, --help            show this help message and exit\n  --bind ADDRESS        Specify alternate bind address [default: localhost]\n  --PYBUILD PYBUILD     Specify python version [default:3.11]\n  --app_name APP_NAME   Specify user facing name of application [default:test]\n  --ume_block UME_BLOCK\n                        Specify wait for user media engagement before running [default:1]\n  --can_close CAN_CLOSE\n                        Specify if window will ask confirmation for closing [default:0]\n  --cache CACHE         md5 based url cache directory\n  --package PACKAGE     package name, better make it unique\n  --title TITLE         App nice looking name\n  --version VERSION     override prebuilt version path [default:0.8.2]\n  --build               build only, do not run test server\n  --html                build as html with embedded assets (pygame-script)\n  --no_opt              turn off assets optimizer\n  --archive             make build/web.zip archive for itch.io\n  --icon ICON           icon png file 32x32 min should be favicon.png\n  --cdn CDN             web site to cache locally [default:https://pygame-web.github.io/archives/0.8/]\n  --template TEMPLATE   index.html template [default:default.tmpl]\n  --ssl SSL             enable ssl with server.pem and key.pem\n  --port [PORT]         Specify alternate port [default: 8000]\n  --disable-sound-format-error   audio files with a common unsupported format found in the assets won't raise an exception\n```\n\nunlisted developper options:\n\n    --git               force cdn use of pygbag current git github CI build\n    --dev               change port to 8666 and use local build served on 8000\n\n\n\nNow navigate to http://localhost:8000 with a modern internet browser.\n\nUse http://localhost:8000?-i# for getting a terminal with repl\n and a downsized canvas ( -i replaces http://localhost:8000#debug that did the same in earlier versions )\n\n\nUrl as a command line:\n\nafter ? and before the # are Python arguments or KEY=VALUE env vars separated by \u0026\n\nafter the # the program name or program arguments all space \" \" separated ( coded as %20 in HTML urls )\n\n\neg to Python 3.14 to run src/test_raylib.py on showroom server with only 1 rabbit and os.environ['KEY']==value call\n https://pygame-web.github.io/showroom/0.9.3.html?cpython3.14\u0026-i\u0026KEY=VALUE#src/test_raylib.py%201\n\n\nFor pygame-script go to http://localhost:8000/test.html\n( for a game folder named \"test\" with option --html )\n\n\nV8 based browsers are preferred ( chromium/brave/chrome ... )\nstarting with 81.0.4044 ( android 4.4 ).\nBecause they set baseline restrictions on WebAssembly loading.\nUsing them while testing ensure proper operation on all browsers\n\nif targeting mobile safari, always best not to play any sound on start of your program and add --ume_block 0 to pygbag command line\n\n\n____\n\n\nNOTES:\n - pygbag only provides support for pygame-ce ( pygame community edition )\n\n - safari/chrome mobile will not run until version ios 15.x. Regarding iOS: This project is tested with BrowserStack when possible.\n\n - first load will be slower, because setting up local cache from cdn to avoid\nuseless network transfer for getting pygame and cpython prebuilts.\n\n - each time there's a major change in the code/assets/template\nyou must run `pygbag your.app.folder` but\ncache will not be destroyed to save bandwidth.\n\n - if you want to reset prebuilts cache, remove the build/web-cache folder in\nyour.app.folder\n\n - pyodide wheels (non-standard wasm) aren't compatible ootb with pygbag runtime\n\n\nHISTORY:\n\n - pygbag's concepts took roots in a 2016 Panda3D community experiment based on custom python2.7 and asm.js (episode 1).\n\n\nBUILDING:\n\nPygbag is not only a python module and its python runtimes are stored online !\nRebuilding all the toolchain can be quite hard.\n\nhttps://github.com/pygame-web/python-wasm-sdk  \u003c= build CPython (not pyodide)\n\nThe default is to build only pygame, but feel free to fork and add yours.\n\nSo read/use pygbag CI to see how to build pygame + the C loader (pymain) and\nhow it is linked it to libpython.\nFor modules loading since 0.6 the default is to use wasm dynamic libraries.\n[wasm wheels info here](https://github.com/pygame-web/pkg-porting-wasm)\n\nhttps://github.com/pygame-web/pygbag\n\nDefault prebuilts CPython + pygame-ce used by pygbag are stored via github pages\nfrom the repo https://github.com/pygame-web/archives under versioned folders.\n\n\n[TEST INTERACTIVE REPL 3.12 (default)](http://pygame-web.github.io/showroom/0.9.3.html?cpython312\u0026-i\u0026noapp#src/hello.py%20arg1%20arg2)\n\n[TEST INTERACTIVE REPL 3.13 (transition)](http://pygame-web.github.io/showroom/0.9.3.html?cpython313\u0026-i\u0026noapp#src/hello.py%20arg1%20arg2)\n\n[TEST INTERACTIVE REPL 3.14 (next)](http://pygame-web.github.io/showroom/0.9.3.html?cpython314\u0026-i\u0026noapp#src/hello.py%20arg1%20arg2)\n\n\nADDING STATIC/DYNAMIC MODULES:\n\n    see in package.d directory and use vendor/vendor.sh\n\n\nSUPPORT FOR STATIC/DYNAMIC MODULES:\n\n    see in package.d/\u003cvendor\u003e/README.md for module \u003cvendor\u003e specific support\n\n\n____\n\n[vendor readme (if applicable)](vendor/README.md)\n\n\nGENERIC PYGBAG SUPPORT OR PYGAME MODULE:\n\n[for generic help around pygbag](https://github.com/pygame-web/pygbag/blob/main/packages.d/pygame/README.md)\n\nGENERIC CPYTHON WASM:\n\n[python.org forum](https://discuss.python.org/c/webassembly/28)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpygame-web%2Fpygbag","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpygame-web%2Fpygbag","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpygame-web%2Fpygbag/lists"}