Quick answer: Build with --add-data 'assets:assets'. Resolve runtime via sys._MEIPASS.
Game runs in dev. Onefile build can’t open assets/player.png. Bundle extracted to a temp dir; relative path doesn’t reach there.
The Fix
import sys, os
def resource_path(rel: str) -> str:
if getattr(sys, "frozen", False):
base = sys._MEIPASS # onefile temp dir
else:
base = os.path.dirname(__file__)
return os.path.join(base, rel)
img = pygame.image.load(resource_path("assets/player.png"))
# Build command:
# pyinstaller --onefile --add-data "assets:assets" main.py
Helper resolves dev and frozen paths transparently. Onefile extracts assets/ to _MEIPASS at startup; helper joins correctly.
Verifying
Run the .exe / binary: assets load. Logs print resource_path correctly. Onedir build also works.
“_MEIPASS in frozen. dir in dev. Assets resolve.”
Related Issues
For Pygame image extension, see image extension. For HiDPI text, see HiDPI.
_MEIPASS resolves. Assets load.