🎮 Build Your First Game with Limn Studio — The Online Editor
Write, run, and test Limn Engine games directly in your browser — no setup required.
🎯 Live Demo
Try the editor right now: limn-engine-doc.vercel.app/editor
The editor comes pre-loaded with a working example — a player that moves around a tilemap. Click Run to see it in action!
🙏 Special Thanks
The Limn Studio editor was developed by Desire — check out their work on DEV.to. Their contribution made it possible to write and test Limn Engine code directly in the browser.
⚠️ Note: Limn Studio Is Still in Development
Before we dive in, a quick heads-up: Limn Studio is still under active development. It's already functional and you can build and test games in it, but you might encounter rough edges, missing features, or occasional bugs. If something doesn't work as expected, don't worry — it's being improved continuously.
With that said, let's build something!
📖 Introduction
Limn Studio is the online code editor for Limn Engine. It's designed to let you write, run, and test games directly in your browser — no downloads, no setup, no hassle.
Here's what we'll build in this tutorial:
- A simple red square that moves left and right
- Keyboard controls using the arrow keys
- A fully working game in just a few lines of code
All in about 10 lines of code.
🚀 Step 1: Open Limn Studio
Go to: limn-engine-doc.vercel.app/editor
You'll see a code editor with some pre-loaded code. This is a working example — you can click Run to test it right now.
📝 Step 2: Write Your First Code
Delete all the pre-loaded code and replace it with this:
const display = new Display();
display.perform(); // dual-canvas pipeline ON
display.start(800, 600);
const player = new Component(50, 50, "red", 400, 300, "rect");
display.add(player);
function update(dt) {
// Game logic goes here — dt = deltaTime
if (display.keys[39]) player.speedX = 4;
if (display.keys[37]) player.speedX = -4;
else player.speedX = 0;
}
🔍 Step 3: Understanding the Code
Let me walk you through each line so you understand what's happening.
1. Create the Display
What you're going to do: Create the foundation of your game — the Display object. This is the first and most important line of code in any Limn Engine game.
const display = new Display();
What this does: This creates a new game window. Think of it as telling the engine "I want a game." Without this line, nothing else works — it's the foundation of every Limn Engine game. The new Display() creates an instance of the Display class, which manages the canvas, rendering, and game loop. The display variable is what you'll use to control everything else.
2. Enable the Dual-Canvas Pipeline
What you're going to do: Activate the high-performance rendering mode. This switches the engine from a basic 50fps loop to a smooth 60fps loop.
display.perform(); // dual-canvas pipeline ON
What this does: This is crucial. It switches the engine from using setInterval (which runs at ~50fps) to requestAnimationFrame (which runs at a smooth 60fps). Without this, your game will feel stuttery. Think of it as upgrading from a bumpy dirt road to a smooth highway. The dual-canvas pipeline also caches static content for better performance.
3. Start the Display
What you're going to do: Create the actual canvas on your page with a specific size.
display.start(800, 600);
What this does: This creates the canvas with a size of 800x600 pixels. The two numbers are width and height — you can change them to make the game bigger or smaller. If you want a full-screen game, you can use display.start(window.innerWidth, window.innerHeight).
4. Create the Player
What you're going to do: Create a game object — a red square that will represent the player.
const player = new Component(50, 50, "red", 400, 300, "rect");
What this does: This creates a component — a game object. The five parameters are: width, height, color, x position, and y position. So this creates a 50x50 red square at position (400, 300). The "rect" at the end means it's drawn as a rectangle. Components are the building blocks of every Limn Engine game — players, enemies, coins, walls, and more are all Components.
5. Add the Player to the Display
What you're going to do: Make the player visible by adding it to the display's render list.
display.add(player);
What this does: This is crucial! Without this, the player exists in memory but never appears on screen. Think of it like creating a character in a game but never spawning them into the world — they exist in the code but have no presence in the game. The display.add() method adds the component to the engine's render list, which means it will be drawn every frame. This is one of the most common mistakes beginners make — forgetting to add their components.
6. The Game Loop
What you're going to do: Write the update function that runs every frame and handles player movement.
function update(dt) {
// Game logic goes here — dt = deltaTime
if (display.keys[39]) player.speedX = 4;
if (display.keys[37]) player.speedX = -4;
else player.speedX = 0;
}
What this does: The update function runs every frame — 60 times per second. Here's what's happening:
-
dt(delta time) is the time between frames — it ensures movement is frame-rate independent -
display.keys[39]— 39 is the keycode for the Right Arrow key -
display.keys[37]— 37 is the keycode for the Left Arrow key - If the right arrow is pressed, the player moves right at speed 4
- If the left arrow is pressed, the player moves left at speed -4
- If neither is pressed, the player stops
The display.keys object tracks all key states — it's updated automatically by the engine.
🎮 Step 4: Run the Game
Click the Run button in Limn Studio. You should see:
- A dark canvas with a red square in the center
- The red square moves left and right when you press the arrow keys
🔧 Step 5: Customize the Game
Try making these changes to see how the engine responds. Each change teaches you something new about Limn Engine.
🔴 Change the Player Color
What you're going to do: Change the player's color from red to blue. The color is the third parameter in the Component constructor.
const player = new Component(50, 50, "blue", 400, 300, "rect");
What you just did: You changed the "red" to "blue". This tells the engine to draw the player as a blue square instead of a red one. You can use any CSS color name ("red", "blue", "green", "yellow", etc.) or hex codes ("#ff0000", "#00ff00", "#0000ff", etc.). This is useful for customizing the look of your game objects.
📏 Change the Player Size
What you're going to do: Make the player bigger by changing its width and height from 50 to 80. The first two parameters in the Component constructor control size.
const player = new Component(80, 80, "red", 400, 300, "rect");
What you just did: You changed the first two numbers from 50, 50 to 80, 80. This tells the engine to draw the player as an 80x80 square instead of a 50x50 one. The player is now 60% larger. This is useful for making objects more visible or easier to hit.
🏃 Change the Player Speed
What you're going to do: Make the player move faster by increasing the speed value from 4 to 8. The speed is the number you assign to player.speedX.
if (display.keys[39]) player.speedX = 8;
if (display.keys[37]) player.speedX = -8;
What you just did: You changed the speed from 4 to 8. The player now moves twice as fast. Speed in Limn Engine is measured in pixels per frame (when not using dt). Larger numbers = faster movement. This is useful for adjusting the feel of your game — faster for action games, slower for puzzle games.
🎯 Add Up and Down Movement
What you're going to do: Add support for the Up and Down arrow keys so the player can move in all four directions. You'll need to add player.speedY and check for keys 38 (Up) and 40 (Down).
function update(dt) {
player.speedX = 0;
player.speedY = 0;
if (display.keys[39]) player.speedX = 4;
if (display.keys[37]) player.speedX = -4;
if (display.keys[38]) player.speedY = -4;
if (display.keys[40]) player.speedY = 4;
}
What you just did: You added two new conditions — one for the Up arrow (key 38) and one for the Down arrow (key 40). You also added player.speedY to control vertical movement. Now the player moves in all four directions: Up, Down, Left, and Right. This is useful for creating more complex games where the player needs full control.
🎮 Full Four-Way Movement with Diagonal Normalization
What you're going to do: Add proper diagonal movement normalization so the player doesn't move faster when going diagonally. This is a common physics fix in game development.
function update(dt) {
let mx = 0, my = 0;
if (display.keys[39] || display.keys[68]) mx = 1;
if (display.keys[37] || display.keys[65]) mx = -1;
if (display.keys[40] || display.keys[83]) my = 1;
if (display.keys[38] || display.keys[87]) my = -1;
// Normalize diagonal movement
if (mx !== 0 && my !== 0) {
mx *= 0.707;
my *= 0.707;
}
const speed = 200;
player.speedX = mx * speed * dt;
player.speedY = my * speed * dt;
}
What you just did: You added WASD support (keys 68, 65, 83, 87) alongside the arrow keys. More importantly, you added diagonal normalization — when both mx and my are non-zero, you multiply them by 0.707 (which is 1/√2). This prevents the player from moving faster when moving diagonally. Without this, diagonal movement would be about 1.4 times faster than horizontal or vertical movement. This is a fundamental principle of game physics and one of the most common "beginner traps."
📊 What You've Learned
| Concept | Why It Matters |
|---|---|
| Display | The foundation of every Limn Engine game — creates the canvas and runs the game loop |
| Component | Every visible game object — player, enemies, coins, walls |
| display.add() | Without this, your component exists but never appears |
| update(dt) | The game loop — runs every frame, dt ensures frame-rate independence |
| display.keys | Keyboard input — check if a key is pressed using its keycode |
| deltaTime (dt) | Ensures movement is frame-rate independent — the game runs at the same speed on all devices |
| Diagonal Normalization | Prevents faster diagonal movement — multiply by 0.707 when moving diagonally |
🔑 Keycodes Reference
| Key | Keycode |
|---|---|
| Left Arrow | 37 |
| Up Arrow | 38 |
| Right Arrow | 39 |
| Down Arrow | 40 |
| A | 65 |
| W | 87 |
| D | 68 |
| S | 83 |
| Space | 32 |
| Enter | 13 |
🚀 What's Next?
Now that you've built your first game in Limn Studio, try these next steps:
- Add enemies that chase the player
- Add coins to collect
- Add a scoring system
- Add a game-over screen
- Build the complete space shooter game from the tutorial
🔗 Resources
| Resource | Link |
|---|---|
| Limn Studio (Editor) | limn-engine-doc.vercel.app/editor |
| Limn Engine Docs | limn-engine-doc.vercel.app |
| Space Shooter Tutorial | DEV.to Tutorial |
| Ball Game Tutorial | DEV.to Tutorial |
| Level 1 Beginner Guide | DEV.to Tutorial |
| Limn Engine GitHub | github.com/terracodes004/limn-engine-doc |
| Report Bugs | GitHub Issues |
🎯 The One-Line Summary
"Limn Studio lets you write and run Limn Engine games in your browser — no setup required. Developed by Desire, it's still in development but already works!" 🎮🚀
Draw your game into existence — one line of code at a time. 🎮🚀


Top comments (0)