Raylib

Using Chasm with the Raylib game engine, setup, API, and running your first game.

Raylib is a simple, open-source C game library. Chasm ships with a complete Raylib binding, compile with --engine raylib and the full Raylib API is available in your script.

Setup

1

Install Raylib

On macOS:

brew install raylib

On Linux:

sudo apt install libraylib-dev
2

Run with the Raylib engine

chasm run --engine raylib game.chasm

The CLI compiles your script and links it against Raylib automatically.

3

Watch mode (hot reload)

chasm watch --engine raylib game.chasm

Save the file → the engine reloads your script instantly without restarting.

Script Structure

A Raylib Chasm script uses on_init, on_tick, and on_draw:

@player_x :: script = 400.0
@player_y :: script = 300.0
@speed    :: script = 200.0

def on_init() do
  # Called once at startup
end

def on_tick(dt :: float) do
  if key_down(:right) do @player_x = @player_x + @speed * dt end
  if key_down(:left)  do @player_x = @player_x - @speed * dt end
  if key_down(:down)  do @player_y = @player_y + @speed * dt end
  if key_down(:up)    do @player_y = @player_y - @speed * dt end
end

def on_draw() do
  clear_background(0x181820ff)
  draw_rectangle(@player_x - 16.0, @player_y - 16.0, 32.0, 32.0, 0x4488ffff)
  draw_text("Move with arrow keys", 10, 10, 20, 0xffffffff)
end

Drawing

FunctionDescription
clear_background(color)Fill the screen with a solid color
draw_rectangle(x, y, w, h, color)Filled rectangle
draw_rectangle_lines(x, y, w, h, color)Outlined rectangle
draw_circle(cx, cy, r, color)Filled circle
draw_circle_lines(cx, cy, r, color)Circle outline
draw_line(x1, y1, x2, y2, color)Line segment
draw_text(text, x, y, size, color)Text with built-in font

Colors are 0xRRGGBBAA packed integers. Common values:

white   = 0xffffffff
black   = 0x000000ff
red     = 0xff0000ff
transparent_white = 0xffffff80   # 50% alpha

Input

Keyboard

FunctionReturnsDescription
key_down(key)boolTrue every frame the key is held
key_pressed(key)boolTrue only on the first frame the key is pressed
key_released(key)boolTrue only on the frame the key is released

Key names are atoms. Common keys: :right, :left, :up, :down, :space, :enter, :escape, :a:z, :f1:f12.

# Move while held
if key_down(:right) do @x = @x + @speed * dt end

# Fire once per press
if key_pressed(:space) do fire_bullet() end

Mouse

FunctionReturnsDescription
mouse_x()floatCurrent mouse X position
mouse_y()floatCurrent mouse Y position
mouse_down(button)boolTrue while button is held (:left, :right, :middle)
mouse_pressed(button)boolTrue on the first frame button is pressed

Screen

FunctionReturnsDescription
screen_width()floatCurrent window width in pixels
screen_height()floatCurrent window height in pixels
get_fps()intCurrent frames per second
get_time()floatSeconds elapsed since startup

Textures and Fonts

@player_tex :: persistent = 0
@font       :: persistent = 0

def on_init() do
  @player_tex = load_texture("assets/player.png")
  @font       = load_font("assets/mono.ttf")
end

def on_draw() do
  draw_texture(@player_tex, @player_x, @player_y, 32.0, 32.0, 0xffffffff)
  draw_text_ex(@font, "Score: #{@score}", 10, 10, 24, 1.0, 0xffffffff)
end

Load textures and fonts in on_init into persistent attrs so they survive hot-reload.

Audio

@shoot_sfx :: persistent = 0

def on_init() do
  @shoot_sfx = load_sound("assets/shoot.wav")
end

def on_tick(dt :: float) do
  if key_pressed(:space) do
    play_sound(@shoot_sfx)
  end
end