Skip to content

Repository files navigation

GdTimeMachine

GdTimeMachine icon

Record any scene, rewind any commit.

GdTimeMachine records your scenes right from the editor — no external capture or window setup. Pick a backend, hit Record, and get a clip named for the scene and time. Built for the “time machine” workflow: rewind your project to any git commit and capture it again to diff how a scene looked across history.

Installation

Asset Library

GdTimeMachine is listed on the Godot Asset Library: https://godotengine.org/asset-library/asset/5430

  1. In Godot: AssetLib → Search "GdTimeMachine" → Download → Install
  2. Then Project > Project Settings > Plugins → Enable GdTimeMachine

Manual Install

# from your project root
cp -r /path/to/GdTimeMachine/addons/GdTimeMachine addons/

Then in Godot:

  1. Open Project > Project Settings > Plugins
  2. Enable GdTimeMachine

No extra dependencies for the built-in backends. OBS and ffmpeg are optional (see below).

Quick Start

  1. Open the GdTimeMachine dock in the bottom panel.
  2. Pick a backend, format, and FPS (duration 0 = record until stopped).
  3. Press Record — press Stop when done. Files are named <scene>_<timestamp>.<ext> in your output dir.

Shortcuts:

  • Ctrl+Alt+R / Cmd+Alt+R (macOS) toggles recording from anywhere in the editor.
  • Command Palette → GdTimeMachine: Toggle Recording.
  • Rebind via Project > Editor Settings > Shortcuts → gd_time_machine/toggle_recording.

The dock status line shows live state while recording (backend, output file, elapsed time) and the final save/convert result.

Tip: Check Remember settings for this scene in the dock to save per-scene overrides.

Backends

  • Movie Maker (RESTART_SCENE) — AVI / OGV / PNG. Restarts the scene to record. AVI capped at 4 GB (auto-stops before cap). No external deps.
  • Screenshot (IN_PLACE) — PNG / JPG native (+ ffmpeg → MP4 / WebM / AVI / OGV). Records the running scene in real time (~15 fps, no audio). Window must stay visible. No restart, no kill on Stop.
  • OBS Studio (IN_PLACE) — MP4 native (Full FPS + audio, auto-launches via WebSocket if not running, no scene restart) + ffmpeg → WebM / AVI / OGV post-convert after stop.

RESTART_SCENE backends must relaunch the scene, so the in-game record button is disabled while a scene runs. IN_PLACE backends capture the running scene directly; if nothing is running, Record launches the scene first.

OBS always appears in the backend list under its plain name — installed-but-idle stays selectable (it auto-launches on Record, with a "will auto-launch" tooltip). If truly unavailable (not installed) the entry is greyed and unselectable with the install reason as tooltip; ffmpeg-dependent formats use the same disabled + tooltip treatment when ffmpeg is missing. Launch progress is narrated in both the dock status line and the terminal [GdTM] log.

OBS Setup

