Quick answer: Pygame is a free, open-source Python library for writing 2D games, not a full game engine. Built on top of SDL, it gives you a window, a drawing surface, input handling, and sound — but there is no editor, no scene system, and no visual tools. You write the main loop, event handling, and the update/draw cycle yourself in Python, which makes it superb for learning how games work, teaching, prototyping, and game jams. For modern projects, use the actively maintained fork pygame-ce.

People search for "Pygame game engine," but the honest framing is more useful: Pygame is a Python library, a set of modules you import into your own program, not an engine you open and click around in. That distinction shapes everything about how you use it and what it is good for. This guide explains exactly what Pygame is, why it remains one of the best ways to learn game programming, how its core pieces — the game loop, surfaces, rects, and sprites — fit together, how it compares to a real engine like Godot, and where its limits (especially distribution) start to bite.

What is Pygame?

Pygame is a free, open-source Python library for writing 2D games and multimedia programs. It is a collection of modules — pygame.display, pygame.event, pygame.draw, pygame.mixer, and more — that you import into a normal Python program. Under the hood it wraps SDL (Simple DirectMedia Layer), the same battle-tested C library that powers countless commercial games, giving Python programs fast access to the screen, the keyboard and mouse, and the sound card.

Pygame was created by Pete Shinners and first released in 2000 as a successor to the older PySDL project. For more than two decades it has been a go-to tool for people learning to program games in Python, and it remains one of the most widely taught game libraries in classrooms and tutorials. It is deliberately small in scope: it gives you the raw materials to draw pixels, play sounds, and read input, and leaves the structure of the actual game entirely up to you.

Type
Free, open-source Python library for 2D games (not a full engine)
License
GNU LGPL (free, open source, usable in commercial games)
Built on
SDL (Simple DirectMedia Layer), a mature C multimedia library
First released
2000; modern recommended fork is pygame-ce (Community Edition)
Language
Python 3
Runs on
Windows, macOS, Linux (anywhere Python and SDL run)
Best for
Learning, teaching Python, prototyping, game jams, 2D experiments

Is Pygame a game engine or a library?

Pygame is a library, not a game engine — and the difference matters. A full engine like Godot or Unity hands you an application: a visual editor, a scene graph, an asset pipeline, a physics system, an animation system, and one-click export. You build games largely by arranging things in the editor and writing scripts that hook into the engine's machinery. Pygame gives you none of that. There is no editor to open, no scene to drag nodes into, and no built-in concept of a "game object." You get a window, a surface to draw on, an event queue, and a sound mixer — and you assemble everything else in plain Python.

So why do so many people search for it as a "game engine"? Partly habit: to a beginner, "the thing I use to make a game" is a game engine, regardless of the technical category. And partly because, in practice, you do end up writing an engine — your own small one — on top of Pygame. You write the main loop, you decide how objects update and draw, you build your own collision and state handling. That is the point. Pygame is the layer below an engine, and using it means you see and control the machinery that a full engine usually hides.

This is exactly why Pygame is so valuable for learning. When you have built your own game loop and watched frames tick by, the abstractions inside a real engine stop being magic. Many developers use Pygame as a stepping stone: learn the fundamentals here, then graduate to Godot or another engine for larger projects with the underlying concepts already in their bones.

Is Pygame free?

Yes — Pygame is completely free and open source. It is distributed under the GNU LGPL (Lesser General Public License), which is important for game developers for a specific reason. In practical terms:

For students, hobbyists, and indie developers, this cost model is ideal: nothing about your budget depends on how successful your game becomes. The only practical consideration is that if you ship a modified version of the Pygame library itself, the LGPL asks you to make those modifications available — but simply using the library in your game, which is what almost everyone does, carries no such obligation.

What can you build with Pygame?

Pygame is a 2D toolkit, and its strengths follow from that.

2D games of all kinds

Platformers, top-down shooters, roguelikes, puzzle games, tile-based RPGs, arcade clones, and visual novels are all squarely within Pygame's reach. You have direct pixel control, simple shape and image drawing, sprite management, and a sound mixer — everything a 2D game needs at the level of primitives.

