Module Gamelle

Gamelle is a tiny 2D game engine. It provides:

Getting started

You can create a new game project with:

$ gamelle init mygame
$ cd mygame
$ make

The make command starts the game in development mode: Editing src/mygame.ml will automatically reload your game on every change. Game assets added to the folder assets/ are automatically available through the dynamic Assets module.

To export your game as a single HTML file, compiled with js_of_ocaml and including all game assets:

$ make html

Main loop

type io

The type allowing input/output operations. Every side-effecting function requires a named argument ~io of this type.

val run : 'state -> (io:io -> 'state -> 'state) -> unit

run initial_state fn is the game main loop. The function fn will be called at every frame to react to player inputs and draw the game state on the screen.

open Gamelle

type state = ...

let initial_state = ...

let () =
  Gamelle.run initial_state @@ fun ~io current_state ->
    let new_state = (* TODO: react to player inputs and update the current state *) in
    (* TODO: draw the new game state *)
    new_state

Maths

Linear Algebra

module Color : sig ... end

Colors.

type xy = {
  1. x : float;
  2. y : float;
}

The type of points and vectors: x and y coordinates.

module Point : sig ... end

Points: x and y positions in 2D.

module Vec : sig ... end

Vectors: directions in 2D.

Geometry

module Size : sig ... end

Sizes: width and height dimensions.

module Segment : sig ... end

Segments connecting two Points.

module Box : sig ... end

Axis-aligned bounding boxes.

module Circle : sig ... end

Circles.

module Polygon : sig ... end

Polygons.

module Shape : sig ... end

Arbitrary shapes: segments, circles and polygons.

Assets

Game assets like images, fonts and sounds which are added to the assets/ folder are automatically loaded and available through the dynamic Assets module. For example, a bitmap file assets/foo.png is accessible as Assets.foo : Bitmap.t.

Images

module Bitmap : sig ... end

Bitmap images: PNG, JPEG.

val draw : io:io -> at:Point.t -> Bitmap.t -> unit

draw ~io ~at bitmap draws the image bitmap at position at on the screen. Same as Bitmap.draw.

Example:

(* draw the assets/player.png bitmap at position x=100, y=200 *)
draw ~io Assets.player ~at:(Point.v 100. 200.) ;

Text

module Font : sig ... end

Typefaces used to render text on screen.

module Text : sig ... end

Text rendering.

val draw_string : io:io -> ?color:Color.t -> ?font:Font.t -> ?size:int -> at:Point.t -> string -> unit

draw_string ~io ~at txt prints the string txt at position at on the screen. Same as Text.draw.

Examples:

draw_string ~io "Hello World" ~at:(Input.mouse_pos ~io) ;
draw_string ~io ~color:Color.red ~at:(Point.v 200. 100.) "Bloody!" ;
draw_string ~io ~at:Point.zero "Why so serious?" ~font:Assets.comic_sans ~size:50 ;

Audio

module Sound : sig ... end

Audio sounds and musics: MP3, OGG.

Player inputs

module Input : sig ... end

Player inputs: mouse and keyboard events.

module Ui : sig ... end

Graphical user interface: buttons, checkboxes, text inputs.

Camera

module View : sig ... end

Customize the io camera, default color and font used.

module Window : sig ... end

Configure the game window.

Animations

val clock : io:io -> float

clock ~io returns the number of elapsed seconds since the game started until the current frame. The clock is defined at the beginning of a frame, calling clock multiple times will always produce the same result.

Examples:

(* circle moving around a circle *)
let center = Vec.(100.0 * v (1. +. cos (clock ~io)) (1. +. sin (clock ~io))) in
Circle.fill ~io (Circle.v center 10.0);
(* show elapsed time since the last click *)
Gamelle.run 0. @@ fun ~io last_click ->
let now = clock ~io in
let last_click = if Input.is_up ~io `click_left then now else last_click in
let elapsed = now -. last_click in
draw_string ~io ~at:Point.zero (Printf.sprintf "Time since clicked: %fs" elapsed);
last_click
val dt : io:io -> float

dt ~io is the duration of a frame, which is fixed to a 60fps framerate.

Example:

Gamelle.run (Point.v 200. 200., Vec.zero) @@ fun ~io (position, velocity) ->
let acceleration = Vec.v 0. 9.81 in (* gravity *)
let velocity = Vec.(velocity + dt ~io * acceleration) in
let position = Vec.(position + dt ~io * velocity) in
Circle.draw ~io (Circle.v position 20.0);
(position, velocity)
module Ease : sig ... end

Easing functions, to smooth changes over time.

module Anim : sig ... end

Animations.

module Physics : sig ... end

Rigid physics for Shape objects.