🗒 API Reference

Display L1

The Display class is the heart of every Limn Engine game. It creates the canvas, runs the game loop, captures input, manages the camera, and controls which scene is active. Every game must create exactly one Display instance and name it display (lowercase) for internal systems to find it.
📖 Full reference & examples

Constructor

const display = new Display();

Creates a new display manager. The canvas is not yet created — you must call .start() to begin.

Properties

PropertyTypeDescription
.canvasHTMLCanvasElementThe game canvas (created after .start()).
.contextCanvasRenderingContext2DThe 2D drawing context — use for custom drawing.
.keysArrayBoolean array indexed by keyCode — true while key is pressed.
.sceneNumberCurrent active scene (0 by default). Only components with matching scene render.
.cameraCameraThe attached camera instance — controls viewport.
.deltaTimeNumberTime since last frame (seconds). Use for frame‑rate independent movement.
.fpsNumberCurrent frames per second (updated every second).
.frameNoNumberTotal frames elapsed since game started.
.x / .yNumber | falseMouse/touch position while pressed, false otherwise.

Methods

.start(width, height, parentNode)

Initialises the canvas and starts the game loop. Parameters: width (default 480), height (default 270), parentNode (default document.body). After this call, the canvas appears on the page and update() is called every frame.

display.start(800, 600); // Creates an 800x600 canvas

.perform()

Activates high‑performance dual‑canvas rendering. Must be called before .start(). It replaces the basic interval loop with requestAnimationFrame and creates an offscreen fake canvas for static backgrounds and tilemaps.

display.perform();
display.start(800, 600); // Now using dual‑canvas mode

.add(component, sceneId)

Registers a component into the engine. The component will be updated and drawn every frame, but only if its assigned sceneId matches the current display.scene value.

const player = new Component(40, 40, "blue", 100, 100);
display.add(player, 1); // Adds to scene 1 (gameplay)

.backgroundColor(color)

Sets a solid CSS colour behind the canvas. Useful as a fallback or for simple games.

display.backgroundColor("#0a0a2a"); // Dark blue background

.lgradient(direction, color1, color2)

Applies a linear gradient background. direction can be "top", "right", "bottom", "left", or combinations like "top left".

display.lgradient("top", "royalblue", "darkblue");

.rgradient(color1, color2)

Applies a radial gradient background, centred on the canvas. Creates a circular glow effect from the centre outward.

display.rgradient("#ffaa00", "#442200"); // Sunburst effect

.stop()

Halts the game loop immediately. Use when the game ends or for debugging.

if (player.health <= 0) display.stop();

.scale(width, height)

Resizes the canvas after the game has started. Updates .clearMargin and the culling area accordingly.

display.scale(1024, 768); // Switch to full HD

.fullScreen() / .exitScreen()

Requests full‑screen mode or exits it. Uses the browser's fullscreen API.

display.fullScreen(); // Enter fullscreen mode

.borderStyle(style) / .borderSize(size) / .borderColor(color)

Styles the canvas border. Useful for debugging or for a polished embedded look.

display.borderStyle("solid");
display.borderSize("4px");
display.borderColor("white");

.tileMap()

Initialises the TileMap system from display.map and display.tile. Creates the display.tileFace object.

Pro tip: Always name your main Display instance display (lowercase) – the engine relies on this name internally for culling and camera systems.

Component L1

Every visible or interactive object in Limn Engine is a Component. It combines position, size, appearance, velocity, physics, and collision detection in one unified object — no separate “sprite” and “body” classes.
📖 Full reference & examples

Constructor

new Component(width, height, color, x, y, type)

Creates a game object. type can be "rect" (default), "image", or "text". For images, set color to the image path and later call .setImage(). For rich text, use Tctxt instead.

const player = new Component(40, 40, "blue", 100, 100);
const coin = new Component(30, 30, "gold", 200, 300);
const label = new Component("24px", "Arial", "white", 50, 50, "text");

Properties