Prototypes and game jam entries

Because there is no project setup ceremony — one Python file can be a complete game — Pygame is excellent for rapid prototyping and for the time pressure of a game jam. You can have a window with something moving in it within minutes.

Teaching and learning projects

Pygame is a fixture in introductory programming courses precisely because it forces the fundamentals into the open. Building Pong, Snake, or a Breakout clone in Pygame teaches loops, state, collision math, and input handling far more concretely than a higher-level engine would.

What it is not for

Pygame is not a 3D engine. It has no built-in 3D rendering, no scene editor, and no physics engine. You can bolt on OpenGL via PyOpenGL for 3D, or a physics library like Pymunk for 2D physics, but at that point you are integrating separate tools by hand. For 3D games or large productions, a full engine is the right call.

How Pygame works: the game loop

At the heart of every Pygame program is a loop you write yourself. Because Pygame does not run the game for you, the structure of your program is the structure of the game. Almost every Pygame game follows the same skeleton:

  1. Initialize Pygame and create a window (a display surface).
  2. Enter the game loop — a while loop that runs once per frame and keeps running until the player quits.
  3. Process events each frame: read the event queue (pygame.event.get()) for keypresses, mouse clicks, and the window-close (QUIT) event.
  4. Update the game state: move objects, run physics, check collisions, advance timers.
  5. Draw the frame: clear the screen, blit (copy) sprites and shapes onto the surface in order.
  6. Flip the display with pygame.display.flip() to show the freshly drawn frame, then tick the clock to cap the frame rate.

This "input, update, draw" cycle is the fundamental rhythm of all real-time games, and a full engine runs essentially the same loop internally — it just hides it behind callbacks like _process(). In Pygame the loop is right there in your code, which is why building one teaches you what an engine is actually doing.

Core concepts: surfaces, rects, and sprites

A handful of objects do most of the work in any Pygame program. Learn these five and you can read almost any Pygame tutorial.

Surface

A Surface is an image in memory — a rectangle of pixels you can draw onto. The window itself is a special surface (the display surface) returned by set_mode(). Loaded images are surfaces too. You compose a frame by blitting (copying) one surface onto another with surface.blit(image, position).

Rect

A Rect is a rectangle defined by position and size. Rects are how Pygame tracks where things are and whether they overlap. Almost every object's position is stored as a Rect, and collision detection is as simple as rect_a.colliderect(rect_b).

Event queue

Input arrives as a queue of events. Each frame you call pygame.event.get() and loop over the events, reacting to the ones you care about — most importantly the QUIT event so the window can close. For continuous movement you usually read held keys with pygame.key.get_pressed() instead.

Sprite and sprite.Group

The pygame.sprite module offers an optional, slightly higher-level structure: a Sprite bundles an image and a rect, and a sprite.Group manages a collection of sprites so you can update and draw them all with a single call. It is the closest thing Pygame has to "game objects," but it is still entirely opt-in.

Clock and tick

A pygame.time.Clock with clock.tick(60) caps your loop at a target frame rate (here, 60 FPS) so the game runs at a consistent speed across fast and slow machines. The tick() call also returns the elapsed time, which you can use for frame-rate-independent movement.

A real Pygame code sample

Here is a minimal but complete Pygame program: it initializes the library, opens a window, and runs the input-update-draw loop until the player closes it. This is the skeleton that every Pygame game grows from.

import pygame

# Initialize all the Pygame modules and open a window
pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("My First Pygame")
clock = pygame.time.Clock()

player = pygame.Rect(300, 220, 40, 40)
speed = 5
running = True

while running:
    # 1. Handle events (input)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    # 2. Update game state
    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT]:
        player.x -= speed
    if keys[pygame.K_RIGHT]:
        player.x += speed

    # 3. Draw the frame
    screen.fill((20, 30, 40))          # clear to a dark background
    pygame.draw.rect(screen, (120, 200, 150), player)

    # 4. Show it and cap the frame rate at 60 FPS
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

