Bindings for raylib 5.5 โ windowing, 2D/3D drawing, input and audio, straight over Bern's FFI.
import vendor/raylib/raylib
The module loads the bundled raylib shared library for your platform (Windows .dll, Linux .so, macOS .dylib) and exposes the raylib C functions under their original names. If you know the raylib cheatsheet, you already know the API: InitWindow, BeginDrawing, DrawText, and the rest are called exactly as you would expect, with the library handle wired up for you.
Only the functions listed here are bound today; the set covers windowing, the frame loop, input, basic shapes, text and audio. Constructors and enums are provided as Bern values, so you rarely touch raw integers.
The core raylib structs are modelled as Bern ADTs. Build them with their constructors and pass them straight into drawing calls.
An RGBA color, each channel a byte (0โ255). A full set of named colors ships as constants.
sky = Color(102, 191, 255, 255) faded = Color(0, 0, 0, 128) -- 50% transparent black -- or use the built-ins RL_RAYWHITE RL_BLACK RL_RED RL_GREEN RL_BLUE RL_GOLD RL_LIME RL_SKYBLUE RL_VIOLET RL_MAGENTA
2D and 3D vectors (32-bit floats, for C compatibility). Rectangle(x, y, width, height) describes an axis-aligned box.
pos = Vector2(400.0, 225.0) size = Rectangle(0.0, 0.0, 120.0, 40.0)
Named constants are grouped into objects, so you read a key or flag by name instead of memorising numbers. Index them with a dot or a key.
KeyboardKey.SPACE -- 32 MouseButton.LEFT -- 0 ConfigFlag.MSAA_4X_HINT -- 32 -- also: CameraProjection, BlendMode, Gesture, TraceLogLevel, -- PixelFormat, GamepadButton, MouseCursor, and more.
Useful constants: RL_VERSION ("5.5"), RL_PI, RL_DEG2RAD, RL_RAD2DEG.
Create the window and OpenGL context. Call this once before anything else draws.
InitWindow(800, 450, "Bern + raylib")
True once the user closes the window or presses the exit key โ the natural condition for the main loop.
Tear down the window and release resources. Call it last.
Other window helpers follow the C names directly:
SetConfigFlags(ConfigFlag.MSAA_4X_HINT) -- before InitWindow
SetWindowTitle("New title")
SetWindowSize(1024, 600)
SetWindowPosition(100, 100)
GetScreenWidth() GetScreenHeight()
IsWindowReady() IsWindowResized()
ToggleFullscreen() MaximizeWindow() MinimizeWindow()
Every frame is bracketed by BeginDrawing() / EndDrawing(). Clear the background, issue draw calls, then end the frame to present it.
Fill the whole framebuffer with a single color, usually the first thing inside BeginDrawing.
Cap the loop at a target frame rate. Companions: GetFPS(), GetFrameTime() (seconds since last frame), GetTime() (seconds since start).
BeginDrawing()
ClearBackground(RL_RAYWHITE)
DrawText("hello", 20, 20, 20, RL_DARKGRAY)
EndDrawing()
Polling functions read the current input state once per frame. Keys and buttons take the named enum values.
Down is held this frame; Pressed fired only on the frame it went down. Also IsKeyReleased, IsKeyUp, and GetKeyPressed() for text-style input.
if IsKeyDown(KeyboardKey.RIGHT) then
x = x + 4
end
Plus IsMouseButtonDown, GetMouseWheelMove(), SetMouseCursor(MouseCursor.POINTING_HAND).
if IsMouseButtonPressed(MouseButton.LEFT) then
click_at(GetMouseX(), GetMouseY())
end
IsGamepadAvailable(0), IsGamepadButtonDown(0, GamepadButton.RIGHT_FACE_DOWN), GetGamepadAxisMovement(0, GamepadAxis.LEFT_X); GetTouchX() / GetTouchY() / GetTouchPointCount() for touch.
The basic 2D primitives. Outlined variants (DrawRectangleLines, DrawCircleLines), gradients (DrawRectangleGradientV/H), DrawEllipse and DrawPixel are all available.
DrawRectangle(20, 20, 120, 60, RL_SKYBLUE) DrawCircle(400, 225, 40.0, RL_RED) DrawLine(0, 0, 800, 450, RL_GRAY)
Draw a string with the built-in font. MeasureText(text, fontSize) returns its pixel width, and DrawFPS(x, y) draws a live frame-rate counter.
CheckCollisionPointRec(point, rect) and CheckCollisionPointCircle(point, center, radius) answer simple hit tests โ handy for buttons and hover states.
Open the audio device once, then load and play sounds (one-shots) or music streams (long tracks you update each frame).
InitAudioDevice()
shot = LoadSound("blip.wav")
PlaySound(shot)
song = LoadMusicStream("theme.ogg")
PlayMusicStream(song)
-- inside the loop: UpdateMusicStream(song)
-- on shutdown
UnloadSound(shot)
UnloadMusicStream(song)
CloseAudioDevice()
Sounds: PauseSound, ResumeSound, StopSound, SetSoundVolume, SetSoundPitch. Music: SeekMusicStream, SetMusicVolume, GetMusicTimeLength, GetMusicTimePlayed.
The classic raylib "first window" โ open a window, run the frame loop until the user closes it, and draw a line of text in the middle.
import vendor/raylib/raylib
InitWindow(800, 450, "Bern + raylib")
SetTargetFPS(60)
for !WindowShouldClose() do
BeginDrawing()
ClearBackground(RL_RAYWHITE)
DrawText("Congrats! You created your first window!", 190, 200, 20, RL_LIGHTGRAY)
EndDrawing()
end
CloseWindow()
And a tiny interactive sketch: a square you move with the arrow keys, redrawn every frame.
import vendor/raylib/raylib
InitWindow(800, 450, "move me")
SetTargetFPS(60)
x = 400
y = 225
for !WindowShouldClose() do
if IsKeyDown(KeyboardKey.RIGHT) then x = x + 4 end
if IsKeyDown(KeyboardKey.LEFT) then x = x - 4 end
if IsKeyDown(KeyboardKey.DOWN) then y = y + 4 end
if IsKeyDown(KeyboardKey.UP) then y = y - 4 end
BeginDrawing()
ClearBackground(RL_RAYWHITE)
DrawRectangle(x, y, 40, 40, RL_MAROON)
DrawText("arrow keys to move", 20, 20, 20, RL_GRAY)
EndDrawing()
end
CloseWindow()