PropertyTypeDescription
.x , .yNumberPosition in world coordinates (pixels).
.aX , .aYNumberAnchor position for .fixed() method (usually the initial spawn point).
.width , .heightNumberDimensions in pixels.
.speedX , .speedYNumberVelocity in pixels per second (when using delta‑time movement).
.angleNumberRotation angle in radians.
.angularMovementBooleanIf true, moveAngle() is used instead of move() — moves along .angle direction.
.physicsBooleanIf true, gravity is applied to gravitySpeed each frame.
.gravityNumberDownward acceleration (pixels per frame²).
.gravitySpeedNumberCurrent vertical speed (affected by gravity).
.bounceNumberEnergy retained after hitting ground (0 = no bounce, 1 = perfect bounce).
.changeAngleBooleanIf true, the component is drawn rotated by .angle.
.isCircleBooleanSet by .enableCircleCollision() – uses circular hitbox.

Methods

.setImage(src)

Loads an image and switches the component to image mode. Falls back to a red rectangle on error.

player.setImage("assets/hero.png");

.setColor(newColor)

Switches back to rectangle/colour mode. Useful for power‑ups or debugging.

player.setColor("red"); // Temporary damage colour

.setText(text, font, color)

Switches the component to text mode. For rich text with backgrounds, use Tctxt instead.

label.setText("Score: 100", "24px Arial", "white");

.crashWith(other)

Rectangle (AABB) collision detection. Returns true if the bounding boxes overlap. Takes rotation into account.

if (player.crashWith(coin)) { score++; }

.enableCircleCollision(radius)

Enables circular collision detection. Sets .isCircle = true and stores the radius.

coin.enableCircleCollision(15);

.crashWithCircle(other)

Circle‑to‑circle or circle‑to‑rectangle collision. Use after enabling circle collision. Automatically falls back to rectangle detection if needed.

if (bullet.crashWithCircle(orb)) { explode(); }

.fixed(ctx)

Locks the component to the camera view. Call this every frame inside update() to make UI elements stay in place while the world scrolls. Pass fake as argument for fake canvas components.

healthBar.fixed(); // Health bar follows camera

.hide() / .show()

Hides or shows the component. Hidden components are not drawn, but they still run their logic.

enemy.hide(); // Enemy disappears but still moves

.destroy()

Permanently removes the component from the engine. Splices it out of both comm and commp arrays and nullifies its update method. Critical for memory management.

bullet.destroy(); // Completely removes the bullet

.move()

Updates position based on speed and gravity. Called automatically by the engine each frame – you should not need to call it manually unless angularMovement is true.

.moveAngle()

Moves the component along its current angle direction. Used for angular movement (e.g., orbiting, turning). Set .angularMovement = true on the component to enable this automatically.

orbiter.angularMovement = true; // Now moves according to .angle

.hitBottom(groundY)

Clamps the component to a ground level and applies bouncing. Call this in update() for platformers. Optionally pass a custom ground Y.

player.hitBottom(display.canvas.height - player.height);

.clicked()

Returns true if the component was clicked or tapped. Takes rotation into account.

if (button.clicked()) { startGame(); }

Pro tip: Components are extremely flexible – you can animate them by changing .x, .y, .angle, and .color directly every frame.

Camera L2

The Camera class defines what part of the game world is visible on screen. It can follow a target, zoom in/out, and create shake effects. Every Display instance contains its own camera.
📖 Full reference & examples

Constructor

new Camera(x, y, worldWidth, worldHeight)

Creates a camera with a world boundary. Usually you don’t create cameras manually – they are automatically created by Display.

Properties

.x , .yCamera position in world coordinates.
.worldWidth , .worldHeightSize of the game world (camera will not show outside these bounds).
.rotationShakeCurrent rotational shake angle (used internally).

Methods

.follow(target, smooth)

Makes the camera track a component. If smooth is true, the camera moves with a 10% lerp (easing) for a gentle lag. false gives instant centering.

display.camera.follow(player, true); // Smooth follow

.setZoom(scale)

Changes the canvas draw scale. 1 = normal, 2 = zoom in (closer), 0.5 = zoom out. Call this every frame to maintain zoom.

display.camera.setZoom(1.5); // 150% zoom

.shake(intensityX, intensityY)

