Publishing with pygbag

You’ve built a cool game and now you want to share it with the rest of the world. With pygbag you turn your Pygame game into a web page that anyone can play in the browser. No setup, no fuss. Just send a link and you’re done!

What is pygbag?

Pygbag compiles your Python code to WebAssembly and packs it with a small Pygame runtime that runs in the browser. The player doesn’t have to install anything: just open the page and play. That makes it perfect for sharing your game with friends, family or on itch.io.

Limitations

Pygbag does not work with Pgzero (the simplified library from the first sessions). You need real Pygame, so this is available from session 4 onwards.

On top of that, a few things don’t work in the browser:

  • No disk access: you can’t read or write files from inside the game.
  • No threads: don’t use threading or multiprocessing.
  • No blocking calls: everything has to run asynchronously (see below).

Installing

In a uv project:

uv add pygbag

Or in Thonny through the package manager:

pip install pygbag

Getting the project ready

Pygbag requires your main loop to be asynchronous. That means: your main function becomes async def main(), and in every frame iteration you add await asyncio.sleep(0). That one line gives the browser the chance to breathe between frames.

Below you’ll find a ready-made basic structure: Pygbag-ready structure for main.py:

import asyncio
import pygame

pygame.init()
screen = pygame.display.set_mode((640, 480))
clock = pygame.time.Clock()

async def main():
    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
        screen.fill((30, 30, 60))
        pygame.display.flip()
        clock.tick(60)
        await asyncio.sleep(0)  # required for pygbag

asyncio.run(main())

Adapt your own game code so everything sits inside async def main(), and don’t forget await asyncio.sleep(0) at the bottom of the while loop.

Building

In your terminal, go to the folder with main.py and run:

uv run python -m pygbag --build main.py

The output appears in the build/web/ folder. That folder contains everything you need to host your game.

Testing locally

Want to see whether it works before you publish? Use the same command without --build:

uv run python -m pygbag main.py

Pygbag starts a local web server on http://localhost:8000. Open that link in your browser and you play your own game, exactly the way others will see it.

Publishing

Once everything works, there are two ways to share your game:

  1. Through your coach: zip the build/web/ folder and give the zip file to your coach. They take care of the hosting.
  2. Through itch.io: make a free account on itch.io, create a new project as an HTML game, and upload the zip of build/web/. Within a few minutes your game has its own page that anyone can visit!

Congratulations! You’ve just published a real web game. 🎮