Notice how much you control directly: there is no hidden runtime starting the loop, no scene to configure, no inspector. You decide the window size, when the loop runs, what counts as input, how the player moves, and what gets drawn in which order. That transparency is Pygame's whole pedagogical appeal — and also why a larger project written this way needs careful structure, because Pygame imposes none for you.

Pygame vs pygame-ce

For new projects in 2026, prefer pygame-ce (Pygame Community Edition). The original Pygame project has had periods of intermittent maintenance, and a group of long-time contributors created pygame-ce as an actively developed fork. It is a drop-in replacement: it uses the same import name (import pygame) and the same API, so existing code and tutorials work unchanged. The difference is that pygame-ce ships bug fixes and new features more regularly and supports newer Python versions sooner.

Practically, the only thing that changes is what you install. Instead of pip install pygame, you run pip install pygame-ce; everything you type in your code still starts with import pygame. You should not install both into the same environment, since they provide the same module. When you read documentation or tutorials, treat the two as interchangeable in terms of API, and choose pygame-ce for the better-maintained foundation.

Platforms and distribution

Pygame runs anywhere Python and SDL run, which in practice means Windows, macOS, and Linux. The same script generally works across all three with no changes, which is one of Python's nice properties. The harder problem is not running your game during development — it is handing a finished game to someone who does not have Python installed.

Bundling a standalone build

To distribute a Pygame game to end users, you package your code, the Pygame library, and a Python interpreter into a single executable using a tool such as PyInstaller (or cx_Freeze / py2exe). This works, but it is more involved and more fragile than the one-click export of a native engine: builds are large (a Python interpreter ships inside each one), and you often have to fix asset paths and tune the build configuration per platform.

Mobile, web, and console

Be honest about the limits here. There is no first-class mobile export and no console support — those paths are limited and unofficial. For the web, the experimental pygbag project can compile Pygame games to WebAssembly so they run in a browser, but it comes with constraints and is not as polished as a native engine's web export. If reaching mobile, console, or the web reliably is central to your project, that is a strong signal to use a full engine instead of Pygame.

Pygame vs Godot vs a code-first option

The most useful comparison for Pygame is not against other engines head-to-head, but against the question "should I use a library or an engine at all?" Here is an honest breakdown across Pygame (a library), Godot (a full free engine), and a code-first framework like MonoGame (an engine-as-library middle ground).

FactorPygameGodotMonoGame (code-first)
CategoryPython library / frameworkFull game engine with editorCode-first framework (no editor)
Editor & toolsNone — you write everythingFull visual editor, scene systemNone — code only, build tooling
LanguagePythonGDScript, C#C#
Learning value (fundamentals)Very high — you build the loopModerate — engine hides plumbingHigh — you build the loop
2D / 3D2D onlyExcellent 2D and capable 3D2D and 3D (you assemble it)
DistributionHarder (PyInstaller; web via pygbag)One-click export to many targetsSolid desktop; some console paths
Best fitLearning, teaching, prototypes, jamsIndie 2D/3D, shipping commercial gamesCode-first devs shipping 2D/indie

Short version: reach for Pygame when the goal is to learn how games work, teach Python, or prototype quickly; reach for Godot when you want an editor, real tooling, and a smooth path to shipping across platforms; reach for a code-first framework like MonoGame when you love writing the loop yourself but need stronger distribution than Python easily offers.

How to install Pygame

Installing Pygame is a single pip command, but a few habits make it painless.

  1. Install Python 3 from python.org (or your OS package manager). Pygame requires Python 3.
  2. Create and activate a virtual environment so the library is scoped to your project: python -m venv venv then activate it.
  3. Install the actively maintained edition: pip install pygame-ce. (If you specifically need the original, use pip install pygame instead — but do not install both in one environment.)
  4. Verify it works by running the bundled demo: python -m pygame.examples.aliens. A little shoot-'em-up window confirms graphics, input, and sound are all functioning.