Adds a temporary, random screen shake. The camera oscillates around its target position for about one frame. Use small values (3–5) for subtle impacts, 10+ for explosions.

display.camera.shake(8, 8); // Shake 8px in both axes

.shakeRotation(angleRadians)

Rotational shake. The canvas rotates back and forth by the given angle (e.g., 0.05 radians) for about one frame. Great for heavy hits.

display.camera.shakeRotation(0.07);

Pro tip: For long shakes, call shake() repeatedly over several frames, or use a timer to call it every frame for a duration.

move utility L1

move is a global object that provides ready‑made kinematic functions for common game motions. Instead of writing manual trigonometry or interpolation, you call one readable function like move.glideTo() or move.pointTo().
📖 Full reference & examples

Movement methods

move.bound(obj)

Prevents an object from leaving the canvas edges. Clamps both x and y to the visible area.

move.bound(player); // Keeps player on screen

move.boundTo(obj, left, right, top, bottom)

Clamps an object to custom boundaries. Pass false for any side you don’t want to restrict.

move.boundTo(player, 50, 750, 100, 500); // Confined to arena

move.forward(obj, steps) / move.backward(obj, steps)

Moves the object along its current angle. Inspired by Python Turtle – very intuitive for angular movement.

move.forward(player, 5); // Moves 5 pixels in direction of .angle

move.turnLeft(obj, radians) / move.turnRight(obj, radians)

Rotates the object by a given angle. Works with .changeAngle = true (the default).

move.turnLeft(turret, 0.1); // Rotate left by 0.1 rad

move.teleport(obj, x, y)

Instantly moves the object to new coordinates.

move.teleport(player, 400, 300); // Center the player

move.stamp(obj)

Creates a clone of the object at its current position. Useful for particle‑like duplication.

const clone = move.stamp(enemy);

move.glideX(obj, durationMs, targetX)

Moves the object horizontally from its current x to targetX over durationMs milliseconds. Uses cubic ease‑out for smooth deceleration.

move.glideX(coin, 500, 800); // Glide to x=800 in 0.5 seconds

move.glideY(obj, durationMs, targetY)

Same as glideX but for vertical movement.

move.glideY(platform, 1000, 400); // Move down to y=400 in 1 second

move.glideTo(obj, durationMs, targetX, targetY)

Simultaneous X and Y glide. Smoothly moves the object to a point. Ideal for enemy movement or UI animations.

move.glideTo(player, 800, 600, 300);

move.project(obj, speed, angleDeg, gravity, groundY)

Launches the object as a projectile. speed in pixels per second, angleDeg from horizontal (0° = right, 90° = up). gravity is added each frame. Optionally bounces off groundY.

move.project(arrow, 300, 45, 0.5); // Arcing arrow

move.pointTo(obj, targetX, targetY)

Rotates the object to face the given world coordinates. Uses Math.atan2 and sets the .angle property.

move.pointTo(turret, mouse.x, mouse.y);

move.circle(obj, angularSpeedRad)

Updates the object's angle for circular motion. Use with angularMovement = true to create orbiting or circular motion.

move.circle(orbiter, 0.05);

move.accelerate(obj, accelX, accelY, maxSpeedX, maxSpeedY)

Adds acceleration to the object's speed, capping at maximum values. Perfect for smooth vehicle movement or wind effects.

move.accelerate(player, 0.5, 0, 8, 8);

move.decelerate(obj, decelX, decelY)

Reduces speed toward zero by the given amounts per frame. Useful for friction or braking.

move.decelerate(player, 0.3, 0.3); // Slows down gradually

move.position(obj, direction, offset)

Snaps the object to a screen edge or the centre. Directions: "top", "bottom", "left", "right", "center". Offset is optional margin.

move.position(healthBar, "top", 20); // Place near top edge

state utility L1

state provides read‑only query functions for components and game status. These helpers let you inspect positions, distances, and physics flags without directly accessing properties.
📖 Full reference & examples

Methods

state.distance(a, b)

Returns the Euclidean distance (in pixels) between the centres of two components. Useful for proximity triggers or enemy AI range checks.

if (state.distance(player, enemy) < 50) { attack(); }

