Skip to content

Development#4817

Open
hrabanazviking wants to merge 31 commits into
pygame:mainfrom
hrabanazviking:development
Open

Development#4817
hrabanazviking wants to merge 31 commits into
pygame:mainfrom
hrabanazviking:development

Conversation

@hrabanazviking
Copy link
Copy Markdown

No description provided.

hrabanazviking and others added 30 commits April 5, 2026 16:07
Full phased roadmap (Phase 0-7): documentation/vibe coding foundation,
bug hardening, cross-platform, AI integration, 3D, VR, internal API
architecture, and modern game engine features. Covers 50+ sub-phases.
Target: H.E.R.E.T.I.C. game engine foundation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ARCHITECTURE.md: complete 29-section master codebase reference with
mermaid diagrams for all major systems (slot API, game loop, surface
blit pipeline, event filter, display flip path, SDL2 integration map,
memory model, thread model, init/quit lifecycle, and extension points).

Per-file structure docs created (docs/structure/):
  base_c.md     — init/quit/slot API/buffer protocol
  display_c.md  — set_mode/flip/GL/renderer pipeline
  surface_c.md  — Surface type, blit pipeline, blend modes, locking
  event_c.md    — event filter, custom events, unicode tracking
  draw_c.md     — Bresenham, Wu's AA, scanline fill, rounded rect
  transform_c.md — scale/rotate/smoothscale/threshold/scale2x
  rect_c.md     — Rect type, Cohen-Sutherland clipline, collision
  color_c.md    — Color type, HSV/HSL/CMY/I1I2I3 color spaces

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
image_c.md      — load/save pipeline, frombuffer, SDL2_image integration
mixer_c.md      — Sound/Channel/Music, audio architecture, SDL2_mixer
font_c.md       — pygame.font (SDL_ttf) + pygame.freetype (FreeType2 direct)
key_mouse_joystick_c.md — input systems, relative mode, instance IDs, hats
mask_c.md       — bitmask collision, connected components, from_surface
math_c.md       — Vector2/3/4, slerp, elementwise proxy, polar/spherical
time_c.md       — Clock, tick, set_timer, wait vs delay precision notes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Phase 0A: ARCHITECTURE.md
— 29-section master reference (4600+ lines)
— Mermaid diagrams: slot API, game loop, surface blit pipeline,
  event filter, display flip, SDL2 integration, memory model,
  thread model, init/quit lifecycle, 3D/VR/AI extension points

Phase 0B: docs/structure/ — 23 per-file structure documents
  simd_blitters.md   — SSE2/AVX2/scalar blit paths, runtime detection
  pixel_systems.md   — PixelArray, pixelcopy, BufferProxy, surfarray
  scrap_c.md         — clipboard: Win32/X11/macOS/SDL2 implementations
  sprite_py.md       — Sprite/Group class hierarchy, collision functions
  sdl2_cython.md     — _sdl2.video/audio/controller Cython API
  python_modules.md  — camera, colordict, cursors, fastevent, midi, etc.
  headers.md         — _pygame.h slot API, pgplatform, pgimport, doc headers
  init_py.md         — bootstrap flow, MissingModule, import order diagram

Phase 0C: docs/TEST_MAP.md — test coverage map + gap analysis
Phase 0D: docs/BUILD_SYSTEM.md — dependency detection, platform notes,
          SIMD flags, adding new modules, Raspberry Pi build

TASK_pygame_viking_edition.md updated with Phase 0 completion status.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
display.c:
- Fix blit_sw/blit_sw_CC/blit_sw_A returning blit_hw values (copy-paste)
- Fix pg_get_surface() NULL deref on old_surface (no renderer, no GL)
- Fix pg_ResizeEventWatch unchecked p_glViewport after SDL_GL_GetProcAddress
- Fix pg_ResizeEventWatch resize handler NULL deref on old_surface

surface.c:
- Fix surf_subtype_new NULL deref if tp_new returns NULL (OOM path)

