Run Python/Pygame projects with fast restart-based hot reload, runtime diagnostics, and traceback-driven error feedback.
What This Extension Is
Pygame Live Preview is a VS Code development extension for Python game projects. It focuses on rapid local iteration:
- edit code
- save file
- see result quickly
It supports standard pygame, pygame-ce, and custom wrappers that use the same runtime surface, with optional adapter hooks for richer telemetry.
What It Offers
- Managed run/restart workflow from inside VS Code.
- Auto reload on save with guardrails against reload storms.
- Error panel with parsed traceback and source links.
- Debug panel for runtime health metrics.
- Optional in-editor preview surface with input routing.
- Health check + dependency guidance for common setup failures.
Features (v1)
- Start/Stop/Restart preview commands.
- Reload on file save with debounce.
- Output channel for stdout/stderr and warnings.
- Error panel with traceback and clickable file/line frames.
- Debug panel with:
- uptime
- restart count
- CPU%
- memory
- last reload cause
- optional FPS and frame time (from adapter)
- Project config via
.pygame-preview.json.
Features (v2 foundations)
- Experimental in-editor preview surface panel (adapter-driven frame stream).
- Setup wizard command to scaffold/update
.pygame-preview.json. - Dependency Doctor command to scan imports and check missing modules in the selected interpreter.
- Debug panel timeline for lifecycle/warning/error events.
- Experimental embedded capture path for pygame apps (bootstrap capture, no project rewrite required).
- Adapter template generator command for custom metrics/hooks.
src-layout import support (e.g.src/core,src/ui) for bootstrap runner.
Features (v4)
- Preview panel input routing:
- keyboard events
- mouse move/click
- wheel events
- Performance controls:
previewFrameIntervalMspreviewMaxWidth- adaptive capture scaling under load
- Reload intelligence:
- soft-reload strategy for asset/config changes
- full restart fallback for code changes
Features (v5)
- Surface mode control:
native(no embedded frame capture, native window only)mirror(native window + in-editor mirrored preview)embedded(panel-first mode, native window hidden where supported)
- Faster embedded frame transport:
- binary frame file transport (
rgb24) instead of JSON base64 payload churn - sequence-based frame polling to avoid redundant frame decode work
- binary frame file transport (
- Input parity improvements in preview panel:
- key repeat/modifier forwarding
- mouse movement deltas and click count
- input capture indicator in panel UI
Features (v6)
- Faster preview transport path:
- local socket frame stream from game bootstrap to extension host
- file transport fallback when socket stream is unavailable
- Latest-frame-only rendering:
- stale frames are dropped under load
- panel always renders the newest received frame
Features (v7)
- Embedded mode hardening:
- reports
surfaceModeRequestedvssurfaceModeActual - explicit fallback reason when embedded window hiding is unsupported/fails
- reports
- Input parity upgrades:
- pointer-lock aware mouse routing for relative movement
- blur-safe key release to reduce stuck-key issues
- text-input forwarding for UI/chat/name-entry flows
- gamepad state forwarding as custom preview events (
pygame.USEREVENT) - embedded input state overrides for
pygame.key.get_pressed()andpygame.mouse.get_pos()/get_pressed()/get_rel()
Features (v8)
- Panel-first beta controls:
panelOnlyMode(best effort) to prefer embedded panel runtime- explicit panel-only status/fallback reporting
- Transport and rendering upgrades:
previewTransport(hybrid/socket/file)- binary RGB frame bytes forwarded to webview (avoids base64 decode on socket path)
- dropped-frame counter (latest-frame strategy visibility)
- Input system upgrades:
- deterministic capture/idle/paused focus model in panel
- IME composition end forwarding
- optional adapter input hook (
on_preview_input)
- In-panel perf HUD v2:
- live mini-graph for FPS and frame-time trends
- dropped frame + input latency stats
- Compatibility upgrades:
sourceRootsconfig for src-layout/monorepo import roots- bootstrap auto-discovers common monorepo roots (
packages/*/src,apps/*/src,services/*/src)
- Adapter SDK v1 workflow:
- typed adapter template (
TypedDicthook signatures) Validate Adaptercommand for signature/import checks
- typed adapter template (
- Playback tooling:
- record input sessions to
.pygame-preview-runtime/input-session-*.jsonl - replay recorded sessions at 1x/2x/4x
- record input sessions to
Features (v9)
- Inspector workflow:
Toggle Inspector PanelcommandRefresh Inspector Snapshotcommand- optional auto-refresh via
inspectorAutoRefreshMs - adapter hooks:
get_scene_snapshot()/get_inspector_snapshot()
- Diagnostics export:
Export Bug Report Bundlecommand- writes
.pygame-preview-runtime/bug-report-*.json
- Runtime control upgrades:
- audio controls from preview panel (mute/volume input events)
- cursor controls from preview panel (visibility/lock input events)
- drop events from preview panel to pygame user events
- gamepad normalization presets (
raw/generic/xbox)
- Capture/perf controls:
performanceModeandpreviewBandwidthKbpspropagate to bootstrap capture logicpanelOnlyStrictfor strict embedded-only startup behavior
- Optional telemetry:
telemetryOptInincludes runner counters in metrics payload
Features (v10)
- Panel runtime GA path:
- stable
surfaceMode: "panel"alias for panel-first execution - automatic mapping to embedded runtime with explicit fallback diagnostics
- stable
- Recovery and safety:
Start Preview (Safe Mode)command- startup crash guard (
startupGuardMaxRestarts,startupGuardWindowMs) - one-click recovery actions on runtime error (safe mode / dependency doctor / open config)
- Input/runtime diagnostics:
- deterministic input clock option (
inputDeterministic,inputDeterministicStepMs) - preview input sequence metadata
- input-to-present latency metric in panel/debug HUD
- dropped-frame cause counters
- deterministic input clock option (
- Inspector v2:
- snapshot diff indicator
- pinned watch paths
- optional source jump buttons from adapter-provided source hints
- Low-latency tuning:
lowLatencyModefor tighter polling/capture pacing
Features (v11 hardening)
- Reload stability and storm protection:
- configurable burst guard (
reloadBurstMax,reloadBurstWindowMs) - configurable reload floor (
reloadMinimumIntervalMs) - temporary per-file suppression for runaway self-updating files
- clearer reload telemetry in Output and debug timeline
- configurable burst guard (
- Dependency helper UX hardening:
- configurable prompt cooldown and post-install mute windows
- deduplicated dependency prompts per module-set/interpreter session
- reduced prompt spam during repeated runtime failures
- Diagnostics polish:
- improved traceback parsing for non-standard/colon-style Python errors
- better summary extraction for argparse/syntax errors
- safer error panel rendering and improved relative-path file linking
- Adapter validation v1 hardening:
- dedicated validator script with workspace/source-root path resolution
- expanded hook signature checks (
inspect, checkpoint hooks) - structured errors/warnings/details output for actionable fixes
- Test/quality improvements:
- extra runner protocol tests (reload lifecycle)
- sample integration tests (
pygame,pygame-ce, custom framework) - CI matrix for extension tests and runner protocol/integration smoke
Features (v12 quality bundle)
- First-run health-check flow:
- one-time prompt before first preview launch in a workspace
- checks entry resolution, interpreter resolution, missing modules, and adapter validation
- quick-fix actions (
Open Config,Setup Wizard,Dependency Doctor, module install shortcut)
- New quality presets:
qualityPreset: "quality" | "balanced" | "performance"- applies a consistent tuning profile for preview fidelity/latency/overhead
- Bug report sharing polish:
- exported bundle now supports
Copy Summaryfor issue reports
- exported bundle now supports
- CI + tests expansion:
- input mapping unit tests (including function keys)
- protocol matrix keeps core runner behavior covered across platforms
Features (v13 performance + reliability)
- Lower-latency panel streaming and runtime overhead reductions:
- latest-frame worker pipeline
- improved socket transport with delta-rect packet envelopes
- adaptive transport/capture tuning visibility in panel diagnostics
- Frame trace and bottleneck diagnostics:
- richer drop-cause counters
- improved transport telemetry for debugging stutter and lag
- Socket transport reliability hardening:
- fixed dedup-state advancement on failed socket sends in socket-only mode
- prevents stale/frozen preview cases when delivery fails transiently
Commands
Pygame Live Preview: Start PreviewPygame Live Preview: Start Preview (Safe Mode)Pygame Live Preview: Stop PreviewPygame Live Preview: Restart PreviewPygame Live Preview: Toggle Debug PanelPygame Live Preview: Toggle Preview SurfacePygame Live Preview: Setup ProjectPygame Live Preview: Run Health CheckPygame Live Preview: Dependency DoctorPygame Live Preview: Setup Adapter TemplatePygame Live Preview: Validate AdapterPygame Live Preview: Start Input RecordingPygame Live Preview: Stop Input RecordingPygame Live Preview: Replay Input SessionPygame Live Preview: Toggle Inspector PanelPygame Live Preview: Refresh Inspector SnapshotPygame Live Preview: Export Bug Report Bundle
Project Config
Create .pygame-preview.json in workspace root:
{
"entry": "main.py",
"reloadDebounceMs": 300
}
Supported fields:
entry: stringpythonPath?: stringwatchInclude?: string[]watchExclude?: string[]softReloadEnabled?: booleansoftReloadInclude?: string[]softReloadExclude?: string[]reloadDebounceMs?: numberautoStart?: booleandebugPanelDefault?: booleanpreviewPanelDefault?: booleanpreviewFrameIntervalMs?: numberpreviewMaxWidth?: numberpreviewInputEnabled?: booleanpanelOnlyMode?: booleanpanelOnlyStrict?: booleanpreviewTransport?: "hybrid" | "socket" | "file"sourceRoots?: string[]gamepadPreset?: "raw" | "generic" | "xbox"audioInitMode?: "auto" | "always" | "off"audioDefaultMuted?: booleanaudioDefaultVolume?: number(0..1)checkpointOnReload?: booleanperformanceMode?: booleanpreviewBandwidthKbps?: numberinspectorAutoRefreshMs?: numbertelemetryOptIn?: booleanlowLatencyMode?: booleaninputDeterministic?: booleaninputDeterministicStepMs?: numberqualityPreset?: "quality" | "balanced" | "performance"startupGuardMaxRestarts?: numberstartupGuardWindowMs?: numberreloadBurstMax?: numberreloadBurstWindowMs?: numberreloadMinimumIntervalMs?: numberdependencyPromptCooldownMs?: numberdependencyPromptMuteAfterInstallMs?: numbersurfaceMode?: "native" | "mirror" | "embedded" | "panel"adapterModule?: stringreloadMode?: "restart" | "inprocess"
Unknown fields warn in output but do not block startup.
Compatibility
Compatibility targets are documented in COMPATIBILITY.md.
Entry Resolution Fallback
If entry is omitted:
main.pyat workspace rootapp.pyat workspace root- first
.pyfile containingif __name__ == "__main__":
Adapter API (optional)
When adapterModule is configured, the runner imports it from workspace root.
Optional functions:
get_metrics() -> dictrequest_reload(payload: dict) -> bool(for experimentalinprocessreload mode)on_preview_input(payload: dict) -> Noneget_frame() -> dict(optional advanced frame source)get_scene_snapshot() -> dictorget_inspector_snapshot() -> dict(for Inspector panel)get_checkpoint() -> dictandrestore_checkpoint(payload: dict) -> None(optional experimental checkpoint flow)
Optional frame stream fields from get_metrics():
framePngBase64: strorframeJpegBase64: strframeRgbBase64: strtogether withframeWidth: intandframeHeight: int
Adapter failures are non-fatal and logged as warnings.
Development
npm install
npm run compile
Package VSIX for install/share:
npm run package:vsix
Runner tests:
npm run test:runner
TypeScript tests:
npm test
Troubleshooting Quick Checks
- Pick the interpreter first:
Python: Select Interpreter, then confirm it in preview output. - If startup crashes loop: run
Pygame Live Preview: Start Preview (Safe Mode). - If modules are missing: run
Pygame Live Preview: Dependency Doctor. - If reload storms happen from generated files:
- add explicit
watchExcludeglobs - tune
reloadBurstMax,reloadBurstWindowMs, andreloadMinimumIntervalMs
- add explicit
- If panel input feels delayed:
- enable
lowLatencyMode - keep
surfaceModeas"panel"or"embedded"
- enable
- If adapter behavior is unclear: run
Pygame Live Preview: Validate Adapter.
Samples
samples/pygame-basicsamples/pygame-ce-basicsamples/custom-framework
Changelog
Current release notes are tracked in CHANGELOG.md.
License
Apache-2.0. See LICENSE.