state.rect(obj)

Returns an array [x, y, width, height] representing the component's axis‑aligned bounding box. Useful for debugging or manual collision.

const rect = state.rect(player); // [x, y, w, h]

state.physics(obj)

Returns true if the component has physics = true. Helps decide when to apply custom forces.

state.changeAngle(obj)

Returns the current state of the changeAngle flag. Indicates whether the component will rotate when drawn.

state.Angle(obj)

Returns the current angle (in radians). Useful for custom rendering or projectile aiming.

const angle = state.Angle(turret);

state.pos(obj)

Returns a formatted string "x,y" for quick logging or saving.

console.log("Player at: " + state.pos(player));

TileMap L2

TileMap turns a 2D array of numbers into a grid of interactive components. It's designed for level design without external tools – you write levels directly in JavaScript. Tiles become full Component instances, so they can have collision, images, and even movement.
📖 Full reference & examples

Setup

// Define tile templates (index 0 is always empty)
display.tile = [
    new Component(32, 32, "black", 0, 0), // ID 0 (empty)
    new Component(32, 32, "green", 0, 0), // ID 1 (grass)
    new Component(32, 32, "brown", 0, 0)  // ID 2 (dirt)
];

// Build a level (row × column)
display.map = [
    [1,1,1,1,1],
    [1,0,2,0,1],
    [1,1,1,1,1]
];

// Initialise the tilemap system
display.tileMap();           // Creates display.tileFace
display.tileFace.show();     // Renders the level

Methods

.tiles(tileId)

Returns an array of all tiles. If tileId is given, only tiles with that ID are returned. Useful for grouping walls or coins.

const allWalls = display.tileFace.tiles(1);

.crashWith(obj, tileId)

Checks collision between obj and any tile (or only tiles with tileId). Returns boolean.

if (display.tileFace.crashWith(player, 1)) { /* hit a wall */ }

.add(tileId, tx, ty, layer)

Places a tile at grid column tx, row ty on the specified layer. Then calls .show() and fake.refresh() to update the cache. Great for destructible blocks.

display.tileFace.add(2, 5, 3, 0); // Place dirt at (5,3) on layer 0

.remove(tx, ty, layer)

Removes the tile at the specified grid position on the given layer. Same refresh behaviour as .add().

display.tileFace.remove(5, 3, 0); // Delete tile

.rTile(tx, ty)

Returns the actual Tile component at grid column tx, row ty, or null if empty. Useful for inspecting tile properties at runtime.

const tile = display.tileFace.rTile(2, 1);
tile.color = "red"; // Change tile colour dynamically

.addMap(layerMap)

Adds a new layer to the tilemap. The engine supports swicthable multiple layers tile world.

display.tileFace.addMap([ [1,1], [0,1] ]);

.show(layer)

Renders the specified layer into the fake canvas buffer. Call show(1) to swicth layers.

Tctxt L1

Tctxt is a specialised text component with built‑in background, padding, alignment, and stroke support. It extends Component and behaves like any other game object – you can move it, rotate it, and even animate it.
📖 Full reference & examples

Constructor

new Tctxt(size, font, color, x, y, align, stroke, baseline, bgColor, padX, padY)

Creates a styled text label. Parameters:

  • size – font size (e.g., "24px")
  • font – font family (e.g., "Arial")
  • color – text colour (e.g., "white")
  • x, y – position
  • align"left", "center", or "right"
  • stroketrue for outline, false for fill
  • baseline"alphabetic", "top", "middle", etc.
  • bgColor – background colour (or null for transparent)
  • padX, padY – padding around text
const scoreUI = new Tctxt("24px", "Arial", "white", 20, 40, "left", false, "alphabetic", "rgba(0,0,0,0.5)", 10, 5);
scoreUI.setText("Score: 0");
display.add(scoreUI);

Methods

.setText(newText)

Changes the displayed string. Automatically updates the background rectangle size. Returns the new text for chaining.

scoreUI.setText("Score: " + score);

.fixed()

Locks the text to the camera view. Call this each frame to keep the text at a fixed screen position.