image.c:
- Fix image_frombuffer NULL deref + SDL_Surface leak if pgSurface_New fails

docs/AUDIT_REPORT.md: Phase 1A+1B findings — 6 fixed C bugs, static
analysis results (mypy/pylint), remaining audit scope documented

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…complete

font.c: TTF_OpenFontRW returning NULL was not checked — font_init returned
0 (success) with self->font = NULL, causing crash on first method call.
Now properly raises SDLError with TTF_GetError() and returns -1.

AUDIT_REPORT.md: updated with BUG-07, all 9 priority C files now marked
COMPLETE, 7 total bugs fixed across display/surface/image/font.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sprite.py: replace invalid Generic[TypeVar("T")] with properly defined
_T = TypeVar("_T") and Generic[_T] — fixes mypy E[misc] invalid base class

sysfont.py: move `import winreg` into initsysfonts_win32() and
`import subprocess` into initsysfonts_unix() — eliminates pylint E0601/E0606
(used-before-assignment on platform-conditional imports); also add proper
type annotations to Sysfonts and Sysalias module-level dicts

__init__.py: add type: ignore[arg-type] on copyreg.pickle() calls —
mypy's strict stub doesn't match the old-style pickle constructor API

mypy: 8 errors → 4 (remaining are star-import false positives from C exts)
pylint: 9.96/10 → 10.00/10

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tate

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…error

display.c — pg_display_quit:
  pg_texture and pg_renderer were left as dangling pointers after
  SDL_QuitSubSystem(SDL_INIT_VIDEO). Added explicit destroy+NULL before
  calling QuitSubSystem.

display.c — SDL_CreateTexture unchecked:
  pg_texture = SDL_CreateTexture(...) had no NULL check; failure would
  silently leave pg_texture NULL and continue, crashing later on use.
  Now raises SDLError and cleans up renderer before goto DESTROY_WINDOW.

display.c — DESTROY_WINDOW path:
  Error goto leaked pg_texture and pg_renderer. Now destroys and NULLs
  both before destroying the window.

transform.c — rotozoom surf32 creation unchecked:
  SDL_CreateRGBSurface for the 32bpp conversion surface was not checked
  for NULL; SDL_BlitSurface and rotozoomSurface would then receive NULL,
  causing a crash. Added NULL guard with proper error return.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…documented

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…update HEAD

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Audited the three concrete Phase 1E sub-items from
TASK_pygame_viking_edition.md against the live source tree:

  1. event.c mutex coverage    — CLEAN (every shared-state
                                  access guarded by
                                  PG_LOCK_EVFILTER_MUTEX)
  2. surface.c lock/unlock     — CLEAN (Lock/Unlock pairs
                                  balanced; multi-thread
                                  surface mutation is the
                                  operator's responsibility
                                  per SDL2 inheritance)
  3. display.c thread safety   — CLEAN-BY-DESIGN (SDL_Video
                                  itself requires same-thread
                                  semantics; pygame correctly
                                  inherits)

No code changes required. Pygame's existing thread-safety
guarantees are complete + correct as of HEAD.

docs/PHASE_1E_AUDIT_2026-05-05.md
  Full audit document covering each sub-item with line-level
  call-site verification + the rationale for closing the
  phase without code changes. Includes a forward note on the
  right lever for future multi-thread enhancement
  (operator-facing docs, not pygame-side locks).

TASK_pygame_viking_edition.md
  Phase 1E checklist marked COMPLETE with forward-pointer
  to the audit document. Phase 1F (Self-Healing Patterns)
  remains as the next slice.

Cross-project housekeeping (item 2 of 3) for the autonomous
run sequence: pygame Phase 1E now closed, MindSpark utils
committed, NSE working tree clean. Continuing with item 3
(coverage push toward 90% on Mythic Vibe CLI) next.
Audited the two concrete Phase 1F sub-items from
TASK_pygame_viking_edition.md against every SDL_Init and
SDL_InitSubSystem call site in src_c/:

  1. SDL_Init failure recovery paths      — 2 defects fixed
  2. Error context enrichment (SDL_GetError) — clean (8/10 sites)