System requirements are trivial by modern standards — any machine that can run Python comfortably can run Pygame. If the demo opens and you can move and shoot, you are ready to write your own game.

How to make your first game in Pygame

Here is the shortest path from an empty file to a running, shareable game. None of these steps need anything beyond Python and Pygame.

  1. Install Python and Pygame. Set up Python 3 and run pip install pygame-ce inside a virtual environment, then confirm with python -m pygame.examples.aliens.
  2. Open a window. Call pygame.init(), create the display with pygame.display.set_mode((640, 480)), and set a caption. You now have a blank game window.
  3. Write the game loop. Add a while running loop that reads pygame.event.get(), handles the QUIT event, fills the screen, draws your objects, and calls pygame.display.flip() — exactly the skeleton in the code sample above.
  4. Handle input and movement. Read held keys with pygame.key.get_pressed(), move your player's Rect, and detect overlaps with colliderect to add walls, pickups, or enemies.
  5. Control the frame rate. Create a pygame.time.Clock and call clock.tick(60) once per frame so the game runs at a steady speed everywhere.
  6. Package and share. When it is playable, use PyInstaller to bundle your script, Pygame, and a Python interpreter into a standalone executable, or try pygbag for an experimental web build.

From there the loop is the same as in any project: add objects, update them, draw them, test, and iterate. Because everything lives in your own code, you can refactor freely — split sprites into classes, add a scene/state manager, and grow your own little engine as the game demands.

Pros and cons of Pygame

Strengths

  • Free and open source (LGPL), commercial-friendly
  • Pure Python — gentle on-ramp for beginners
  • Teaches the fundamentals: you write the game loop
  • Tiny, fast to start — one file can be a whole game
  • Mature and stable (especially via pygame-ce)
  • Great for prototypes, jams, and education
  • Cross-platform on Windows, macOS, and Linux

Trade-offs

  • Not a full engine — no editor or scene system
  • 2D only; no built-in 3D or physics
  • You build all structure yourself, which scales poorly
  • Distribution is clunky (PyInstaller, large builds)
  • Mobile/console export is limited and unofficial
  • Python performance ceiling for heavy real-time work
  • Few large commercial titles ship on raw Pygame

Games made with Pygame

It is worth being honest here: few big commercial hits ship on raw Pygame. The most cited example is Frets on Fire, an open-source music game that found a real audience, along with a long tail of indie, jam, and hobbyist titles distributed on itch.io. Where Pygame genuinely shines is not the storefront chart but the learning curve: countless developers built their first Snake, Pong, or platformer in Pygame, internalized how games work, and carried that understanding into engines like Godot or Unity. Its value is education, prototyping, jams, and fundamentals — not a portfolio of AAA releases, and that is fine, because that is what it is designed for.

Learning Pygame: a roadmap

A sensible path for a newcomer:

  1. Get a window with movement on screen first. Type out the code sample above, run it, and tweak the colors, sizes, and speeds until the loop feels concrete.
  2. Build Pong or Snake from scratch. These tiny games force you to handle input, movement, collision, and scoring — the whole loop in miniature.
  3. Adopt pygame.sprite. Refactor your objects into Sprite classes and a sprite.Group to learn the closest thing Pygame has to game objects.
  4. Add structure. Introduce a simple state manager (menu, playing, game over) and split your code into modules. This is where you start writing your own mini-engine.
  5. Ship something small. Package a finished mini-game with PyInstaller, put it on itch.io, and watch how it behaves on a machine that is not yours — the lesson no tutorial teaches.

If you build with Pygame, our Pygame solutions page walks through how to wire crash and bug reporting into a Python game, and the Bugnet blog covers focused fixes for common Python and Pygame pitfalls — from frame-rate drift to crashes that only appear in a packaged build. The official docs and tutorials at pygame.org remain the best single reference for the API itself.

Shipping a Pygame game: the part tutorials skip