scoreUI.fixed(); // Score follows camera

Sound L1

The Sound class loads and plays a single audio file. It handles overlapping sounds automatically by cloning, so you can fire the same effect many times without cutting off previous instances.
📖 Full reference & examples

Constructor

new Sound(src, options)

Creates a sound object. Options include volume (0–1), loop (boolean), and autoplay.

const jumpSound = new Sound("jump.wav", { volume: 0.7 });

Methods

.play(volume)

Plays the sound. If the sound is already playing and loop is false, creates a clone to allow overlapping. Optionally override the volume.

jumpSound.play();

.stop()

Stops the sound and resets its playback position to the beginning.

.pause()

Pauses the sound at its current position.

.setVolume(value)

Changes the volume (0.0 to 1.0) of the sound instance. Does not affect clones already playing.

.setLoop(loop)

Enables or disables looping.

.isPlaying()

Returns true if the sound is currently playing.

SoundManager L4

SoundManager is a central hub for loading, organising, and mixing multiple sounds. It separates music from sound effects, provides global volume controls, and preloads assets to avoid delays during gameplay.
📖 Full reference & examples

Constructor

window.soundManager = new SoundManager();

Creates a sound manager instance. Store it globally for easy access.

Methods

.load(name, src, options)

Loads a sound and assigns it a name key. The same options as Sound constructor.

.preload(soundList, callback)

Loads multiple sounds in parallel. Each element should be {name, src, options}. Calls callback when all are ready.

.play(name, volume)

Plays the sound associated with name. Uses sfxVolume by default (unless the name starts with "music_", then it uses musicVolume).

.stop(name)

Stops a specific sound by name.

.playMusic(name, loop)

Stops any currently playing music and starts the new track. Looping is enabled by default.

.stopMusic()

Stops the current background music.

.setMasterVolume(value)

Global volume multiplier (0–1) applied to all sounds and music.

.setSFXVolume(value)

Sets the volume for sound effects (0–1).

.setMusicVolume(value)

Sets the volume for background music (0–1).

.mute() / .unmute()

Silences all audio without unloading assets.

ParticleSystem L3

ParticleSystem creates and manages hundreds of small visual effects like sparks, smoke, or explosions. It automatically handles physics, fading, and removal, so you only need to emit particles or create emitters.
📖 Full reference & examples

Constructor

const ps = new ParticleSystem(display);

Creates a particle manager linked to a specific display. Call .update() every frame inside your game's update() function.

Methods

.emit(x, y, options)

Creates a single particle. Options can include life (frames), gravity, alphaFade, speedX/Y, color, type ("rect", "circle").

.burst(x, y, count, options)

Emits count particles at once. Perfect for explosions.

.createEmitter(x, y, options)

Creates a continuous emitter that produces particles every frame. The returned object has start(), stop(), and setPosition() methods. options.rate controls particles per second.

.update()

Must be called every frame. Advances all particles, fades them, and removes dead ones. Also updates emitters.

.clear()

Removes all particles and emitters.

Built-in Presets (via move.particles)

PresetCall
explosionmove.particles.explosion(ps, x, y, intensity)
smokemove.particles.smoke(ps, x, y)
sparklemove.particles.sparkle(ps, x, y)
rainmove.particles.rain(ps, x, y, intensity)
bloodmove.particles.blood(ps, x, y, amount)
magicmove.particles.magic(ps, x, y)

Sprite & AnimatedSprite L2

Sprite turns a horizontal sprite sheet into an animated component. AnimatedSprite extends it with named animation clips (idle, run, jump) that you can switch by name.
📖 Full reference & examples

Sprite Constructor

new Sprite(image, frameWidth, frameHeight, frameCount, frameSpeed, x, y)

Creates a sprite from a spritesheet. frameCount is the number of frames in the sheet, frameSpeed controls animation speed (lower = faster).

AnimatedSprite Constructor

new AnimatedSprite(image, frameWidth, frameHeight, x, y)

AnimatedSprite Methods

.addAnimation(name, startFrame, endFrame, speed, loop)

Defines a named animation clip. startFrame and endFrame are zero‑based indices. loop determines whether it repeats.

