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?
- Is Pygame a game engine or a library?
- Is Pygame free?
- What can you build with Pygame?
- How Pygame works: the game loop
- Core concepts: surfaces, rects, sprites
- A real Pygame code sample
- Pygame vs pygame-ce
- Platforms and distribution
- Pygame vs Godot vs a code-first option
- How to install Pygame
- How to make your first game
- Pros and cons of Pygame
- Games made with Pygame
- Learning Pygame: a roadmap
- Shipping a Pygame game
- Compare other game engines
- Frequently asked questions
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:
- No purchase price, no subscription, no royalties. You install it with one command and use it forever, including in games you sell.
- Commercial use is allowed. You can charge money for games built with Pygame on Steam, itch.io, or anywhere else and keep 100% of the revenue.
- Your own code stays yours. The LGPL (as opposed to the stricter GPL) means that linking against Pygame does not force you to open-source your game's code. Your game can remain fully proprietary.
- The library itself is open. You can read the source, study how it works, and contribute fixes upstream.
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:
- Initialize Pygame and create a window (a display surface).
- Enter the game loop — a
whileloop that runs once per frame and keeps running until the player quits. - Process events each frame: read the event queue (
pygame.event.get()) for keypresses, mouse clicks, and the window-close (QUIT) event. - Update the game state: move objects, run physics, check collisions, advance timers.
- Draw the frame: clear the screen, blit (copy) sprites and shapes onto the surface in order.
- 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).
| Factor | Pygame | Godot | MonoGame (code-first) |
|---|---|---|---|
| Category | Python library / framework | Full game engine with editor | Code-first framework (no editor) |
| Editor & tools | None — you write everything | Full visual editor, scene system | None — code only, build tooling |
| Language | Python | GDScript, C# | C# |
| Learning value (fundamentals) | Very high — you build the loop | Moderate — engine hides plumbing | High — you build the loop |
| 2D / 3D | 2D only | Excellent 2D and capable 3D | 2D and 3D (you assemble it) |
| Distribution | Harder (PyInstaller; web via pygbag) | One-click export to many targets | Solid desktop; some console paths |
| Best fit | Learning, teaching, prototypes, jams | Indie 2D/3D, shipping commercial games | Code-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.
- Install Python 3 from python.org (or your OS package manager). Pygame requires Python 3.
- Create and activate a virtual environment so the library is scoped to your project:
python -m venv venvthen activate it. - Install the actively maintained edition:
pip install pygame-ce. (If you specifically need the original, usepip install pygameinstead — but do not install both in one environment.) - 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.
- Install Python and Pygame. Set up Python 3 and run
pip install pygame-ceinside a virtual environment, then confirm withpython -m pygame.examples.aliens. - Open a window. Call
pygame.init(), create the display withpygame.display.set_mode((640, 480)), and set a caption. You now have a blank game window. - Write the game loop. Add a
while runningloop that readspygame.event.get(), handles theQUITevent, fills the screen, draws your objects, and callspygame.display.flip()— exactly the skeleton in the code sample above. - Handle input and movement. Read held keys with
pygame.key.get_pressed(), move your player'sRect, and detect overlaps withcolliderectto add walls, pickups, or enemies. - Control the frame rate. Create a
pygame.time.Clockand callclock.tick(60)once per frame so the game runs at a steady speed everywhere. - 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:
- 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.
- Build Pong or Snake from scratch. These tiny games force you to handle input, movement, collision, and scoring — the whole loop in miniature.
- Adopt
pygame.sprite. Refactor your objects intoSpriteclasses and asprite.Groupto learn the closest thing Pygame has to game objects. - 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.
- 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:
- Best game engines for indie developers — the side-by-side comparison and decision guide.
- Godot game engine — free, open-source, great for 2D and indie.
- Unity game engine — the broad, asset-rich industry standard.
- Unreal Engine — best-in-class high-end 3D.
- GameMaker — fast, focused 2D development.
- Construct 3 — no-code, browser-based 2D.
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.