captkirk88/zevy-raylib
zevy-raylib is a Zig integration layer connecting the zevy-ecs with the Raylib game library. It provides a plugin-based architecture for rapid game pr...
3cd4d3179d967fc8b931514603fdbc4a43a1d77183d39161eac2ed6f37ad3cb4d9dd518696ce90bbZevy Raylib is an integration layer that connects the Zevy ECS with the Raylib game library. It provides input handling, asset loading utilities, GUI components, and a plugin system to register common engine features easily.
Zevy Raylib is a small library that wires the Raylib runtime into a Zevy ECS-based app. It handles window creation, input harvesting, asset management and sets up RayGui-based UI systems over the Zevy scheduler.
WARNING This library and its APIs are experimental. They are intended as a convenient integration layer for example apps and prototypes. The API and internal behavior can and will change without backward compatibility guarantees. Tests and cross-platform coverage are limited — treat this as a development-time dependency rather than a production runtime. Please open issues or submit PRs if you rely on features that should be stabilized.
Files of interest:
src/root.zig — main package root and plugin wiringsrc/app.plugin.zig — Raylib and RayGui plugin implementationssrc/assets.plugin.zig — Adds the asset subsystem to the ECSsrc/input.plugin.zig — Input plugin and system registrationThe input layer provides the following:
InputManager — the main runtime service that polls raylib for input state and dispatches events.InputBindings and InputBinding — mapping action names to input chords.Files and location:
src/input/input_manager.zigsrc/input/input_bindings.zigsrc/input/input_types.zigInputManager is designed to be added to the ECS via the InputPlugin and optionally polled directly from systems. It supports event handlers and action checking API:
isActionActive("action_name") — check if action is currently activewasActionTriggered("action_name") — check a press event this frameaddEventHandler — subscribe to input eventsInput bindings, chords, and actions are declared with types located inside the input folder. Use the InputBindings helper to create action mappings from keyboard/mouse/gamepad/touch inputs.
The IO module provides a powerful AssetManager<T, Loader> generator for loading and tracking assets.
Key files:
src/io/asset_manager.zig — generic AssetManager implementationsrc/io/loaders.zig — built-in loaders for asset typessrc/io/loader.zig — loader interfacessrc/io/scheme_resolver.zig — handles scheme parsing and resolvingUse AssetManager to queue asset loads and process them in a separate step. It validates asset paths (supports builtin embedded:// scheme), manages unload, and stores assets in a string-to-entry map.
Useful methods:
loadAsset(file, settings) — queue asset for asynchronous loadingloadAssetNow(file, settings) — load asset immediatelyprocess() — perform a single step of queued loadersunloadAsset(handle) — release a loaded assetThe system supports schemes (for embedded:// content or custom resolvers) and allows custom loaders via AssetLoader and AssetUnloader wrappers.
Zevy Raylib exposes a RayGui-based GUI layer tied to the Zevy scheduler.
src/gui/ui.zig — exports components, layout, renderer, and systemssrc/gui/* — UI primitives, layout engines (flex, grid, anchor, dock), render systemsThe RayGuiPlugin registers a GuiStage and several systems:
Examples are available in src/gui/examples.zig and unit tests in src/gui/ui_tests.zig and src/gui/ui_render_tests.zig.
The embed module exposes helpers to include binary assets in the compiled artifact. See embed.zig in src/builtin. Use embedded:// URIs with the asset manager to reference compiled-in assets.
src/builtin/embed.zig — helper utilitiesembedded_assets/ — small sample files compiled into the binary, e.g., embedded_assets/alien.pngZevy Raylib defines several convenience plugins that register and configure services with the Zevy ECS system.
src/app.plugin.zig — Raylib application and RayGui pluginsrc/assets.plugin.zig — assets resource (wraps io.Assets)src/input.plugin.zig — registers InputManager and the input systemapp.plugin.zig)Provides:
rl.initWindow) with title, width, heightrl.initAudioDevice)deinit (close audio and window)Usage example:
try plugs.add(RaylibPlugin, RaylibPlugin{ .title = "My App", .width = 800, .height = 600 });
app.plugin.zig)Wires RayGui into the Zevy scheduler and adds UI systems to a GuiStage. The plugin registers the UI systems and the uiRenderSystem into the drawing stage.
assets.plugin.zig)Creates and registers io.Assets in the ECS as a resource so your systems can call loadAsset and process through the io API.
input.plugin.zig)Registers the InputManager resource and attaches an input update system that polls device state and emits events each frame.
src/gui/examples.zig — GUI usage examplessrc/input/tests.zig — Input unit testssrc/io/*_tests.zig — IO tests for asset managers and loadersTo run tests for the package use the workspace-level zig build test or per-package tests using zig build test inside the package directory.
src/root.zig by adding them to plug()src/* directorydeps/ folderzevy_raylib supports keeping external dependencies inside a deps/ folder using git submodules. If you (or your CI) have a .gitmodules entry for deps/zevy-ecs, here are useful commands for fetching and updating the module on Windows PowerShell or a POSIX shell.
Clone including submodules (recommended):
# From the repository root
git clone --recurse-submodules <repo-url>
If you already cloned without submodules:
git submodule update --init --recursive
Update an individual submodule to its currently configured branch (reads .gitmodules branch, or the checked-out branch in the submodule):
# From repository root
git submodule update --remote --merge deps/zevy-ecs
Update all submodules to their configured remotes/branches:
git submodule foreach --recursive 'git fetch --all && git merge --ff-only origin/$(git rev-parse --abbrev-ref HEAD)'
If you want to explicitly pull from a branch in a submodule and commit the gitlink at the top-level repo:
cd deps/zevy-ecs
git checkout main
git pull origin main
cd ../..
git add deps/zevy-ecs
git commit -m "update deps/zevy-ecs"
Notes:
deps/ manually — but submodules keep history and make updates easier.git submodule update --remote will update based on the branch configured in .gitmodules. Set a branch via git submodule set-branch --branch main deps/zevy-ecs if you want to track a specific branch.update_submodules.zigYou can also use the included Zig helper to initialize and update repo submodules. Run it from the zevy_raylib folder:
zig run update_submodules.zig
This runs the same sequence of commands shown above (initialize then update remote for all submodules). The script supports a few flags:
--init — only run git submodule update --init --recursive
--remote — only run git submodule update --remote --merge --recursive
--path <submodule-path> — update a single submodule path (useful for deps/zevy-ecs)
--dry-run — print the git commands without running them (useful for review)
Examples:
# Initialize submodules
zig run update_submodules.zig -- --init
# Update remote merge for all submodules
zig run update_submodules.zig -- --remote
# Update only the zevy-ecs submodule
zig run update_submodules.zig -- --remote --path deps/zevy-ecs
# Dry-run example (shows commands but doesn't execute them)
zig run update_submodules.zig -- --dry-run