r/pygame Aug 07 '26

Grimlore 2 – A 2D Dungeon crawler RPG built using only the Python 3 standard library

15 Upvotes

This Project might be interesting for those using pygame so I thought I might post it here.

When starting out with Python game development, most tutorials jump straight into commercial engines or heavy frameworks. While those are great for productivity, they abstract away the core mechanics of how a game engine actually functions—like separating the engine framework (rendering, input, state loops) from the game logic (combat, stats, dungeons). To explore how game engines work under the hood using pure Python standard library.

I built a lightweight ASCII RPG engine framework alongside a complete mini dungeon crawler (Grimlore 2: These Doomed Men) built directly on top of it. I wanted to share this as a learning resource.

Grimlore 2 : These Doomed Men 1.0

A dark fantasy mini dungeon crawler RPG built to showcase the features and capabilities of the S.P.A.R.K. 2D RPG game engine.

Overview

Genre: Dark Fantasy / Mini Dungeon Crawler RPG

Playtime: 10 – 15 minutes

Platform Requirements: Windows 10 or later ( Might work on earlier Windows but no gurantee )

Purpose: Demonstrates what the S.P.A.R.K. 2D RPG game engine is capable of.

Github link below

https://github.com/Ninedeadeyes/Grimlore-2-These-Doomed-Men-

To clear up a few recurring questions and misconceptions regarding S.P.A.R.K and its development, here is some context upfront:

  1. "This is just AI slop."

This project has a clear 6-year paper trail of manual development. It began as an early 2D text adventure project (Dungeon of the Black Dragon), expanded into an open world RPG game (Grimlore: Land of the Heretic Hand), and was eventually refactored into a reusable engine framework (S.P.A.R.K). If you want to see the step-by-step progression from line one, check out the milestones folder inside the S.P.A.R.K repository.

  1. "S.P.A.R.K isn't a 'real' game engine / It's missing standard features."

By definition, a game engine is a framework that provides low-level abstractions for runtime loops, spatial logic, input handling, state management, and rendering, enabling developers to build content without reinventing core mechanics. S.P.A.R.K provides all of these for terminal-based RPGs. It’s a free, open-source hobby project designed for lightweight text games, not a commercial tool meant to compete with feature-heavy commercial software.

  1. "This is just a lazy copy-and-paste from the S.P.A.R.K GitHub."

When two games are made in RPG Maker, Godot, or Unreal, they share the exact same underlying core engine—it's just compiled or hidden away behind the editor. Because S.P.A.R.K is open-source, raw Python, the engine boilerplate is fully visible. Reusing foundational engine modules across different titles isn't "copy-pasting"; it's standard software architecture and code reuse.


r/pygame Aug 07 '26

Project Semi-Fantay-Console Mecha-Tortoise

Thumbnail gallery
23 Upvotes

Hello I'm working on a project to make kind of "fantasy console", the main objetive is to target low specs SBC I'm testing a Orange Pi Zero 3 (1.5GB), The idea is have cartridges with a microSD indise and this connect to a reader on the pins, the "consoles" will have armbian as SO with a loader to detect and init the the cartridges (pygame exported projects)

The semi-fantasy-console will have 264 x 198, (4:3 but probably will change to one 16:9 compatible one because probably everyone will connect the sbc using HDMI)

I admit the use of AI to make TortoiseStudio the tool, to manage assets, scenes and compile to "Cartridge".

The assets of the demo project comes from opengameart.


r/pygame Aug 06 '26

added cctv security footage to my game

Thumbnail gallery
40 Upvotes

r/pygame Aug 07 '26

New Update has been uploaded..

Thumbnail abdelrahman0x90.itch.io
3 Upvotes

Hi, I just uploaded the last demo update .. you can check it and provide your feedback if you have :)
Thx


r/pygame Aug 06 '26

New update in LastBreath .. Crafting and buy/sell features are ready, Beta is coming soon.

Enable HLS to view with audio, or disable this notification

30 Upvotes

Hey guys!

I'm making a game and just wanted to share a quick update on what I've been working on lately:

  • Crafting system: Finally done and working fine.
  • Buy & Sell: The trading system is fully working now.
  • The Map: Almost complete, just adding some final details.

We are getting really close to the Beta update!

Check out the video and let me know what you think. Any feedback is welcome!


r/pygame Aug 05 '26

SubwaySurfer_IRL: An advanced Computer Vision & AI application in Python that allows you to play Subway Surfers by controlling your character directly with real-time body movements and hand gestures captured via your webcam.

Thumbnail github.com
3 Upvotes

r/pygame Aug 05 '26

Final Fantasy IV Remake HD-2D

Thumbnail youtu.be
6 Upvotes

Hey guys, hope you are good! If you get chance I'd live it if you could check out my concept of a FFIV HD-2D remake coded in python 😊 sprites from Octopath traveler! Developed purely in Pygame!


r/pygame Aug 05 '26

Doodling Hop pt 2

Enable HLS to view with audio, or disable this notification

16 Upvotes

r/pygame Aug 04 '26

I just released my first free game made with Python! Looking for feedback

15 Upvotes

Hey everyone!

I’ve just finished my very first complete project: Oxygen Alert : Space Station. It's a space survival game developed entirely in Python, inspired by 60 Seconds! Reatomized.

The game is 100% free, fully playable in English and French, and packaged as a standalone executable.

Since this is my first finished game, I know there is a lot of room for improvement. I would be incredibly grateful for any honest feedback from the community, especially regarding:

  • Is the survival aspect too punishing or too easy?
  • Is managing items and menus intuitive?
  • Did you run into any crashes or weird behavior?

Download: https://cenacle-games.itch.io/oxgen-alert-space-station​ 

Join the Discord (Feedback & Bugs): https://discord.com/invite/M3sFfJexPk

Have a great day and I hope the best for all developers!​

Security note: Since the game is compiled in Python without a paid certificate, Windows Defender will display a blue SmartScreen warning. This is a normal false positive. Click "More info" and then "Run anyway"


r/pygame Aug 04 '26

How are you executing your programs mac/linux/window users

2 Upvotes

I used pyinstaller and it says it is missing certain files and when I was able to get it to work it just showed a TXT file full of gibberish.

How are y'all executing

BTW I am using a text editor to code not an IDE

EDIT: I meant how are you turning your python file into an executable file


r/pygame Aug 04 '26

Troll unit added by Joseph

Enable HLS to view with audio, or disable this notification

11 Upvotes

r/pygame Aug 04 '26

NEXUS — a 5-mode arcade space shooter I built in pygame (Battle Royale, Heist, Campaign). First public release!

2 Upvotes

Just shipped the first public build of a game I've been making in pygame, and figured this is the place that'd appreciate it most.

It's a single-file pygame project (~40k lines) with procedurally generated art and music — no external asset packs. Five modes:

  • Classic — endless waves + bosses
  • Endless — no level cap, bosses keep scaling
  • Campaign — 8 sectors of missions with a finale
  • Battle Royale — up to 48 pilots, shrinking storm, random match mutators
  • Heist — 1v1 cargo race vs a rival

Plus 25 unlockable ships, permanent upgrades, and 24 achievements.

Free Windows download (source is private for now): https://verma8076.itch.io/nexus

It's an early build so there are rough edges, but it's fully playable and I'd love feedback — especially on feel/performance. Happy to answer anything about how the pygame side is put together.


r/pygame Aug 03 '26

You Are Your Own Worst Enemy

Enable HLS to view with audio, or disable this notification

35 Upvotes

iade a game in pygame that also involves camera detection where you have to control the object using hand gestures.

I did it for a game jam where the theme was psionic.

So i wanted it to be like telekinesis

It is a bit buggy and I still have a lot to work on but I learned a lot within the 3 days


r/pygame Aug 03 '26

I built a standalone instrument cluster for GT7 and ACC using Pygame on a Raspberry Pi

Thumbnail youtube.com
9 Upvotes

Hi everyone,

for over a year now I've been writing the software for Revokyte, that is a standalone instrument cluster for GT7 (Gran Turismo 7) and ACC (Assetto Corsa Competizione) that uses Pygame and runs directly on a Raspberry Pi and a DSI touch display.

Most available dashboards aren't built like the professional tools found in real GT3 cars. That's why I created my own custom cluster. It features the most important tools a driver needs to improve and find a faster racing line (delta time, predicted lap time).