src_c/scrap_sdl2.c:53 — defect fixed
  Before: SDL_Init(SDL_INIT_VIDEO) discarded its return value;
          init proceeded to malloc + flag _scrapinitialized=1
          even on SDL_Init failure. The caller at scrap.c:119
          had `if (!pygame_scrap_init()) return RAISE(...)` but
          it never triggered because the function returned 1
          regardless.
  After:  Check the return; return 0 on failure so the caller's
          existing RAISE path surfaces the real SDL error string.
          Block comment documents why the code path is rare in
          practice (VIDEO_INIT_CHECK runs first) but the fix is
          defensive against state-loss between checks.

src_c/base.c:352-356 — defect fixed
  Before: pg_sdl_was_init captured success as a bool used by the
          atexit handler, but the SDL error message was lost.
          Operators saw no startup diagnostic when SDL_Init
          genuinely failed; each submodule (display, joystick,
          mixer, time) lazily retried SDL_InitSubSystem and
          surfaced its own cryptic per-subsystem error.
  After:  Snapshot SDL_GetError() to a stack-local buffer,
          emit PyErr_WarnEx(PyExc_RuntimeWarning, ...). The
          atexit handler is unchanged. Warning is non-fatal so
          existing startup behavior is preserved; operators
          who want startup-fail-on-warning get that via their
          own -W filter (Phase 1F doesn't change pygame's
          default behavior).

docs/PHASE_1F_AUDIT_2026-05-05.md
  Full audit doc covering both fixes with before/after diffs +
  the 8 already-clean call sites confirmed via the table at
  the top. Includes a thread-safety note on SDL_GetError's
  thread-local string lifecycle: the captured-string-survives
  pattern works because every audited site consumes the
  string immediately into the Python exception/warning before
  any subsequent SDL call.

TASK_pygame_viking_edition.md
  Phase 1F marked CLOSED; the parent Phase 1 (entire
  defensive-C-surface phase) is now fully closed. Next phase
  is Phase 2 (cross-platform expansion).

Risk: minimal. Both fixes are diagnostic improvements on rare
failure paths (most operator setups have SDL_Init succeed
unconditionally). The new warning + the new return-0 branch
are reached only on previously-quietly-broken states.
…5-05)

Phase 2A scope per TASK_pygame_viking_edition.md:
  1. Audit all #ifdef platform guards
  2. Create pgplatform.h with unified abstractions
  3. Runtime vs compile-time capability detection

Items 1 + 2 shipped; item 3 deferred to Phase 2B per the audit's
recommendation.

docs/PHASE_2A_PLATFORM_GUARD_AUDIT_2026-05-05.md
  Comprehensive audit of ~150 #ifdef directives across
  src_c/*.c|h. Top-10 file table by guard density. 5-class
  taxonomy (OS family / CPU arch / SIMD / compiler / SDL
  feature). 5 findings: Windows-macro inconsistency,
  missing arm64 detection, legacy darwin + macintosh
  aliases, opaque BUILD_STATIC cluster.

src_c/include/pgplatform.h
  New additive header. All 0/1 binary macros. Defines
  PG_PLATFORM_{WINDOWS,APPLE,LINUX,ANDROID,WEB,BSD,POSIX},
  PG_ARCH_{X86_64,X86_32,ARM64,ARM32,PPC64},
  PG_HAVE_{SSE2,AVX2,NEON,SIMD},
  PG_BUILD_{STATIC,EMBEDDED}. Existing legacy macros remain
  valid; modules opt into new spellings independently.

TASK_pygame_viking_edition.md
  New Phase 2 Status section. 2A marked shipped; item 3
  deferred to 2B. 5 cleanup recommendations flagged for
  human review (subtractive — additive-only convention
  applies).

Risk: zero. Audit is documentation-only; header is additive
include with no module-code changes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant