Skip to content

ingur/raylib-starter

Repository files navigation

raylib-starter

My personal, minimal game template for creating cross-platform raylib games in Python, powered by pocketpy.

Features

  • Includes raylib (v6.0) and pocketpy (v2.1.8), built from source and version-pinned
  • Write your whole game in Python, with live hot reload while developing
  • Cross-platform builds (Linux-x64, Windows-x64 & Web)
  • Autogenerated Python bindings and type stubs
  • Includes build helper script for easy development
  • Automatic asset packing/loading using a zip pak + virtual filesystem
  • Persistent save/ directory on all platforms, IndexedDB backed on web

Note

The previous LuaJIT (and C/C++) version lives on the luajit branch.

Requirements

  • git, zip, and zig 0.16
  • pkg-config, OpenGL, X11 and Wayland development libraries
  • Optional: emscripten for the web target
  • Optional: curl and python3 with pycparser and pcpp, only needed for ./build.sh bindgen
  • Develop on Linux, or on Windows via WSL2

Tip

See the wiki for quick installation commands

Getting Started

Clone the repository:

git clone --depth 1 https://github.com/ingur/raylib-starter.git

Use the helper script to build and run the game:

./build.sh run

There is also a hot reload mode. Save a file and the game reloads:

./build.sh dev

You can use the following commands:

# usage: ./build.sh <command> [options]
./build.sh run        # build and run the game [debug|release]
./build.sh dev        # build and run the game with hot reload
./build.sh linux      # build the linux target [debug|release]
./build.sh windows    # build the windows target [debug|release]
./build.sh web        # build the web target
./build.sh dist       # package release zips for all platforms into dist/
./build.sh bindgen    # regenerate the python bindings and type stubs
./build.sh clean      # clean build environment
./build.sh help       # show the help message

Build targets default to release, run defaults to debug.

Note

The first build downloads and compiles raylib and pocketpy from source. Later builds are incremental. Binaries land in zig-out/.

Example Code

import raylib as rl

# top level runs once at boot, the window is already open.
# define update(), it runs every frame (return True to quit)
def update():
    rl.BeginDrawing()

    rl.ClearBackground(rl.RAYWHITE)
    rl.DrawText("Congrats! You created your first window!", 190, 200, 20, rl.LIGHTGRAY)

    rl.EndDrawing()

Configuration/Tips

  • The Python entrypoint is game/main.py
  • Define update() to run code every frame
  • Return True from update() to quit the game
  • Window startup settings live in game/window.py
  • Debug builds enable the DEV builtin
  • ./build.sh dev enables hot reloading
  • ./build.sh run release plays the packed build, exactly what players get
  • The windows target cross-compiles from Linux, no extra toolchain needed
  • Define before_reload() and after_reload(state) to carry a state string across reloads
  • Reloads never free GPU resources
  • Unload them in before_reload() like the demo does
  • Project name lives in build.zig, dependency versions in build.zig.zon
  • Rerun bindgen after a raylib or pocketpy bump
  • Vectors and colors come from the built-in vmath module (vec2, vec3, color32)
  • assets/ and game/ are packed into assets.pak, a plain zip
  • Files load through a virtual filesystem
  • Loose files win over the pak:
    sprite = rl.LoadTexture("assets/sprite.png")
  • Shaders are assets too and load the same way
  • Desktop uses GLSL 330 and web uses GLSL ES 100
  • Ship both and pick at runtime:
    import sys
    version = "glsl100" if sys.platform == "emscripten" else "glsl330"
    shader = rl.LoadShader("", f"assets/shaders/{version}/scanline.fs")  # "" = default vertex shader
  • Write save files to save/, which exists and persists on every platform:
    rl.SaveFileText("save/highscore.txt", str(score))
  • On web, anything written outside save/ is in-memory only
  • Read any packed or loose file with rl.LoadFileText and rl.LoadFileData, which return str and bytes
  • The builtin open() only sees real files like save/
  • Use the rl loaders for packed assets
  • Some raylib functions take C pointers, shown as intptr in the stubs
  • The built-in stdc module bridges them with addressof, malloc, and typed boxes like Float
  • Test web builds locally with emrun zig-out/web/index.html

Credits

  • raylib for the amazing library
  • pocketpy for the embeddable Python interpreter
  • miniz for zip-based asset packing

About

My personal, minimal game template for creating cross-platform raylib games

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages