DEV Community

Cover image for Announcing Limn Engine — A Lightweight 2D Game Framework for the Browser
Kehinde Owolabi
Kehinde Owolabi

Posted on • Originally published at limn-engine-doc.vercel.app

Announcing Limn Engine — A Lightweight 2D Game Framework for the Browser

Announcing Limn Engine

I'm excited to launch Limn Engine — a lightweight, zero-dependency HTML5 Canvas game framework for the browser. No npm install. No build step. No bloated dependency tree. Drop in a single script and start making 2D games.

The Core Idea: Display + Component

Limn Engine is built around two classes that cover 90% of what you need in a 2D game:

Display — The Game Shell

A singleton Display class that manages the canvas, runs the game loop, handles keyboard and mouse input, controls the camera, and manages scenes. Setting up a game is a one-liner:

const display = new Display();  
display.start(800, 600);  
Let me try creating it step by step.

Enter fullscreen mode Exit fullscreen mode

Component — Every Object in Your Game

A unified Component class that combines position, size, color/image, velocity, physics, and collision detection. No separate "Sprite" and "Body" classes — one object does it all.

const player = new Component(40, 40, "blue", 100, 100);
Enter fullscreen mode Exit fullscreen mode

Components support three modes:

  • Rectangle — solid color shapes for rapid prototyping
  • Image — loaded from spritesheets or single image files
  • Text — the Tctxt subclass for text elements with backgrounds, padding, and alignment

Key Features

Dual-Canvas High-Performance Rendering

Call display.perform() to activate dual-canvas mode. Static backgrounds and tilemaps are drawn once to an offscreen buffer, then composited as a single drawImage() call per frame. This dramatically reduces draw calls and improves frame rates for complex scenes.

display.perform();
display.start(800, 600);
Enter fullscreen mode Exit fullscreen mode

Tilemap Levels

Define game worlds as 2D arrays and initialize the tilemap engine with one call. Supports dynamic tile placement during gameplay — great for destructible environments and breakable blocks.

display.map = [
  [1, 1, 1, 1, 1],
  [1, 0, 0, 0, 1],
  [1, 0, 9, 0, 1],
  [1, 0, 0, 0, 1],
  [1, 1, 1, 1, 1]
];
display.tileMap();
Enter fullscreen mode Exit fullscreen mode

Sprite & AnimatedSprite

Load horizontal spritesheets and define named animation clips (idle, run, jump). Animations can loop, ping-pong, or play once — with frame timing and direction flipping built in.

const hero = new AnimatedSprite("hero.png", 64, 64, 400, 300);
hero.addAnimation("idle", 0, 3, 8, true);
hero.addAnimation("run",  4, 7, 12, true);
hero.play("idle");
Enter fullscreen mode Exit fullscreen mode

Physics & Collision Detection

Enable physics on any component with a single property. Built-in collision detection supports both AABB (rectangle) and circular hitboxes.

player.physics = true;
player.gravity = 0.5;
player.bounce = 0.3;

if (player.collide(platforms)) {
  player.posY = platform.y - player.height;
  player.speedY = 0;
}
Enter fullscreen mode Exit fullscreen mode

Background Effects

Build rich environments with linear and radial gradient backgrounds, solid colors, and a parallax skybox component for atmospheric depth.

display.lgradient("top", "royalblue", "midnightblue");
display.fullscreen();
Enter fullscreen mode Exit fullscreen mode

Audio

Built-in support for background music and sound effects to complete the game experience.

Why Limn?

There are plenty of game frameworks out there. Here's what makes Limn different:

  • Zero dependencies — No npm, no webpack, no node_modules. One file, one script tag.
  • Small footprint — Tiny enough to read through and understand in a single

Top comments (0)