The story of a subtle camera bug that hid in plain sight — and how I caught it.
Every game engine has bugs. Some are obvious — objects don't render, physics breaks, sounds don't play. Others are subtle — they only appear under specific conditions, and they're easy to miss.
This is the story of one of those subtle bugs.
I spent months building Limn Engine. I tested it on a Chromebook, a Toshiba laptop with 4GB of RAM, an HP laptop (behind my sister's back), and a Tecno Pop 4 with 1GB of RAM. The engine worked beautifully — 60 FPS on low-end hardware, smooth movement, responsive controls.
But there was a problem.
Click events didn't work when the camera moved.
I noticed it while testing a game with a scrolling map. Clicking on objects worked fine when the camera was at (0,0). But as soon as the camera followed the player, clicks stopped working. Objects that were clearly on screen weren't registering clicks.
I had already run the entire Limn Engine codebase through five major AI models — DeepSeek, ChatGPT, Claude, Gemini, and Grok — for evaluation and analysis. They all reviewed the code, provided feedback, and helped me optimize the engine.
None of them noticed the click bug.
They all looked at the clicked()
method and said it looked correct. They didn't consider that the mouse position was in screen space while the component positions were in world space.
So I fixed it myself.
Before I found the bug, I had already submitted Limn Engine for evaluation to the five major AI models:
| AI Model | What They Evaluated | What They Missed |
|---|---|---|
| DeepSeek | ||
| Full codebase, API design, performance | The camera offset in click events | |
| ChatGPT | ||
| Architecture, features, documentation | Screen space vs. world space mismatch | |
| Claude | ||
| Code quality, optimization suggestions | The missing + camera.x in event listeners |
|
| Gemini | ||
| Overall engine rating, strengths/weaknesses | Click detection with camera movement | |
| Grok | ||
| Performance analysis, edge cases | The space mismatch in clicked() |
|
All five models gave Limn Engine ratings between 88/100 and 94/100. They praised the dual-renderer system, the intuitive API, the comprehensive documentation, and the delta time fix.
But none of them caught the click bug.
| Space | What It Means | Example |
|---|---|---|
| Screen Space | ||
| Position relative to the visible screen | (100, 100) = 100 pixels from the top-left of the screen | |
| World Space | ||
| Position relative to the entire game world | (100, 100) = 100 pixels from the top-left of the world |
When the camera is at (0,0), screen space and world space are the same. But when the camera moves — say, to (100, 100) — the relationship changes.
window.addEventListener('mousedown', (e) => {
this.x = e.pageX; // ← Screen space
this.y = e.pageY; // ← Screen space
});
// In clicked():
clicked() {
const centerX = this.x + this.width / 2;
const centerY = this.y + this.height / 2;
// Uses display.x and display.y — both in screen space
const rotatedX = (display.x - centerX) * Math.cos(-this.angle) - (display.y - centerY) * Math.sin(-this.angle) + centerX;
// ...
}
The mouse position (display.x
and display.y
) was in screen space, but the component's position (this.x
and this.y
) was in world space. When the camera moved, these two spaces drifted apart, and clicks stopped working.
I asked five AI models to evaluate the code. Here's what they all missed:
| AI Model | What They Said | What They Missed |
|---|---|---|
| DeepSeek | ||
| "The click detection looks correct." | The camera offset | |
| ChatGPT | ||
| "The rotation math is good." | The space mismatch | |
| Claude | ||
"The clicked() method handles rotation well." |
||
| Screen vs. world | ||
| Gemini | ||
| "The component collision system is solid." | The missing + camera.x |
|
| Grok | ||
| "The event handling is clean." | The offset in mouse events |
None of them asked: "Wait, is display.x in screen space or world space?"
They assumed the code was correct because it looked like standard click detection. But standard click detection in most engines handles this automatically. In Limn Engine, it didn't.
The fix was simple once I understood the problem.
window.addEventListener('mousedown', (e) => {
this.x = e.pageX + this.camera.x; // ← World space
this.y = e.pageY + this.camera.y; // ← World space
});
window.addEventListener('touchstart', (e) => {
this.x = e.touches[0].pageX + this.camera.x; // ← World space
this.y = e.touches[0].pageY + this.camera.y; // ← World space
});
Two lines of code. That's all it took.
By adding the camera offset (+ this.camera.x
and + this.camera.y
), I converted the mouse position from screen space to world space right at the event listener level. Now display.x
and display.y
are always in world space, and clicked()
works correctly no matter where the camera is.
| Scenario | Before Fix | After Fix |
|---|---|---|
| Camera at (0,0) | Click works ✅ | Click works ✅ |
| Camera at (100, 100) | Click fails ❌ | Click works ✅ |
| Camera at (500, 300) | Click fails ❌ | Click works ✅ |
| Camera following player | Click fails ❌ | Click works ✅ |
AI is not infallible. Five major AI models missed this bug because they don't "think" about context — they just analyze code.
Testing beats theory. AI can analyze code structure, but only you can test the actual behavior.
Context matters. The same code can be correct in one context and wrong in another. Understanding the difference between screen space and world space is essential for game development.
Test with camera movement. Many bugs only appear when the camera moves. Always test your games with scrolling and camera following.
The simplest fix is often the best. Two lines of code fixed a bug that confused five AI models.
Trust yourself. I noticed the bug because I tested my game thoroughly. Don't rely on AI to catch everything — test your code.
The fixed code is live in the Limn Engine repository:
👉 Limn Engine Source Code (epic.js)
If you encounter any issues with Limn Engine, please report them on GitHub:
👉 https://github.com/terracodes004/limn-engine-doc/issues
| Concept | Why It Matters |
|---|---|
| Screen Space vs. World Space | |
| Mouse events are in screen space; game objects are in world space | |
| Camera Offset | |
Add camera.x and camera.y to convert mouse position to world space |
|
| AI Limitations | |
| Even five AI models can miss bugs that require contextual understanding | |
| Test with Camera Movement | |
| Bugs often appear only when the camera moves | |
| Trust Your Testing | |
| If something feels wrong, it probably is — test thoroughly |
Now that you understand screen space vs. world space, you can apply this knowledge to other areas of game development:
"I fixed a click bug by adding the camera offset to mouse events — two lines of code that five AI models (DeepSeek, ChatGPT, Claude, Gemini, and Grok) all missed."🎮🚀
Draw your game into existence — one frame at a time. 🎮🚀