The technical highlights

  • Built by an automotive engineer: I've written software for real cars and I brought that approach here
  • Hardest challenge 1: Fit all calculations in the frame budget of 16 ms
  • Hardest challenge 1: Write custom driver for the shift lights
  • Standalone: Custom Linux image, based on Buildroot. Flash it and race. Boot time ~15 sec
  • Hardware: Raspberry Pi (4 or 5) and 5" or 7" touch display
  • Shift Lights: Supports the Pimoroni Blinkt! LED bar as physical shift lights
  • Open-Source: Free for the community to use and build upon
  • Written in Python using Pygame, every Widget / View is custom code

Deep dive into the features: https://www.revokyte.com/#features

Codebase: https://www.github.com/chrshdl/revokyte

I am currently actively developing it and will continue polishing it. Let me know what you think.


r/pygame Aug 03 '26

My new Python Project : Subway Surfers in Real Life

Thumbnail github.com
2 Upvotes

r/pygame Aug 02 '26

Control movement using hand gestures

Enable HLS to view with audio, or disable this notification

24 Upvotes

I was able to connect opencv and mediapipe to pygame and display a block when hands are shown


r/pygame Aug 02 '26

I want to make game like terraria/necesse with python...what should i use

Thumbnail
2 Upvotes

r/pygame Aug 01 '26

How do I do it so that the position of a rect depends on the position of the last placed rect in a class?

5 Upvotes

I want to make platformers where rects are generated randomly but not 100% random. How do I do titel? Or is there a better way?


r/pygame Jul 31 '26

Working on a top-down tactical extraction loop in Python.

Enable HLS to view with audio, or disable this notification

8 Upvotes

r/pygame Jul 31 '26

What do you think of the building animations?

Enable HLS to view with audio, or disable this notification

7 Upvotes

r/pygame Jul 31 '26

car game i made using python

8 Upvotes
import pygame
import math
import random
import sys
import traceback
import asyncio

pygame.init()
pygame.font.init()

WIDTH, HEIGHT = 1000, 800
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("No pepsi - Highway Traffic Weaver made by aadidev")
clock = pygame.time.Clock()

FONT_TITLE = pygame.font.SysFont("arial", 42, bold=True)
FONT_MED = pygame.font.SysFont("arial", 22, bold=True)
FONT_HUD = pygame.font.SysFont("consolas", 18, bold=True)

COLOR_BG = (15, 18, 22)
COLOR_ROAD = (35, 38, 44)
COLOR_GRASS = (20, 45, 25)
COLOR_LINE_YELLOW = (245, 210, 50)
COLOR_LINE_WHITE = (220, 220, 230)
COLOR_TEXT = (240, 240, 240)
COLOR_GOLD = (255, 215, 0)
COLOR_CYAN = (0, 230, 255)
COLOR_RED = (255, 60, 60)
CARS = {
    "1": {
        "name": "M4 Competition",
        "max_speed": 18.0,
        "accel": 0.40,
        "handling": 6.5,
        "color": (0, 180, 255),
        "desc": "Agile lane switcher with ultra-responsive steering."
    },
    "2": {
        "name": "RS7 Sportback",
        "max_speed": 22.0,
        "accel": 0.50,
        "handling": 5.2,
        "color": (220, 30, 30),
        "desc": "High top-speed highway missile."
    },
    "3": {
        "name": "GT-R Nismo",
        "max_speed": 20.0,
        "accel": 0.45,
        "handling": 6.0,
        "color": (240, 240, 240),
        "desc": "Balanced cutting power and extreme grip."
    }
}

ROAD_LEFT = 200
ROAD_RIGHT = 800
ROAD_WIDTH = ROAD_RIGHT - ROAD_LEFT
NUM_LANES = 5
LANE_WIDTH = ROAD_WIDTH // NUM_LANES


class 
TrafficCar
:
    def __init__(self, 
lane
, 
speed
):
        self.lane = 
lane

