Repository navigation
Raylib Tutorial
Home › Using C Libraries › raylib
📘 Start with: Using C Libraries, the ideas these steps rely on.
📖 In the book: Chapter 30, raylib. Measured with raylib 6.0, on Windows and Linux.
raylib is a library for making games. It has one header and 600 functions with plain names, and nothing to set up before your first window. It covers 2D and 3D drawing, textures, fonts, keyboard, mouse, gamepads and sound. raylib publishes ready-built packages for both of tiko's platforms, so nothing has to be compiled.
Go to github.com/raysan5/raylib/releases, open release 6.0, and download:
| File | For | Contains |
|---|---|---|
raylib-6.0_win64_msvc16.zip |
Windows |
include/raylib.h (+ raymath.h, rlgl.h)lib/raylib.lib (static, 5.3 MB)lib/raylibdll.lib (import library)lib/raylib.dll
|
raylib-6.0_linux_amd64.tar.gz |
Linux | the same headerslib/libraylib.a (static)lib/libraylib.so.6.0.0, plus links libraylib.so.600 and libraylib.so
|
Ignore the win32 (32-bit), mingw-w64 (another toolchain), arm64, macos and webassembly packages.
The project keeps raylib in vendor/raylib/. Rename the link-time files so that each carries its target. Both platforms can then share the folder, and one #foreignlib line finds the right file on each.
From the Windows zip:
| Copy | To |
|---|---|
include/raylib.h |
vendor/raylib/raylib.h |
lib/raylib.lib |
vendor/raylib/raylib_windows_x86_64.lib |
lib/raylibdll.lib |
vendor/raylib/raylibdll_windows_x86_64.lib |
lib/raylib.dll |
raylib.dll, beside your program (do not rename) |
From the Linux tarball:
| Copy | To |
|---|---|
include/raylib.h |
vendor/raylib/raylib.h (the same file) |
lib/libraylib.a |
vendor/raylib/raylib_linux_x86_64.a |
lib/libraylib.so.6.0.0 |
vendor/raylib/raylibdll_linux_x86_64.so |
lib/libraylib.so.6.0.0 |
libraylib.so.600, beside your program (the soname; do not change it) |
On Linux use cp -L (or copy the real file libraylib.so.6.0.0), so that you copy the library and not a link to it.
This is raylib's first example, core_basic_window:
'' raylib's first example, core_basic_window: open a window and draw a
'' line of text until it is closed. A number on the command line stops
'' it after that many frames instead.
#cinclude once "vendor/raylib/raylib.h"
#ifdef __FB_WIN32__
#foreignlib RAYLIB static "vendor/raylib/raylib", _
"system:winmm", "system:gdi32", "system:user32", _
"system:shell32"
#else
#foreignlib RAYLIB static "vendor/raylib/raylib", _
"system:GL", "system:m", "system:pthread", "system:dl", _
"system:rt", "system:X11"
#endif
const ScreenWidth = 800
const ScreenHeight = 450
dim maxFrames as int32 = valint( command( 1 ) ) '' 0: until closed
SetTraceLogLevel( LOG_WARNING ) '' raylib logs to stdout otherwise
InitWindow( ScreenWidth, ScreenHeight, _
"raylib [core] example - basic window" )
SetTargetFPS( 60 )
dim frames as int32 = 0
do until WindowShouldClose( )
BeginDrawing( )
ClearBackground( RAYWHITE )
DrawText( "Congrats! You created your first window!", _
190, 200, 20, LIGHTGRAY )
EndDrawing( )
frames += 1
if frames = maxFrames then exit do
loop
CloseWindow( )
print "drew "; str( frames ); " frames"tiko raylib-window.tiko
./raylib-windowAn 800×450 window opens with "Congrats! You created your first window!" in grey. Close it, and the program prints how many frames it drew. Give it a number, as in ./raylib-window 60, and it stops by itself after that many frames.
What is new compared with the C example:
-
The
#foreignlibline differs by platform, because a static raylib needs the operating system's libraries too, and they differ:- Windows:
winmm(timers),gdi32,user32,shell32 - Linux: OpenGL (
GL),m,pthread,dl,rtandX11, the list raylib's documentation gives
#ifdef __FB_WIN32__chooses between them. - Windows:
-
SetTraceLogLevel( LOG_WARNING ): raylib reports everything it does on standard output, about forty lines when a window opens. Leave it out to see them. -
RAYWHITEandLIGHTGRAYare C macros that build aColorstruct.#cincludeturns them into tiko definitions that build the sameColor, andDrawTexttakes theColorby value, as in C.
Replace the directives at the top with:
#cinclude once "vendor/raylib/raylib.h"
#foreignlib RAYLIB dynamic "vendor/raylib/raylibdll"The DLL brings its own system libraries, so none are listed. The program shrinks from 608 KB to 27 KB, and needs raylib.dll (Windows) or libraylib.so.600 (Linux) at run time:
tiko raylib-dll.tiko
./raylib-dll # Windows: raylib.dll beside it
LD_LIBRARY_PATH=. ./raylib-dll # LinuxIf the library cannot be found, Windows exits with -1073741515 and prints nothing, while Linux says error while loading shared libraries: libraylib.so.600 and exits with 127.
Repeating the #cinclude line and the platform-specific #foreignlib lines in every program gets old. Put them in a file of their own, vendor/raylib.ti:
'' raylib.ti -- raylib 6.0 for tiko: its header, and the library to
'' link, in one file a program includes. Both paths are relative to
'' this file, so the folder it sits in can live anywhere: inside one
'' project, or in a single place that every program shares.
#pragma once
#cinclude once "raylib/raylib.h"
#ifdef __FB_WIN32__
#foreignlib RAYLIB static "raylib/raylib", _
"system:winmm", "system:gdi32", "system:user32", _
"system:shell32"
#else
#foreignlib RAYLIB static "raylib/raylib", _
"system:GL", "system:m", "system:pthread", "system:dl", _
"system:rt", "system:X11"
#endifIts paths are relative to itself: #foreignlib always resolves that way, and #cinclude looks beside the file that names the header. So the folder works wherever it lives.
game/tiko.toml says where the bindings are, relative to tiko.toml:
# A program that uses raylib without saying where raylib is: the
# -i below names the folder of bindings, relative to this file.
[package]
name = "game"
[target.game]
main = "main.tiko"
options = ["-i", "../vendor"]game/main.tiko is raylib's example core_input_keys. Move the ball with the arrow keys:
'' raylib's example core_input_keys: move a ball with the arrow keys.
'' A number on the command line stops it after that many frames.
#include once "raylib.ti"
const ScreenWidth = 800
const ScreenHeight = 450
dim maxFrames as int32 = valint( command( 1 ) ) '' 0: until closed
SetTraceLogLevel( LOG_WARNING )
InitWindow( ScreenWidth, ScreenHeight, _
"raylib [core] example - keyboard input" )
dim ball as Vector2 = type( ScreenWidth / 2, ScreenHeight / 2 )
SetTargetFPS( 60 )
dim frames as int32 = 0
do until WindowShouldClose( )
if IsKeyDown( KEY_RIGHT ) then ball.x += 2
if IsKeyDown( KEY_LEFT ) then ball.x -= 2
if IsKeyDown( KEY_UP ) then ball.y -= 2
if IsKeyDown( KEY_DOWN ) then ball.y += 2
BeginDrawing( )
ClearBackground( RAYWHITE )
DrawText( "move the ball with arrow keys", 10, 10, 20, DARKGRAY )
DrawCircleV( ball, 50, MAROON )
EndDrawing( )
frames += 1
if frames = maxFrames then exit do
loop
CloseWindow( )
print "ball at "; str( ball.x ); ", "; str( ball.y ); _
" after "; str( frames ); " frames"cd game
tiko build game
./out/debug/gameball is a Vector2, a C struct of two floats. type( ... ) fills it, and it is passed to DrawCircleV by value. KEY_RIGHT and the other key names come from a C enum in raylib.h.
Windows has no standard place for C libraries, so make one, such as C:\tiko-libs:
C:\tiko-libs\raylib.ti
C:\tiko-libs\raylib\raylib.h
C:\tiko-libs\raylib\raylib_windows_x86_64.lib
C:\tiko-libs\raylib\raylibdll_windows_x86_64.lib
Every project then writes #include once "raylib.ti" and adds options = ["-i", "C:/tiko-libs"] to its tiko.toml, or passes -i C:\tiko-libs on the command line. When linking dynamically, also copy raylib.dll beside each program, or add the folder holding it to PATH.
Linux: recent distributions package raylib as libraylib-dev (Ubuntu 24.04 does not). Otherwise install the prebuilt tarball under /usr/local:
sudo cp include/*.h /usr/local/include/
sudo cp -P lib/libraylib.* /usr/local/lib/
sudo ldconfigPrograms then need no paths:
#cinclude once "raylib.h"
#foreignlib RAYLIB dynamic "system:raylib"Instead of a header, raylib can be a module that programs #import. The module says public #cinclude, which makes raylib's names the names of every program that imports it:
'' raylib as a module. 'public #cinclude' makes raylib.h's names the
'' names of every program that imports the module, and the module's
'' own #foreignlib links the library into each of them. Both paths are
'' relative to this file.
#module "raylib"
public #cinclude once "../../vendor/raylib/raylib.h"
#ifdef __FB_WIN32__
#foreignlib RAYLIB static "../../vendor/raylib/raylib", _
"system:winmm", "system:gdi32", "system:user32", _
"system:shell32"
#else
#foreignlib RAYLIB static "../../vendor/raylib/raylib", _
"system:GL", "system:m", "system:pthread", "system:dl", _
"system:rt", "system:X11"
#endif# A program that imports raylib as a module: the -i below names the
# folder that holds module folders, relative to this file.
[package]
name = "modgame"
[target.modgame]
main = "main.tiko"
options = ["-i", "../modules"]'' raylib's core_basic_window once more, through the raylib module:
'' one #import, and every raylib name is the program's own.
'' A number on the command line stops it after that many frames.
#import "raylib"
dim maxFrames as int32 = valint( command( 1 ) ) '' 0: until closed
SetTraceLogLevel( LOG_WARNING )
InitWindow( 800, 450, "raylib [core] example - basic window" )
SetTargetFPS( 60 )
dim frames as int32 = 0
do until WindowShouldClose( )
BeginDrawing( )
ClearBackground( RAYWHITE )
DrawText( "Congrats! You created your first window!", _
190, 200, 20, LIGHTGRAY )
EndDrawing( )
frames += 1
if frames = maxFrames then exit do
loop
CloseWindow( )
print "drew "; str( frames ); " frames"cd modgame
tiko build modgame
./out/debug/modgame 60drew 60 frames
The names are bare (InitWindow, not raylib.InitWindow), as #cinclude makes them, because a C header's #defines and struct macros cannot live in a namespace. To install the module for every program, put its folder in a directory named by TIKO_PATH (set TIKO_PATH=C:\tiko-modules on Windows, export TIKO_PATH=~/tiko-modules on Linux) and give the module's paths to its own library files.
Record the program's own directory as an rpath:
#cmdline "-x raylib-rpath -Wl -rpath,$ORIGIN"
#cinclude once "vendor/raylib/raylib.h"
#foreignlib RAYLIB dynamic "vendor/raylib/raylibdll"The program then finds libraylib.so.600 beside it wherever it is copied. In a shell, quote the option: tiko raylib-dll.tiko -Wl '-rpath,$ORIGIN'.
| Problem | Fix |
|---|---|
undefined symbol: __declspec(dllimport) DragQueryFileW linking statically on Windows |
a system library is missing (that one is shell32); the full list is winmm, gdi32, user32, shell32
|
undefined reference to 'XOpenDisplay' linking statically on Linux |
add "system:X11" (and the rest of the list in step 3) |
a long list of INFO: lines |
SetTraceLogLevel( LOG_WARNING ) before InitWindow
|
TKO0329 with raylib.a among the names tried |
rename the Linux archive to raylib_linux_x86_64.a; untagged, Windows would try it before raylib.lib
|
tiko-lang · Home · Feature Index · Keyword Index · License
FreeBASIC manual pages reproduced under the GNU FDL 1.3.
- Generics
- Interfaces
- For Each
- Iterators
- Tuples
- Array Results
- Defer
- Lambdas
- Block Strings
- Partial Types
- String Slices
- Embed
- Typed Variadics
- C Header Import
- Foreign Library Linking
- UString
- Fixed-Width Types
- Nullptr
- String Library
- Format
- Array
- Map
- Set
- LinkedList
- OrderedMap
- OrderedSet
- Sorting
- Optional
- Result
- Smart Pointers
- Date and Time (Chrono)
- Filesystem
- File Streams
- Config (INI and TOML)
- Codec
- Hash
- UUID
- OS
- Process
- Net
- HTTP and TLS
- Math Library
- Finance
- Logging
- Terminal TUI Library
- PsControls
- tkControls
- sys/win
- Goroutines and Channels
- LLVM Backend
- tiko build
- TIKO_COMPILER
- Variable Declarations
- Standard Data Types
- User Defined Types
- Procedures
- Operators
- Control Flow Statements
- Converting Data Types
- Array Functions
- String Functions
- Mathematical Functions
- Bit Manipulation
- Date and Time Functions
- File I/O Functions
- Console Functions
- User Input (Runtime Library)
- User Input Functions (Graphics Library)
- Screen Functions
- 2D Drawing Functions
- Graphics Library Reference
- Graphics Keyword List
- Memory Functions
- Threading Support Functions
- Error Handling Functions
- Operating System Functions
- Preprocessor
- Intrinsic Defines
- Miscellaneous Keywords
- Modularizing