A Zero-Friction Entry VS Code extension for Love2D projects that launches through a bootstrap layer, watches Lua changes, and logs the reload path in the VS Code output channel.
- Smart File Watcher: Automatically detects changes and triggers hot-swaps for Lua code or restarts for assets.
- Gitignore Integration: Automatically respects your
.gitignorerules while allowing manual overrides. - Flexible Watch Scopes: Choose between watching only the active app folder or the entire project workspace.
- Process Management: Integrated process control with stdout/stderr piped to the VS Code Output Channel.
- Visual Feedback: Real-time status bar updates for running and stopped states.
- Granular Log Filtering: Control exactly which logs appear in the output channel by scope (
app,bridge), level (info,warn,error), or combinations (app:warn).
- Launch: Open a Love2D workspace and click the
$(debug-start) Love2Dbutton in the status bar or run the Love2D: Run Game command. - Auto-Reload: Any change to a
.luafile is hot-swapped via the bridge. Changes to assets (images, shaders, etc.) trigger a full game restart. - Inspect Logs: Open the
Love2Doutput channel to see[love2d]and[watcher]diagnostics for change detection and reload actions.
Project configuration is completely optional. If no project config exists, Love2D Forge uses these defaults:
proxyErrorLogs: trueinferLogTypes: trueautoDiscovery: trueautoDiscoverySearchDepth: 2locations: undefinedwatchScope: "location"logFilter: ["info", "warn", "error"]fileLogs.enabled: falsefileLogs.outputFile: "love2d.log"fileLogs.logLines: 1000fileLogs.sessionClear: falsefileLogs.reloadClear: false
When you want a project config, run Love2D: Init Config. This creates .love2d-forge/config.json.
Example:
{
"proxyErrorLogs": true,
"inferLogTypes": true,
"autoDiscovery": true,
"autoDiscoverySearchDepth": 2,
"locations": [
"apps/game",
"tools/editor"
],
"watchScope": "project",
"watchExclude": ["temp/**", "old_assets/**"],
"logFilter": ["app", "bridge:warn"],
"fileLogs": {
"enabled": false,
"outputFile": "love2d.log",
"logLines": 1000,
"sessionClear": false,
"reloadClear": true
}
}How it works:
-
proxyErrorLogsenables advanced error handling by proxying Love calls so critical errors are always logged. -
inferLogTypesclassifies bridged Luaprint()messages by prefixes likeerror:,warn:, orinfo:. -
autoDiscoveryscans formain.luawhenlocationsis not configured. -
locationsoptionally points to one or more app folders ormain.luafiles. -
watchScopecontrols the watcher range:"location"(Default): Only watches files inside the active app's folder."project": Watches the entire workspace, useful for shared libraries.
-
watchExcludeallows manual overrides to ignore specific files or folders. Note that .gitignore rules and internal extension files are always ignored automatically. -
logFiltersets a whitelist of rules that control which log lines are shown. Each rule is matched against the log's scope and level. Three forms are supported:Form Example Effect Level only "info"Show INFOmessages from any scopeScope only "app"Show all levels from the appscopeScope + Level "app:warn"Show only WARNfrom theappscopeWildcard "*"Show everything Scopes in the output channel:
love2d:app—print()calls from your Lua game code. Each line also shows the source file and line, e.g.[love2d:app:main.lua:12], but onlyappis needed for filtering.love2d:bridge— Internal bridge lifecycle messages (connected, reloaded, errors).love2d:process— OS process management (spawning, stdout/stderr).love2d:watcher— File watcher events (change detected, reload triggered).love2d:extension— Extension lifecycle (status bar, config load).
Log levels (from noisiest to most critical):
trace,debug,info,warn,error.inferLogTypesclassifies bridgedprint()calls by their message prefix:- Messages starting with
error:→ logged asERROR - Messages starting with
warn:orwarning:→ logged asWARN - Messages starting with
info:→ logged asINFO - Messages starting with
debug:→ logged asDEBUG - Anything else → logged as
INFO
Common filter recipes:
"logFilter": ["info", "warn", "error"]
Default. Shows all levels ≥ INFO from every scope.
"logFilter": ["app"]
Only your game's
print()output. Hides all bridge/process/watcher noise."logFilter": ["app", "bridge:warn"]
Game prints at all levels + only warnings/errors from the bridge.
"logFilter": ["app:warn", "app:error"]
Only warnings and errors from your game. Suppress info-level prints.
"logFilter": ["*"]
Everything. Useful for debugging the extension itself.
-
fileLogscontrols optional persisted output logging for the last N lines.enabled: Toggles file logging.outputFile: Path to the log file.logLines: Maximum lines to keep.sessionClear: Iftrue, the log file is wiped clean at the start of every manual session or manual restart.reloadClear: Iftrue, the log file is wiped clean only when an automatic hard-reload is triggered by the file watcher.
| Setting | Description | Default |
|---|---|---|
love2d.executablePath |
Path to love executable. |
love (auto-detects common macOS paths) |
love2d.reloadDebounce |
Milliseconds to wait after save before acting. | 300 |
love2d.hotPollInterval |
Milliseconds between mtime checks inside the injected Lua hot-reload layer. | 500 |
- Love2D installed and in your system PATH.
Love2D: Run GameLove2D: Stop GameLove2D: Restart GameLove2D: Init Config
Managed and maintained by Love2D Forge.