.playAnimation(name)

Switches to the named animation. The sprite will start from the first frame of that clip.

.updateAnimation()

Advance the frame counter. Must be called every frame in update().

.faceLeft() / .faceRight()

Flip the sprite horizontally without changing the underlying frames.

const hero = new AnimatedSprite("hero.png", 64, 64, 400, 300);
hero.addAnimation("idle", 0, 0, 1, true);
hero.addAnimation("run", 1, 4, 6, true);
hero.addAnimation("jump", 5, 6, 4, false);
display.add(hero);

function update() {
    if (moving) hero.playAnimation("run");
    else hero.playAnimation("idle");
    hero.updateAnimation();
}

Fake Canvas & bgComm L4

The fake canvas is an offscreen buffer used for high‑performance dual‑canvas rendering. Static content (tilemaps, backgrounds) renders once to the fake canvas, then is drawn as a single image each frame. fake.bgComm is a special component that renders behind everything else – perfect for skies, parallax backgrounds, and ambient effects.
📖 Full reference & examples

What is the Fake Canvas?

When you call display.perform(), the engine creates a hidden canvas called fake. Any component added with fake.add() is rendered to this offscreen buffer instead of the main display. The buffer is then drawn to the main canvas using drawImage(fake.canvas, 0, 0) – a single extremely fast operation.

What is fake.bgComm?

fake.bgComm is a special background component that renders before anything else on the fake canvas. It is drawn before tilemaps, foreground objects, and all other fake canvas content – making it perfect for skyboxes, distant mountains, clouds, or any scenery that should appear behind the game world.

Properties

PropertyTypeDescription
fake.bgCommComponent | falseIf set to a Component, that component renders behind everything else on the fake canvas.
fake.sceneNumberCurrent scene of the fake canvas – only components with matching scene are rendered.

Methods

fake.add(component, scene)

Adds a static component to the fake canvas. The component will be rendered once (or when the cache refreshes) and is perfect for background walls, decorations, or any object that doesn't move.

fake.refresh()

Forces the fake canvas to redraw on the next frame. Call this after making changes to static components (e.g., destroying a wall) to update the cached image.

Usage Example

// Activate dual-canvas mode
display.perform();
display.start(800, 600);

// Set a sky background that renders behind everything
fake.bgComm = new Component(1600, 1200, null, 0, 0, "image");
fake.bgComm.setImage("sky.png");

// Add clouds that also render behind tiles
const clouds = new Component(1600, 400, null, 0, 100, "image");
clouds.setImage("clouds.png");
fake.add(clouds);

// Tilemap renders on top of bgComm and clouds
const tilemap = new TileMap(display, level, tiles, 1600, 1200);
tilemap.show();

// Trees and decorations render on top of tilemap
const tree = new Component(64, 64, null, 400, 300, "image");
tree.setImage("tree.png");
fake.add(tree);

// Player renders on main display (top layer)
const player = new Component(36, 36, "blue", 400, 200);
display.add(player);

Render Order

  1. fake.bgComm – lowest layer (sky, distant scenery)
  2. tileComm – tilemap layers (ground, walls)
  3. commp – other fake canvas components (trees, decorations)
  4. comm – main display components (player, enemies, UI with .fixed())
💡 Use fake.bgComm for large, static background images – it renders only once and requires no per‑frame updates, making it extremely performant.
⚠️ Components added to fake are not automatically updated – they are static. Only use fake.add() for objects that don't move. Dynamic objects (players, enemies, moving platforms) must go to display.add().

Key Code Table

Use these numeric codes with display.keys[keyCode] to detect key presses. The array is updated automatically by the engine. Check it inside your update() function every frame.
see full table...
KeyCodeKeyCode
← Left Arrow37A65
↑ Up Arrow38W87
→ Right Arrow39D68
↓ Down Arrow40S83
Space32Enter13
Escape27Shift16
Z90X88
F70M77
0–948–57F1–F12112–123

Tip: For WASD controls, use codes 65 (A), 87 (W), 68 (D), 83 (S) – they are adjacent on most keyboards and comfortable for left‑hand movement.