Building the game is one thing; keeping it stable once real players have it is another — and Pygame makes this harder than a full engine because so much is your own code with no safety net. A Python game that runs perfectly in your editor can throw an unhandled exception on a player's machine the moment it hits an audio device you never tested, a save file in an unexpected state, or a code path that only fires after twenty minutes of play. In a packaged PyInstaller build, that exception often means the window simply vanishes, and all the player can tell you is "it crashed."

The bug you can't reproduce isn't gone — it's just invisible until you capture it from the player's machine.

The fix is to capture failures automatically from the player's machine. With the right reporting in place, each crash or unhandled exception arrives with its full Python traceback, the OS and hardware details, the build number, and a breadcrumb trail of what the player did right before it broke. Identical tracebacks fold into a single grouped issue ranked by how many players each one hits, so your worklist sorts itself worst-first instead of arriving as a stream of vague reports.

That is exactly what Bugnet does for Pygame games: a small SDK captures every unhandled exception with full context, groups duplicates by traceback, and ties each issue to the build it first appeared in — so you fix the problem that hurts the most players first and confirm it is gone when its signature disappears from the next release. It is the difference between guessing at a vague complaint and shipping a fix you can prove worked.

Compare other game engines

Still deciding? These companion guides go just as deep on the other major engines, and our hub compares them side by side:

Frequently asked questions

What is Pygame?

Pygame is a free, open-source Python library for writing 2D games and multimedia programs. It is a set of modules built on top of the SDL library that give you windowing, graphics, sound, and input handling. Pygame is not a full game engine: there is no editor, no scene system, and no visual tools. You write everything in Python code, including the main loop, event handling, and the update and draw cycle.

Is Pygame a game engine?

Not in the usual sense. Pygame is a library or framework, not an engine like Godot, Unity, or Unreal. It gives you the building blocks (a window, a drawing surface, an event queue, sound playback) but does not provide an editor, a scene graph, a physics system, or built-in game objects. People often call it a game engine because it is the tool they use to make games, but technically you write the engine yourself on top of it.

Is Pygame free?

Yes. Pygame is free and open source, distributed under the GNU LGPL license. You can use it in commercial games, charge money for the games you build with it, and keep all of your revenue. There are no fees, no subscriptions, and no royalties. Because it uses the LGPL rather than a more restrictive license, your own game code does not have to be open source.

What is pygame-ce?

pygame-ce (Pygame Community Edition) is an actively maintained, drop-in fork of the original Pygame. It uses the same import name and API, so existing code keeps working, but it ships fixes and new features more quickly. Because the original project's maintenance has been intermittent, pygame-ce is the recommended modern choice for new projects.

Is Pygame good for beginners?

Yes, Pygame is one of the best tools for learning how games work. Because you write the game loop, event handling, and rendering yourself in plain Python, you see exactly how the pieces fit together rather than relying on an editor. That makes it a favorite in classrooms and for teaching programming, and a great way to understand fundamentals before moving to a full engine.

Can you make 3D games with Pygame?

Pygame is designed for 2D games and is not a 3D engine. Its drawing primitives, sprites, and surfaces all work in two dimensions. You can integrate OpenGL through PyOpenGL for 3D rendering inside a Pygame window, but at that point you are writing low-level graphics code yourself. For 3D games, a dedicated engine like Godot or Unity is a far more practical choice.

How do you distribute a Pygame game?

You bundle your Python code, the Pygame library, and a Python interpreter into a standalone executable using a tool such as PyInstaller. This is more involved than the one-click export of native engines, and the resulting builds are larger. Mobile and console export are limited and unofficial; for experimental web and WebAssembly builds you can try pygbag. Be aware that distribution is one of Pygame's weaker areas compared with full engines.

Have any commercial games shipped with Pygame?

A few have, with Frets on Fire being the best-known example, but big commercial hits built on raw Pygame are rare. Pygame's real value is in education, prototyping, game jams, and understanding fundamentals rather than shipping large commercial titles. Most developers who learn on Pygame eventually move to a full engine for production-scale games.

Pick the tool that teaches you the most while you ship. Pygame won't run your game for you — and that is exactly why building one, and then keeping it stable in players' hands, teaches you what a game really is.