Skip to content

Debugging Guide ​

Open the editor to debug issues live.

Common Errors ​

"No entry file found" ​

The project needs exactly one entry file. The default is main.js (shown with an entry badge). You cannot change entry in the UI — put your return in that file.

"Module 'xxx' not found" ​

Import specifier must match a file name in the explorer (with or without .js):

javascript
import { helper } from './utils';  // needs utils or utils.js

"Circular import detected" ​

A imports B and B (directly or indirectly) imports A. Extract shared code into a third leaf module.

Syntax errors / "Unexpected token" ​

Typical causes:

  • Missing } or )
  • Default or namespace imports (only named imports are supported)
  • Multiline import { ... } (keep on one line)
  • Top-level await

Named import { ... } from './file' is allowed in the entry file.

"xxx is not defined" ​

Only time, dt, state, w, h, and your imports exist in the entry. Modules do not see frame globals — pass them as arguments.

javascript
// BUG
return { particles: [{ x: x, y: 100 }] };

// FIX
const x = 100;
return { particles: [{ x, y: 100 }] };

"Cannot read property of undefined" ​

Missing init:

javascript
if (!state.init) {
  state.particles = [];
  state.init = true;
}
state.particles.push({ x: 100, y: 100 });

Simulation Behavior ​

Particle stays still ​

Position overwritten every frame, or using let instead of state:

javascript
state.x = (state.x ?? 100) + 50 * dt;

Particle teleports ​

Forgot dt:

javascript
state.x += 50 * dt;  // not state.x += 50

Jump after tab switch ​

dt is clamped to 50ms. If you still see jumps, check for custom time accumulation that ignores the clamp.

Nothing renders ​

You must return a FrameResult. While paused, the host stops the frame callback — expect a cleared canvas with grid/axes only.

Edits reset the sim ​

Recompile (~400ms after typing stops) clears state and time. That is intentional. Use Pause to freeze without clearing; Restart to clear without changing code.

Click does nothing ​

javascript
if (state.clickX !== undefined) {
  // handle
  state.clickX = undefined;
  state.clickY = undefined;
}

Avoid truthy checks alone if 0 could be a valid coordinate (rare, but !== undefined is safer).

Performance ​

  1. Cap primitive counts (see Performance Guidelines).
  2. Bound trail / particle arrays.
  3. Prefer squared distances in hot loops:
javascript
const perceptionSq = r * r;
const distSq = dx * dx + dy * dy;
if (distSq < perceptionSq) { /* ... */ }
  1. Show frame cost in the HUD:
javascript
return { text: { dt: (dt * 1000).toFixed(1) + 'ms' } };

Consistently > 16ms means the frame is overloaded.

Editor Issues ​

Code doesn't update ​

Wait for the 400ms debounce after typing.

Error won't clear ​

Fix the code, or click Restart. Persistent errors are real compile/runtime failures.

Red squiggles in Monaco ​

TypeScript does not know about injected globals. Squiggles are usually false positives. Add // @ts-nocheck at the top if they distract you.

Restart vs Reset ​

RestartReset
CodeKeptRestored to starter main.js
state / timeClearedCleared