Linux and Windows only — on other platforms the backend stays unselectable with the reason shown.

  1. Install OBS Studio (obsproject.com).
  2. In OBS: Tools → WebSocket Server Settings → Enable WebSocket Server (default port 4455). Set a password if desired.
  3. In Godot: Project > Editor Settings → gd_time_machine/obs/* — set matching host, port, and password.
  4. Optional obs/* settings: scene (record target, default GdTimeMachine), auto_launch (default on), auto_close (stop OBS we launched when Godot closes), auto_setup_scene (default on — build the PipeWire capture scene when the record scene is empty), binary_path (custom OBS binary).

Each Record targets your game window directly — no picker: on Linux the game reports its X11 window id over the debugger channel and OBS captures it via xcomposite_input (OBS is auto-launched under XWayland so the kind registers); on Windows OBS captures [exe]: title via window_capture (best-effort — exact-title matching is OBS-side). Whatever can't be targeted programmatically falls back exactly once to PipeWire screen capture (which needs one human share pick, remembered afterwards); if that fails too, the recording errors instead of going black. Progress is narrated in both the dock status line and the terminal [GdTM] log.

The gear button next to the backend dropdown re-opens the capture status dialog anytime: which scene/source/target the next Record will use, plus a one-shot Set up window capture now action. If PipeWire-fallback recordings show the wrong window: its saved share points at the wrong target — delete that share in OBS (or the whole GdTimeMachine scene and let the next Record rebuild it) and re-pick the game window.

Output Formats

The format dropdown is backend-aware — it shows native formats plus what ffmpeg can convert to.

  • Native (no ffmpeg): AVI, OGV, PNG sequence, JPG sequence (availability depends on backend).
  • Converted via a transcoder (ffmpeg): MP4 (H.264), WebM (VP9), AVI, OGV from a backend's native artifact — e.g. Movie Maker AVI → MP4, Screenshot PNG/JPG frames → MP4/WebM, OBS MP4 → WebM.

Tier-2 conversion is on by default (transcoders/ffmpeg/auto_convert). It uses the capture's measured average FPS. If no transcoder is available or conversion fails, the native artifact is kept and the status line explains why — never a lost recording. On success, intermediate frames/files are cleaned up per clean_frames.

  • AVI: MJPEG, largest files, 4 GB cap.
  • OGV: Theora+Vorbis, editor binaries only.
  • PNG/JPG: image sequences, lossless/compact masters.
  • MP4/WebM: require ffmpeg.

ffmpeg Setup (for MP4 / WebM)

Godot has no built-in MP4 writer — MP4/WebM come from ffmpeg tier-2 conversion of the native artifact.

  1. Install ffmpeg: Linux sudo apt install ffmpeg, macOS brew install ffmpeg, Windows winget install ffmpeg / choco install ffmpeg.
  2. Verify on PATH: ffmpeg -version should print a version; which ffmpeg shows the path.
  3. Tell Godot where it is: if on PATH, nothing to do; otherwise set Project > Editor Settings → transcoders/ffmpeg/path to the full path. Test with an MP4/WebM recording — status shows Converted or a missing-tool notice.

Disable tier-2 via transcoders/ffmpeg/auto_convert = false to keep native formats only.

Configuration

All defaults live in Project > Editor Settings and can be overridden per scene.

Recorder (gd_time_machine/recorder/*):

  • output_dir — where recordings are written (default res://media/captures)
  • output_format — default format (avi, ogv, png, jpg, mp4, webm)
  • default_backend — backend selected by default
  • default_fps — target FPS cap
  • default_duration — seconds (0 = until stopped)

Transcoders (transcoders/*):

  • active — ordered transcoder preference (default ["ffmpeg"])
  • transcoders/ffmpeg/*: path — custom ffmpeg binary (empty = PATH lookup)
  • transcoders/ffmpeg/*: auto_convert — auto-convert tier-2 formats after recording (default true)
  • transcoders/ffmpeg/*: clean_frames — delete frames after successful conversion (default true)

OBS (gd_time_machine/obs/*):

  • host, port, password, scene, auto_launch, auto_close, auto_setup_scene, binary_path

Shortcut:

  • gd_time_machine/toggle_recording — Ctrl+Alt+R / Cmd+Alt+R

Per-scene overrides — addons/GdTimeMachine/config/state/profiles.cfg (gitignored by default):

[default]
output_dir = res://media/captures
output_format = mp4
fps = 60
duration = 30

["res://scenes/menu.tscn"]
fps = 30
output_format = png

Each ["res://..."] overrides [default]. Edit directly or use Remember settings for this scene in the dock. Commit for shared team profiles.

CLI — batch capture (history)

gdtime is the headless companion for the time-machine workflow — same plugin.cfg version as the editor plugin, no extra dependencies.

gdtime validate <manifest.json> [--strict]          # check manifest (strict rejects unknown keys)
gdtime run [options] <manifest.json>                # worktree → godot → build → record
gdtime doctor [--verbose] [--fix]                   # git / godot / ffmpeg / OBS / build hook / worktrees
gdtime list-commits <manifest.json>                 # commit label for each capture
gdtime --help
gdtime --version

Manifest (res://addons/GdTimeMachine/cli/schema/batch_manifest.schema.json): project_root, captures[] with commit (hex 4–40 or HEAD), scene (res://…), label ([A-Za-z0-9_-]+, unique), optional duration/fps/godot_version_hint/output_path/build_command and top-level godot_path/build_command/output_dir.

run options: --dry-run (preview), --resume LABEL (skip before label), --keep-worktrees / --keep-failed, --no-git (HEAD-only), --force (overwrite), --build-timeout SECS (default 600), --fail-fast, --strict.

Examples:

gdtime validate test/cli/manifest_history.json
gdtime run --dry-run test/cli/manifest_history.json
gdtime run test/cli/manifest_history.json
gdtime doctor --verbose

History uses godot --path <worktree> --write-movie (Vulkan, no --headless) with godotenv/GODOT_BIN resolution and rm -rf .godot && godot --editor --headless --quit cache regeneration. Wrapper is addons/GdTimeMachine/cli/gdtime (godot --headless -s addons/GdTimeMachine/cli/main.gd -- … also works).

Exit codes: 0 ok, 1 failure, 2 degraded/partial (doctor warnings or run with --keep-failed).

License

Apache-2.0 — see LICENSE.txt.

About

A built-in screen recorder for Godot, able to hook into OBS studio, FFMPEG, and with tooling to build a "time machine" recording checkpoints from old commits

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages