Native SDL2 backend for mini-arcade-core using SDL2 + pybind11.
Project description
mini-arcade-native-backend
Native SDL2 backend for mini-arcade-core, implemented in C++ with SDL2 + pybind11
and exposed to Python as a backend that plugs into your mini-arcade game framework.
The goal of this repo is to provide a native window + input + drawing layer while
keeping all game logic in Python (via mini-arcade-core).
- C++ (
SDL2+pybind11) ⇒_nativeextension module - Python adapter ⇒
NativeBackendimplementingmini_arcade_core.backend.Backend
Features (current)
- Opens an SDL window from Python
- Basic event polling (Quit, KeyDown, KeyUp) mapped to
Event/EventTypein mini-core - Simple rendering:
begin_frame()/end_frame()draw_rect(x, y, w, h)(filled rectangle)
- Example script that shows a moving rectangle and exits on ESC or window close
This is intentionally minimal and intended as a foundation for adding sprites, textures, audio, etc.
Repository layout
mini-arcade-native-backend/
├─ cpp/
│ ├─ engine.h # C++ Engine class (SDL wrapper)
│ ├─ engine.cpp
│ └─ bindings.cpp # pybind11 bindings for Engine / Event / EventType
├─ src/
│ └─ mini_arcade_native_backend/
│ ├─ __init__.py # Python adapter (NativeBackend)
│ └─ ... # (future helpers)
├─ examples/
│ └─ native_backend_demo.py # example using NativeBackend directly
├─ CMakeLists.txt # C++ build (pybind11 + SDL2)
└─ pyproject.toml # Python package & build config (scikit-build-core)
Install modes
There are two ways to consume this backend:
- From PyPI (recommended for players / game users)
Prebuilt wheels for your platform (no C++ toolchain or vcpkg needed). - From source (for contributors / engine dev)
Build the C++ extension locally using CMake + vcpkg.
1. Using the backend from PyPI (no C++ build)
Once wheels are published, you can simply do:
pip install mini-arcade-core
pip install mini-arcade-native-backend
And in your game:
from mini_arcade_core import Game, GameConfig, Scene
from mini_arcade_core.backend import EventType
from mini_arcade_native_backend import NativeBackend
class MyScene(Scene):
def handle_event(self, event):
if event.type == EventType.KEYDOWN and event.key == 27: # ESC
self.game.quit()
def update(self, dt: float):
...
def draw(self, backend):
backend.draw_rect(100, 100, 200, 150)
config = GameConfig(
width=800,
height=600,
title="Mini Arcade + Native SDL2",
backend_factory=lambda: NativeBackend(),
)
game = Game(config)
scene = MyScene(game)
game.run(scene)
For normal users of your games, this is the ideal path: no vcpkg, no CMake, no compiler.
2. Developing / building from source
If you want to work on the native backend itself (C++ + Python), you’ll build the extension locally. For that, you need a C++ toolchain, CMake, and vcpkg.
2.1. System requirements
- OS: Windows 10 or later (current dev setup)
- Compiler: MSVC via Visual Studio Build Tools or Visual Studio 2022
- Install the “Desktop development with C++” workload
- CMake: 3.16+
- Python: 3.9–3.11 (matching your
mini-arcade-coreversion) - vcpkg: for
SDL2andpybind11 - (Optional but nice) virtual environment / Poetry for Python deps
2.2. vcpkg + C++ libraries
This project uses vcpkg to manage C++ dependencies.
Clone and bootstrap vcpkg
cd C:\Users\<your_user>\work
git clone https://github.com/microsoft/vcpkg.git
cd vcpkg
.\bootstrap-vcpkg.bat
Install dependencies via vcpkg
# From the vcpkg folder:
.\vcpkg.exe install sdl2 pybind11
You only need to do this once per machine (unless you wipe vcpkg or add new libraries).
2.3. Linking CMake to vcpkg
For builds in this repo, set the toolchain environment variable once per shell:
$env:CMAKE_TOOLCHAIN_FILE = "C:/Users/<your_user>/work/vcpkg/scripts/buildsystems/vcpkg.cmake"
(Adjust the path if you cloned vcpkg somewhere else.)
3. Building & installing the package from source
This project uses scikit-build-core as
the build backend, which lets pip drive CMake for you.
From the repo root (mini-arcade-native-backend/):
3.1. Editable install (dev mode)
# Activate your virtualenv (or use Poetry's venv)
# Then, with CMAKE_TOOLCHAIN_FILE set:
pip install -e .
What this does:
- Runs CMake via scikit-build-core
- Builds the
_nativeextension - Installs the package in editable mode, so changes to
src/are picked up immediately
After this, you can test in Python:
>>> from mini_arcade_native_backend import NativeBackend
>>> backend = NativeBackend()
>>> backend.init(800, 600, "Hello from native backend")
3.2. Building wheels / sdist
To build distributable artifacts:
python -m build
This will produce:
dist/
mini-arcade-native-backend-0.1.0-*.whl
mini-arcade-native-backend-0.1.0.tar.gz
Those wheels can be uploaded to PyPI (e.g. via twine) and installed by anyone with:
pip install mini-arcade-native-backend
End users installing the wheel do not need vcpkg or a compiler.
4. Python usage & example
The package exposes a NativeBackend that implements the Backend protocol from
mini-arcade-core and wraps the C++ Engine underneath.
from mini_arcade_native_backend import NativeBackend
from mini_arcade_core.backend import EventType
A small standalone demo is provided under examples/:
python examples/native_backend_demo.py
That demo:
- opens an 800×600 window,
- moves a rectangle horizontally,
- exits on ESC or window close.
(When installed via pip install -e ., you can run this from the repo root.)
5. How it fits into mini-arcade-core
On the C++ side (cpp/engine.h / cpp/engine.cpp):
mini::Enginewraps SDL:init(width, height, title)begin_frame()/end_frame()draw_rect(x, y, w, h)poll_events()→std::vector<Event>
EventTypeandEventare simple types mapping SDL events to something Python-friendly.
On the Python side (src/mini_arcade_native_backend/__init__.py):
- The compiled C++ module is imported as
._native(installed into the same package) NativeBackendimplementsmini_arcade_core.backend.Backend:init(width, height, title)→_native.Engine.init(...)poll_events()→ converts_native.Eventto coreEventbegin_frame()/end_frame()→ pass-throughdraw_rect(x, y, w, h)→ pass-through
A minimal integration with mini-arcade-core:
from mini_arcade_core import Game, GameConfig, Scene
from mini_arcade_core.backend import Backend, Event, EventType
from mini_arcade_native_backend import NativeBackend
class MyScene(Scene):
def handle_event(self, event: Event) -> None:
if event.type == EventType.KEYDOWN and event.key == 27: # ESC
self.game.quit()
def update(self, dt: float) -> None:
...
def draw(self, backend: Backend) -> None:
backend.draw_rect(100, 100, 200, 150)
config = GameConfig(
width=800,
height=600,
title="Mini Arcade + Native SDL2",
backend_factory=lambda: NativeBackend(),
)
game = Game(config)
scene = MyScene(game)
game.run(scene)
6. Troubleshooting
-
ModuleNotFoundError: No module named '_native'- Ensure
pip install -e .(orpython -m build) completed successfully. - Confirm that the wheel contains
mini_arcade_native_backend/_native.*.pyd.
- Ensure
-
DLL load error / Python version mismatch
- Make sure you are building and running with the same Python version.
- If you have multiple Python versions installed, ensure the one used by
pip install -e .is the one used to run your game.
-
CMake can’t find SDL2 or pybind11
- Confirm vcpkg is installed and
sdl2+pybind11are installed via vcpkg. - Make sure
CMAKE_TOOLCHAIN_FILEis set correctly in your shell.
- Confirm vcpkg is installed and
7. Roadmap
- Configurable clear color (per scene / per game)
- Basic texture / sprite support
- Simple audio playback
- CI that builds wheels for Windows and uploads to PyPI
- A
mini-arcade-coreexample project that uses this backend as the default renderer
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mini_arcade_native_backend-0.4.6.tar.gz.
File metadata
- Download URL: mini_arcade_native_backend-0.4.6.tar.gz
- Upload date:
- Size: 21.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6e5ba3e63565925230e7a980f86b1fff7e9eef0c843fa92cc02223d7d440db93
|
|
| MD5 |
d2292963856673b7163ee973db7aa20e
|
|
| BLAKE2b-256 |
b910222bc27cc82ef95592c9db4cfb767621af282c9a2e8fc06f14b00218573e
|
File details
Details for the file mini_arcade_native_backend-0.4.6-cp311-cp311-win_amd64.whl.
File metadata
- Download URL: mini_arcade_native_backend-0.4.6-cp311-cp311-win_amd64.whl
- Upload date:
- Size: 105.9 kB
- Tags: CPython 3.11, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b3867fa50333f57e4a173ab44176a0db2378653aa366adbf1919eae32d387ca5
|
|
| MD5 |
fa19b7f19500a813eeaa0743717cd4e3
|
|
| BLAKE2b-256 |
3475d5165ff8273a54ad594e97ddd2bad3ef72d27dfa85d299885be6ad0eb402
|
File details
Details for the file mini_arcade_native_backend-0.4.6-cp310-cp310-win_amd64.whl.
File metadata
- Download URL: mini_arcade_native_backend-0.4.6-cp310-cp310-win_amd64.whl
- Upload date:
- Size: 105.1 kB
- Tags: CPython 3.10, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6fa345868ebddc55c587ab4bd09d86a3622c7ba5a857f6498eac654dfab32ba3
|
|
| MD5 |
dc2e3244c00b704cbf0e4ecefc95784a
|
|
| BLAKE2b-256 |
8795ae99790209ebf7387b6d3a712eadf2c180d10c56562b0be3fa73570bbde4
|
File details
Details for the file mini_arcade_native_backend-0.4.6-cp39-cp39-win_amd64.whl.
File metadata
- Download URL: mini_arcade_native_backend-0.4.6-cp39-cp39-win_amd64.whl
- Upload date:
- Size: 108.2 kB
- Tags: CPython 3.9, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
91023facebd2bb0c197c2fe43f3a99141d788e2b74c9f2e2eaebb2717acb06e6
|
|
| MD5 |
35ddfd9d2591b7d035dee99d6c9d3ce1
|
|
| BLAKE2b-256 |
c48e97193cac914c162a468cc787d41acd4ec2be04f03137c74b91b6500493dc
|