extern fn declares a C function so Chasm code can call it. The compiler emits a direct call to the C symbol at the call site, no marshaling, no overhead.
Syntax
extern fn draw_circle(x: float, y: float, r: float, color: int) -> voidThe parameter names are for documentation only. The types map directly to C:
| Chasm type | C type |
|---|---|
int | int64_t |
float | double |
bool | bool |
string | const char* |
void | void |
C Name Alias
If the C symbol name differs from what you want to call it in Chasm, use = "c_name":
extern fn draw_circle(x: float, y: float, r: float, color: int) -> void = "rl_draw_circle"Now Chasm calls it as draw_circle(...) but the emitted C calls rl_draw_circle(...). Without an alias, the Chasm name is used as the C symbol directly.
Calling Extern Functions
Extern functions are called like any other function:
extern fn draw_text(text: string, x: int, y: int, size: int, color: int) -> void
def on_draw() do
draw_text("Score: #{@score}", 10, 10, 20, 0xffffffff)
endEngine Bindings
When you compile with --engine raylib, the Raylib binding file is prepended automatically. It declares all Raylib functions as extern fn:
# From engine/raylib/raylib.chasm (included automatically)
extern fn draw_rectangle(x: float, y: float, w: float, h: float, color: int) -> void
extern fn draw_circle_v(cx: float, cy: float, r: float, color: int) -> void
extern fn key_down(key: atom) -> bool
extern fn key_pressed(key: atom) -> boolYour game script then calls them directly:
def on_draw() do
draw_rectangle(@player_x, @player_y, 32.0, 32.0, 0x4488ffff)
draw_circle_v(@bullet_x, @bullet_y, 4.0, 0xffff00ff)
endGodot Plugin
When compiling with --engine godot, the GDExtension binding is used instead. Chasm scripts become ChasmComponent nodes that can be attached to any Godot node.
Writing Your Own Engine Bindings
Create a .chasm file with extern fn declarations for every C function you want to expose:
engine/my_engine.chasm:
extern fn draw_sprite(id: int, x: float, y: float, w: float, h: float) -> void = "engine_draw_sprite"
extern fn play_sound(id: int, vol: float) -> void = "engine_play_sound"
extern fn load_texture(path: string) -> int = "engine_load_texture"Then pass it to the CLI as a prelude using resolveImports in a custom CLI wrapper, or include it via import in your game file.
Type safety:
Extern functions bypass the type checker at the boundary. Ensure parameter types in the Chasm declaration match the C function signature exactly.