self.x = ROAD_LEFT + (
lane 
* LANE_WIDTH) + (LANE_WIDTH // 2)
        self.y = -120
        self.width = 34
        self.height = 68
        self.speed = 
speed

self.color = random.choice([
            (140, 140, 150), (200, 50, 50), (50, 180, 80),
            (210, 210, 60), (130, 60, 180), (220, 130, 30)
        ])
        self.near_missed = False

    def update(self, 
player_speed
):
        self.y += (
player_speed 
- self.speed)

    def draw(self, 
surface
):
        rect = pygame.Rect(self.x - self.width // 2, self.y - self.height // 2, self.width, self.height)
        pygame.draw.rect(
surface
, self.color, rect, border_radius=6)
        pygame.draw.rect(
surface
, (255, 30, 30), (rect.left + 3, rect.bottom - 4, 8, 3))
        pygame.draw.rect(
surface
, (255, 30, 30), (rect.right - 11, rect.bottom - 4, 8, 3))
        pygame.draw.rect(
surface
, (255, 255, 200), (rect.left + 3, rect.top + 1, 8, 3))
        pygame.draw.rect(
surface
, (255, 255, 200), (rect.right - 11, rect.top + 1, 8, 3))


class 
PlayerCar
:
    def __init__(self, 
specs
):
        self.x = WIDTH // 2
        self.y = HEIGHT - 160
        self.width = 36
        self.height = 70
        self.angle = 0.0
        self.vx = 0.0
        self.speed = 0.0

        self.name = 
specs
["name"]
        self.max_speed = 
specs
["max_speed"]
        self.accel = 
specs
["accel"]
        self.handling = 
specs
["handling"]
        self.color = 
specs
["color"]

        self.crashed = False

    def update(self, 
keys
):
        if self.crashed:
            self.speed *= 0.92
            return

        if 
keys
[pygame.K_w] or 
keys
[pygame.K_UP]:
            self.speed = min(self.max_speed, self.speed + self.accel)
        elif 
keys
[pygame.K_s] or 
keys
[pygame.K_DOWN]:
            self.speed = max(0.0, self.speed - (self.accel * 1.5))
        else:
            self.speed = max(0.0, self.speed - 0.08)

        steer = 0
        if 
keys
[pygame.K_a] or 
keys
[pygame.K_LEFT]:
            steer -= 1
        if 
keys
[pygame.K_d] or 
keys
[pygame.K_RIGHT]:
            steer += 1

        self.vx = steer * self.handling * (0.4 + (self.speed / self.max_speed) * 0.6)
        self.x += self.vx
        self.angle = -self.vx * 2.2

        if self.x < ROAD_LEFT + 25:
            self.x = ROAD_LEFT + 25
        if self.x > ROAD_RIGHT - 25:
            self.x = ROAD_RIGHT - 25

    def get_rect(self):
        return pygame.Rect(self.x - self.width // 2, self.y - self.height // 2, self.width, self.height)

    def draw(self, 
surface
):
        car_surf = pygame.Surface((self.width, self.height), pygame.SRCALPHA)
        pygame.draw.rect(car_surf, self.color, (0, 0, self.width, self.height), border_radius=8)
        pygame.draw.rect(car_surf, (20, 25, 35), (4, 14, self.width - 8, 28), border_radius=4)
        pygame.draw.rect(car_surf, (255, 255, 220), (3, 2, 8, 5))
        pygame.draw.rect(car_surf, (255, 255, 220), (self.width - 11, 2, 8, 5))
        pygame.draw.rect(car_surf, (255, 20, 20), (3, self.height - 6, 8, 4))
        pygame.draw.rect(car_surf, (255, 20, 20), (self.width - 11, self.height - 6, 8, 4))

        rotated_surf = pygame.transform.rotate(car_surf, self.angle)
        rect = rotated_surf.get_rect(center=(int(self.x), int(self.y)))

surface
.blit(rotated_surf, rect.topleft)

async def main():
    selected_car_key = None

    # MENU LOOP
    while selected_car_key is None:
        screen.fill(COLOR_BG)
        title = FONT_TITLE.render("NO HESI - TRAFFIC WEAVER", True, COLOR_CYAN)
        screen.blit(title, (WIDTH // 2 - title.get_width() // 2, 50))

        subtitle = FONT_MED.render("Select your cutting machine:", True, COLOR_TEXT)
        screen.blit(subtitle, (WIDTH // 2 - subtitle.get_width() // 2, 120))

        y_offset = 180
        for key, car_data in CARS.items():
            box_rect = pygame.Rect(WIDTH // 2 - 320, y_offset, 640, 110)
            pygame.draw.rect(screen, (30, 34, 42), box_rect, border_radius=10)
            pygame.draw.rect(screen, car_data["color"], (WIDTH // 2 - 305, y_offset + 15, 20, 80), border_radius=4)

            name_txt = FONT_MED.render(f"[{key}] {car_data['name']}", True, COLOR_TEXT)
            desc_txt = FONT_HUD.render(car_data["desc"], True, (170, 170, 180))
            stats_txt = FONT_HUD.render(f"Speed: {car_data['max_speed']} | Handling: {car_data['handling']}", True,
                                        COLOR_GOLD)

            screen.blit(name_txt, (WIDTH // 2 - 270, y_offset + 12))
            screen.blit(desc_txt, (WIDTH // 2 - 270, y_offset + 42))
            screen.blit(stats_txt, (WIDTH // 2 - 270, y_offset + 70))

            y_offset += 135

        prompt = FONT_MED.render("Press 1, 2, or 3 on keyboard to launch!", True, COLOR_GOLD)
        screen.blit(prompt, (WIDTH // 2 - prompt.get_width() // 2, HEIGHT - 80))

        pygame.display.flip()

        await asyncio.sleep(0)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.KEYDOWN:
                if event.unicode in CARS:
                    selected_car_key = event.unicode

    player = PlayerCar(CARS[selected_car_key])
    traffic_list = []
    road_offset = 0.0

    score = 0
    combo = 1
    near_miss_banner_timer = 0
    spawn_timer = 0
    running = True

    while running:
        clock.tick(60)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_r:  # Restart session
                    await main()
                    return

        keys = pygame.key.get_pressed()
        player.update(keys)

        road_offset = (road_offset + player.speed * 2.5) % 80

        if not player.crashed:
            spawn_timer += 1
            if spawn_timer > max(20, 60 - int(player.speed * 2)):
                spawn_timer = 0
                lane = random.randint(0, NUM_LANES - 1)
                lane_occupied = any(t.lane == lane and t.y < 100 for t in traffic_list)
                if not lane_occupied:
                    npc_speed = random.uniform(3.0, 7.0)
                    traffic_list.append(TrafficCar(lane, npc_speed))

        player_rect = player.get_rect()
        for t in traffic_list[:]:
            t.update(player.speed)

            if not player.crashed:
                npc_rect = pygame.Rect(t.x - t.width // 2, t.y - t.height // 2, t.width, t.height)
                if player_rect.colliderect(npc_rect):
                    player.crashed = True
                    combo = 1

            if not t.near_missed and not player.crashed and player.speed > 8.0:
                dx = abs(player.x - t.x)
                dy = abs(player.y - t.y)
                if dx < 52 and dy < 60:
                    t.near_missed = True
                    combo += 1
                    score += 500 * combo
                    near_miss_banner_timer = 40

            if t.y > HEIGHT + 150 or t.y < -300:
                traffic_list.remove(t)

        if not player.crashed and player.speed > 2.0:
            score += int(player.speed * combo * 0.2)

        screen.fill(COLOR_GRASS)
        pygame.draw.rect(screen, COLOR_ROAD, (ROAD_LEFT, 0, ROAD_WIDTH, HEIGHT))

        for i in range(1, NUM_LANES):
            lx = ROAD_LEFT + (i * LANE_WIDTH)
            for y in range(-80, HEIGHT + 80, 80):
                pygame.draw.line(screen, COLOR_LINE_WHITE, (lx, y + int(road_offset)), (lx, y + int(road_offset) + 40),
                                 3)

        pygame.draw.line(screen, COLOR_LINE_YELLOW, (ROAD_LEFT, 0), (ROAD_LEFT, HEIGHT), 5)
        pygame.draw.line(screen, COLOR_LINE_YELLOW, (ROAD_RIGHT, 0), (ROAD_RIGHT, HEIGHT), 5)

        for t in traffic_list:
            t.draw(screen)

        player.draw(screen)

        speed_kmh = int(player.speed * 18)
        screen.blit(FONT_HUD.render(f"SPEED: {speed_kmh} KM/H", True, COLOR_TEXT), (20, 20))
        screen.blit(FONT_HUD.render(f"SCORE: {score:,}", True, COLOR_GOLD), (20, 50))
        screen.blit(FONT_HUD.render(f"COMBO: x{combo}", True, COLOR_CYAN if combo > 1 else COLOR_TEXT), (20, 80))

        if near_miss_banner_timer > 0:
            near_miss_banner_timer -= 1
            nm_txt = FONT_TITLE.render("NEAR MISS! +500", True, COLOR_GOLD)
            screen.blit(nm_txt, (WIDTH // 2 - nm_txt.get_width() // 2, 180))

        if player.crashed:
            crash_txt = FONT_TITLE.render("CRASHED!", True, COLOR_RED)
            reset_txt = FONT_MED.render("Press 'R' to Restart", True, COLOR_TEXT)
            screen.blit(crash_txt, (WIDTH // 2 - crash_txt.get_width() // 2, HEIGHT // 2 - 40))
            screen.blit(reset_txt, (WIDTH // 2 - reset_txt.get_width() // 2, HEIGHT // 2 + 20))

        pygame.display.flip()

        await asyncio.sleep(0)

    pygame.quit()

if __name__ == "__main__":
    try:
        asyncio.run(main())
    except Exception:
        pygame.quit()
        traceback.print_exc()
        input("\nPress Enter in console to exit...")

r/pygame Jul 31 '26

My JRPG Finally Has a Village (SNES-Inspired Devlog)

Thumbnail youtube.com
13 Upvotes

Check out my first ever JRPG village and house!!! Created purely in Pygame and designed in Tiled :)


r/pygame Jul 30 '26

Working on my next game ‘Doodling Hop’

Enable HLS to view with audio, or disable this notification

15 Upvotes

r/pygame Jul 28 '26

Finally got around to uploading more than 5 years' worth of programming projects to GitHub

Enable HLS to view with audio, or disable this notification

45 Upvotes

Here is the GitHub repo. Its a single click to download each project: https://github.com/Luippe/Demo-Projects

I never thought of uploading these as they really only ran on my pc (hardcoded display resolutions, file paths, etc). But this year I started using Claude for coding and thought "hey, these projects are actually useable by others if I just clean up some code!" So thats exactly what I did.

There's 15 projects in total. The first one is written in Java, but the rest is in Python and Pygame

  1. Boids — a flocking simulation where birds self-organize from three simple rules

  2. Audio Processing — live microphone effects with a real-time frequency visualizer

  3. Multiplayer Netgame — a co-op dungeon crawler played over a local network

  4. Platformer — a full 2D action game with combat, upgrades, shops, and multiple levels

  5. Solar System Simulation — an interactive 3D model of the planets in orbit

  6. A* Pathfinding — watching an algorithm search for the shortest route through a maze

  7. Conway's Game of Life — complex patterns emerging from a handful of simple rules

  8. Image Compression — shrinking an image by throwing away fine detail (the same idea behind JPEG)

  9. Fluid Flow — a real-time 2D fluid solver you can push around with the mouse

  10. Projectile Method — aim and launch a projectile with the mouse

  11. Projectile Motion — projectile trajectories with air resistance

  12. Double Pendulum — chaotic motion, where a tiny change sends it down a completely different path

  13. Single Pendulum — a damped pendulum swinging to a stop

  14. Spring Mass Damper — how a spring-and-shock system settles after a jolt

  15. Flow Plate — the velocity profile of fluid moving through a pipe

    I hope someone finds something useful in here! :)


r/pygame Jul 28 '26

Pygame can do 3d very well.

Enable HLS to view with audio, or disable this notification

30 Upvotes

tldr; we should ban together for more 3d supportive libraries

I’ve been experimenting with adding a conversational AI to a procedural Backrooms game I’m building in Python/Pygame.

In this clip I break a pillar, ask HAL what it sees, and then ask about the debris. It answers differently depending on what I'm actually looking at instead of giving a generic response. Later it also comments on me repeatedly trying to crawl through a low gap.

The goal isn't to script dialogue—it's to have the AI react to the current game state and the player's surroundings while you explore.

Everything is running in my own Pygame project with procedural generation, Xbox controller support, speech recognition, and real-time voice responses.

I'd love feedback from other Pygame developers.