glemy
A small 2D circle-physics/game engine for Gleam,
targeting both the Erlang and JavaScript runtimes. Follows a
Functional Core, Imperative Shell
split: glemy/physics and its submodules are pure Gleam (entities, an
axis-aligned bounding box, gravity, integration, and a pairwise
collision sweep with a caller-supplied interaction rule), fully tested
with plain gleam test on both targets; render/io are the thin,
@target(javascript)-gated Shell that draws entities to a real WebGPU
canvas and polls keyboard/mouse input.
glemy itself ships no game — see glemy-games for three reference games (Tiers, Breakout, Platformer) built on it, and the live demo to try them in a browser.
Installing
Not yet published to Hex. Until then, depend on it directly from GitHub, pinned to a commit (Gleam’s own recommended practice over a branch or tag):
[dependencies]
glemy = { git = "https://github.com/recregt/glemy", ref = "<commit-sha>" }
Usage
import glemy/physics
import glemy/physics/bounds.{Bounds}
import glemy/physics/collision_sweep.{Bounce}
import glemy/physics/entity.{Entity}
import glemy/physics/vector2.{Vector2}
pub fn main() {
let bounds = Bounds(min: Vector2(0.0, 0.0), max: Vector2(100.0, 100.0))
let model =
physics.Model(entities: [], bounds: bounds, gravity: Vector2(0.0, -9.8))
|> physics.spawn_entity(Entity(
position: Vector2(50.0, 90.0),
velocity: vector2.zero,
radius: 5.0,
kind: 0,
resting_time: 0.0,
))
// Advance one frame: integrate under gravity, bounce off `bounds`,
// and resolve any overlaps as plain elastic bounces (`Bounce`) --
// pass your own function instead of `fn(_a, _b) { Bounce }` to merge,
// destroy, or otherwise react to a specific pair of entities.
let #(next_model, _events) =
physics.update(model, 1.0 /. 60.0, bounds.bounce, fn(_a, _b) { Bounce })
physics.entity_count(next_model)
}
See ARCHITECTURE.md for where new code goes and why, and
docs/technical-architecture.md for the project-level architecture
spanning this repo, glemy-games, and glemy-website.
Developing
gleam test --target erlang
gleam test --target javascript
deno task check-warnings
See CLAUDE.md for the full verification checklist this project holds
every change to.